themis_sst2nc.c 12.2 KB
 /**************************************************************/
 /*                   THEMIS SST CDF -> DD netCDF             */
 /*                         04.01.2008                         */
 /*                           V 1.1                            */
 /*                    Energy in  info  file                   */
 /*   New CDF with ALL modes and new params                    */
 /**************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <netcdf.h>
#include <cdf.h>
#include <DD.h>
#include <string.h>
#include <time.h>
#include <math.h>

#define TimeGap  3600.0
#define Source "themis@cdpp2"
#define MAX_FILE_NAME_LEN  250                   // Max. file name length
#define MAX_VARS           250                   // Max # of VARS in CDF


/*************************************
   Global variables and structures
**************************************/
long  CDFDims,                                   // Number of dimensions in a CDF file
		CDFVars,                                   // Number of variables in a CDF file
		CDFDimSizes[CDF_MAX_DIMS],                 // Dimension Sizes in a CDF file
		CDFencoding,                               // Data encoding
		CDFmajority,                               // Variable majority
		CDFmaxRec,                                 // max Record number
		CDFAttrs;                                  // number of CDF Attributes


struct cdfvar {                                  // CDF variable structure
		char name[CDF_VAR_NAME_LEN+1];
		long num;                                  // Variable number
		long datatype;
		long numElem;                              // variable dimensionality
		long recVariance;                          // variable rec Variance
		long dimVariances[CDF_MAX_DIMS];           // # of data values in dimSizes
} cdfVar[MAX_VARS];

char mode[4];
int  ncID;
char ncFile[] = "psif_000000000.nc";
int TimeDimID, TimeLengthID, FluxDimID;
int TimeDimVector[2], FluxDimVector[2];          // netCDF Dim vectors

size_t Start[2] = {0L,0L};
size_t TimeCount[2] = {1L,TIMELENGTH};
size_t FluxCount[2] = {1L,16L};

CDFstatus   cstatus;                            // CDF status code

char Version[]="v01";
char ThemisID[]="tha\0";
char ThemisTime[]="tha_psif_time";
char PAR0[]="tha_psif_delta_time";
char PAR1[]="tha_psif_density";
char PAR2[]="tha_psif_en_eflux";

int StartTimeID, StopTimeID;
int StartTimeSpID, StopTimeSpID;
int DeltaTID, DensID, AvTempID, ThVelID, PotID, CurrID, SymAngID;                   // 1D
int MfTempID, TempID, ModeID, ModeSpID, VelID, Flux2ID, SymmID;                     // 2D -> 3
int prTenID, mfTenID;                                                               // 2D -> 6
int FluxID;                                                                         // 2D -> 32
int TimeID;                                                                         // Time netCDF variable
int TimeSpID; 
  
char StartT[TIMELENGTH]; // Start time from  data
char StopT[TIMELENGTH];  // Stop time from  data
/**************************
   Function prototypes
**************************/
void usage();
void cdf_handle_error (CDFstatus);
void nc_handle_error (int);
void removeFilepath();
void removeCDFext();
void removeVers();
void ncdefine();
/*--------------------------------------------------------------------------*/
void usage()
{
	printf ("\nDescription:\n");
	printf ("This program converts a themis CDF file into a netCDF file.\n");
	printf ("\n");
	printf ("Usage: esa2nc <CDF file name> <ThemisID> <mode>\n");
	printf ("\n");
	printf ("Example: esa2nc testfile tha peif\n");
	printf ("\n");
	exit(1);
}
/*--------------------------------------------------------------------------
 *  Handles a CDF error.
 *--------------------------------------------------------------------------*/
void cdf_handle_error(CDFstatus status)
{

	char  message[CDF_STATUSTEXT_LEN+1];

	CDFerror (status, message);              /* Get the appropriate message */
	fprintf  (stderr, "CDF: %s\n", message);
	// exit(1);
}
/*--------------------------------------------------------------------------
 *  Handles a netCDF error.
 *--------------------------------------------------------------------------*/
void nc_handle_error(int status)
{
	fprintf(stderr, "%s\n", nc_strerror(status));
	exit(1);
}

/*--------------------------------------------------------------------------
 *  NetCDF File Definition  *
 *--------------------------------------------------------------------------*/
void ncdefine(double Time)
{
	char *s;
	time_t p;
	int status;
	char *STime;

/*********************** Create netCDF file *****************************/
	memcpy(&(ncFile[0]),&(mode[0]), 4);
	STime = Double2DD_Time(Time);
	memcpy(&(ncFile[5]),&(STime[2]), 9);
	if ((status = nc_create(ncFile, NC_CLOBBER, &ncID)) != NC_NOERR)
																	nc_handle_error(status);
/******************netCDF Dimensions *******************************/
	nc_def_dim (ncID, "Time", NC_UNLIMITED, &TimeDimID);
	nc_def_dim (ncID, "TimeLength", TIMELENGTH, &TimeLengthID);
	nc_def_dim (ncID, "Flux", 16L, &FluxDimID);

/********************netCDF Variables ******************/
	TimeDimVector[0] = TimeDimID;          
	TimeDimVector[1] = TimeLengthID;
	FluxDimVector[0] = TimeDimID;  
	FluxDimVector[1] = FluxDimID;
	
	nc_def_var (ncID, "Time", NC_CHAR, 2, TimeDimVector, &TimeID);

	nc_def_var (ncID, "DeltaT", NC_DOUBLE, 1, &TimeDimID, &DeltaTID);
	nc_def_var (ncID, "density", NC_DOUBLE, 1, &TimeDimID, &ModeID);
	nc_def_var (ncID, "en_eflux", NC_DOUBLE, 2, FluxDimVector, &FluxID);

	nc_def_var (ncID, "StartTime",NC_CHAR, 1, &TimeLengthID, &StartTimeID);
	nc_def_var (ncID, "StopTime",NC_CHAR, 1, &TimeLengthID , &StopTimeID);
           
	nc_put_att_text(ncID, NC_GLOBAL, "Themis", 3, ThemisID);
	nc_put_att_text(ncID, NC_GLOBAL, "Source", 12, Source);
	nc_put_att_text(ncID, FluxID, "Units", 17, "eV/(cm^2-s-sr-eV)");
            
	time(&p);
	s = ctime(&p);
	nc_put_att_text(ncID, NC_GLOBAL, "Created", 24, s); 
				
	status = nc_enddef(ncID); 
      
	nc_put_vara_text(ncID, StartTimeID, &(Start[1]), &(TimeCount[1]), Double2DD_Time(Time));          
}

void put_double(RecStart, RecCount, ParCDF, ParNC) 
{
	long RecInt = 1;
	long indices[1] = {0}, intervals[1] = {1}, counts[1] = {1};
	
	double *value;

	value = (double *)malloc(sizeof(double)*RecCount);
	if ((cstatus = CDFlib (SELECT_, zVAR_, ParCDF,
										zVAR_RECNUMBER_, RecStart ,
										zVAR_RECCOUNT_, RecCount,
										zVAR_RECINTERVAL_, RecInt,
										zVAR_DIMINDICES_, indices,
										zVAR_DIMCOUNTS_, counts,
										zVAR_DIMINTERVALS_, intervals,
										GET_, zVAR_HYPERDATA_, value, NULL_))
															!= CDF_OK)  cdf_handle_error(cstatus);
	nc_put_var_double(ncID, ParNC, value);

	free(value);
}

 
void put_mode(RecStart, RecCount, ParCDF, ParNC) 
{  
	float *value;
	long indices[2] = {0,3}, intervals[1] = {1}, counts[1] = {3};
	long RecInt = 1;

	value = (float *)malloc(sizeof(float) * RecCount *3);
	if ((cstatus = CDFlib (SELECT_, zVAR_, ParCDF,
										zVAR_RECNUMBER_, RecStart ,
										zVAR_RECCOUNT_, RecCount,
										zVAR_RECINTERVAL_, RecInt,
										zVAR_DIMINDICES_, indices,
										zVAR_DIMCOUNTS_, counts,
										zVAR_DIMINTERVALS_, intervals,
										GET_, zVAR_HYPERDATA_, value, NULL_))
															!= CDF_OK)  cdf_handle_error(cstatus);
	nc_put_var_float(ncID, ParNC, value);
       
   free(value);
}

void put_spectra(RecStart, RecCount, ParCDF, ParNC) 
{
	double *value;
	long indices[2] = {0,16}, intervals[1] = {1}, counts[1] = {16};
	long RecInt = 1;

	value = (double *)malloc(sizeof(double)*RecCount*16);
	if ((cstatus = CDFlib (SELECT_, zVAR_, ParCDF,
										zVAR_RECNUMBER_, RecStart ,
										zVAR_RECCOUNT_, RecCount,
										zVAR_RECINTERVAL_, RecInt,
										zVAR_DIMINDICES_, indices,
										zVAR_DIMCOUNTS_, counts,
										zVAR_DIMINTERVALS_, intervals,
										GET_, zVAR_HYPERDATA_, value, NULL_))
															!= CDF_OK)  cdf_handle_error(cstatus);      
	nc_put_var_double(ncID, ParNC, value);
	free(value);
}
 
/*--------------------------------------------------------------------------*/
int main(int argc, char *argv[])
{
	long RecStart = 0, RecCount, RecCountF = 1, RecInt = 1, MaxRec;
	long indices[1] = {0}, counts[1] = {3}, counts2[1] = {6}, countsFlux[1] = {32}, intervals[1] = {1};
	long countsE[1] = {1}, indicesF[2]={0,3}, indicesF2[2]={0,6}, indicesFlux[2] = {0, 32};
	double *value;
	float *value_f;
	size_t numElem;
	long dimN, varN, par0, par1, par2;
	
	CDFid id;
	int i, j, status;
	char  fileName[MAX_FILE_NAME_LEN];
	dd_tmstr_t *dtm;
	int First = 1;
	double DayOld;
  
	char *UT;
	char data_set[8]="thx_psxf";
/*-------------------------------- Arguments Decoding ----------------------------------------*/
	if (argc <= 3) usage();       // CDF input file name and THEMIS Number not specified
	else
	{
			strcpy(fileName, argv[1]);
			strncpy(ThemisID,argv[2],3);
			strncpy(mode,argv[3],4);
	}
      
/*------------------------------------------ CDF Variables Names Updated according to THEMIS Number -------------*/
         
	memcpy(&(data_set[2]),&(ThemisID[2]),1);
	memcpy(&(data_set[6]),&(mode[2]),2);

	memcpy(&(ThemisTime[0]),&(data_set[0]),8);
	memcpy(&(PAR0[0]),&(data_set[0]),8); 
	memcpy(&(PAR1[0]),&(data_set[0]),8); 
	memcpy(&(PAR2[0]),&(data_set[0]),8); 

/*********************** Open CDF file *****************************/
	if ((cstatus = CDFopen(fileName, &id))  != CDF_OK)
												cdf_handle_error(cstatus);
	printf(" THEMIS  %s %s\n", ThemisID, mode);

/*********** treat all vars as zVars with eliminated false dimensionality **********/
    
	if ((cstatus = CDFlib(SELECT_, CDF_zMODE_, zMODEon2, NULL_)) != CDF_OK)
																cdf_handle_error (cstatus);

/************************ Get CDF Data  ************************************/

	cstatus = CDFlib(GET_, zVAR_NUMBER_, ThemisTime, &varN, NULL_);
	cstatus = CDFlib( SELECT_, zVAR_, varN, GET_, zVAR_MAXREC_, &MaxRec, NULL_);

	cstatus = CDFlib(GET_, zVAR_NUMBER_, PAR0, &par0, NULL_);    
	cstatus = CDFlib(GET_, zVAR_NUMBER_, PAR1, &par1, NULL_); 
	cstatus = CDFlib(GET_, zVAR_NUMBER_, PAR2, &par2, NULL_); 


	RecCount = (long)(MaxRec+1);
	printf(" Max Rec %d\n", MaxRec);
   if (MaxRec > 1)
	{   
		value = (double *)malloc(sizeof(double)* RecCount);
		if ((cstatus = CDFlib (SELECT_,
			zVAR_, varN,
			zVAR_RECNUMBER_, RecStart ,
			zVAR_RECCOUNT_, RecCount,
			zVAR_RECINTERVAL_, RecInt,
			zVAR_DIMINDICES_, indices,
			zVAR_DIMCOUNTS_, countsE,
					zVAR_DIMINTERVALS_, intervals,
						GET_, zVAR_HYPERDATA_, value,  NULL_) )
														!= CDF_OK) cdf_handle_error(cstatus);

		for (i = 0; i < RecCount; i++) 
		{                      
			UT = Double2DD_Time(value[i]); 

			if ((First == 0) && (value[i] - DayOld) > TimeGap) 
			{
				printf("GAP %f\n",(value[i] - DayOld)/60.0);                                              
	//        put_double(RecStart, (long)i - RecStart, par0, DeltaTID);
	//               put_mode(RecStart, (long)i - RecStart, par1, ModeID, ModeSpID);
				put_spectra(RecStart, (long)i - RecStart, par2, FluxID);

				nc_put_vara_text(ncID,StopTimeID, &Start[1], &TimeCount[1], Double2DD_Time(DayOld));                        

				if ((status = nc_close(ncID)) != NC_NOERR) nc_handle_error(status); 
								
				First = 1;
				RecStart = (long)i;
				UT = Double2DD_Time(value[i]);
			}
							
			dtm =  ReadTime(UT); 
			if (First == 1) { 
				ncdefine(dtm->times);

				First = 0;
				Start[0] = 0;	
			}  
			
			nc_put_vara_text(ncID, TimeID, Start, TimeCount, UT);
			
			Start[0]++;
			DayOld = value[i];
		}
	 
		free(value);
		nc_put_vara_text(ncID,StopTimeID, &Start[1], &TimeCount[1], UT); 
			
				
		//      put_double(RecStart, RecCount - RecStart, par0, DeltaTID);
		//      put_mode(RecStart, RecCount - RecStart, par1, ModeID, ModeSpID);
		put_spectra(RecStart, RecCount - RecStart, par2, FluxID);
/********************Close Files******************/
		
		if ((status = nc_close(ncID)) != NC_NOERR) nc_handle_error(status);     
	}
	
	if ((cstatus = CDFlib(CLOSE_, CDF_, NULL_)) != CDF_OK)
									cdf_handle_error (cstatus);
		
}