/* * read_mfi_cdf_h0.c * * Purpose: an example to convert cdf files to ascii with selected columns * * Functions and subroutines: * requires CDF (Common Data Format) library v2.5 or above * The library can be obtained at the National Space * Science Center, NASA/Goddard Space Flight Center, * Greenbelt, Maryland * * see: http://nssdc.gsfc.nasa.gov/cdf * * Usage: cdf2asc_wi3smfi cdf_inputfile ascii_outputfile\n * * CDF input : wind/mfi high res. data in cdf format * * ASCII outputs : * * (1) On screen: brief description of the content of the cdf file. * * (2) The ascii file (e.g., ascii_outputfile) contains: * * int yr Year (e.g., 1996) * int mon Month (e.g. 1-January...12-December) * int day Day of Month (1...28/29/30/31) * int hr Hour (1 -24) * int min Minute (0-59) * float sec second of the minute (0.0-59.9999) * float BGSE[0] X component of B in GSE coordinate in nT * float BGSE[1] Y component of B in GSE coordinate in nT * float BGSE[2] Z component of B in GSE coordinate in nT * float BGSM[1] Y component of B in GSM coordinate in nT * float BGSM[2] Z component of B in GSM coordinate in nT * float BF1 Total magnetic flux in nT * float BRMSGSM[0] X component of the rms of B in nT * float BRMSGSM[1] Y component of the rms of B in nT * float BRMSGSM[2] Z component of the rms of B in nT * float BRMSF1 Total magnitude of the rms of B in nT * int NUM_PTS Number of points in averaging * float PGSE[0] X component of s/c position in GSE coordinate in Re * float PGSE[1] Y component of s/c position in GSE coordinate in Re * float PGSE[2] Z component of s/c position in GSE coordinate in Re * float PGSM[1] Y component of s/c position in GSM coordinate in Re * float PGSM[2] Z component of s/c position in GSM coordinate in Re * * Format used for ascii output: * * "%d %d %d %d %d %.1f %.6g %.6g %.6g %.6g %.6g %.6g * %.6g %.6g %.6g %.6g %d %.6g %.6g %.6g %.6g %.6g\n" * * Note: * The information of s/c position has only 1-min resolution. * Each minute of the position data is duplicated 20 times to fill * the 3-s records. * * * Created by Sean (Sheng-Hsien) Chen, Hughes STX Corporation, * Greenbelt, Maryland * * Adapted from cdfinfo.c by Jason Mathews, NASA/GSFC * * October 17, 1997 * ****************************************************************************/ #include #include #include "cdf.h" /* * Macro definitions: */ /*************************************************************************** * `long' is 64 bits on a DEC Alpha (__alpha) [`int' is 32 bits]... ***************************************************************************/ #if defined(__alpha) && defined(__osf__) # define LONG int #else # define LONG long #endif #define GLOBALscope(scope) \ (scope == GLOBAL_SCOPE || scope == GLOBAL_SCOPE_ASSUMED) #define Zq(Z,z,r) (Z ? z : r) #define CheckStatus(msg) if (status != CDF_OK) ErrorHandler(msg, status) #define CDFvarGetpad(id, Z, varNum, padValue) \ CDFlib(SELECT_, CDF_, id, Zq(Z,zVAR_,rVAR_), varNum, \ GET_, Zq(Z,zVAR_PADVALUE_,rVAR_PADVALUE_), padValue, NULL_) #if (defined(__STDC__) || defined(vms) || defined(MSDOS)) # define PROTOARGs(args) args # else # define PROTOARGs(args) () #endif /* * Function prototypes: */ void ErrorHandler PROTOARGs((char* where, long status)); void GetCDFInfo PROTOARGs((char* CDFname,FILE *fw)); void GetVarInfo PROTOARGs((CDFid id, long varNum, int Z)); /* Function: ErrorHandler * * Purpose: Handle CDF errors * * Params: where - string describing where error occured in calling routine. * status - CDF status code. */ void ErrorHandler (where, status) char *where; long status; { char text[CDF_STATUSTEXT_LEN+1]; if (status >= CDF_OK) return; /* ignore OK and info messages */ CDFlib (SELECT_, CDF_STATUS_, status, GET_, STATUS_TEXT_, text, NULL_); if (status >= CDF_WARN) { printf("CDF WARNING: %s\n", text); /* print warning messages */ return; } /* only abort for an error */ printf ("Aborting at %s...\n", where); printf ("%s\n", text); printf ("Program aborted.\n"); exit(1); } /* end ErrorHandler */ /* Function: GetVarInfo * * Purpose: Get pad value for specified variable * * Params: id - Identifier of the CDF. * varNum - variable number * Z - 0 if rVariable, 1 if zVariable */ void GetVarInfo( id, varNum, Z ) CDFid id; long varNum; int Z; { CDFstatus status; long type, numRecs; union { char c; unsigned char uc; short s; unsigned short us; int i; unsigned int ui; LONG l; unsigned LONG ul; float f; double d; } pad; char varName[80]; if (Z) { status = CDFlib (SELECT_, CDF_, id, zVAR_, varNum, GET_, zVAR_NAME_, varName, zVAR_DATATYPE_, &type, zVAR_MAXREC_, &numRecs, NULL_); } else { status = CDFlib (SELECT_, CDF_, id, rVAR_, varNum, GET_, rVAR_NAME_, varName, rVAR_DATATYPE_, &type, rVAR_MAXREC_, &numRecs, NULL_); } CheckStatus("3.0 GET/Var info"); printf("%-20s\t%3ld%c\t%5ld\t", varName, varNum, Zq(Z,'z','r'), numRecs + 1); switch (type) { case CDF_BYTE: case CDF_CHAR: case CDF_INT1: status = CDFvarGetpad(id, Z, varNum, &pad.c); printf("char\t"); if (status == CDF_OK) printf("%d\n", pad.c); else printf("0\t(default)\n"); break; case CDF_UINT1: status = CDFvarGetpad(id, Z, varNum, &pad.uc); printf("uchar\t"); if (status == CDF_OK) printf("%d\n", pad.c); else printf("0\t(default)\n"); break; case CDF_INT2: status = CDFvarGetpad(id, Z, varNum, &pad.s); printf("short\t"); if (status == CDF_OK) printf("%d\n", pad.s); else printf("0\t(default)\n"); break; case CDF_UINT2: status = CDFvarGetpad(id, Z, varNum, &pad.us); printf("ushort\t"); if (status == CDF_OK) printf("%u\n", pad.us); else printf("0\t(default)\n"); break; case CDF_INT4: status = CDFvarGetpad(id, Z, varNum, &pad.l); printf("long\t"); if (status == CDF_OK) printf("%ld\n", (long)pad.l); else printf("0\t(default)\n"); break; case CDF_UINT4: status = CDFvarGetpad(id, Z, varNum, &pad.ul); printf("ulong\t"); if (status == CDF_OK) printf("%lu\n", (unsigned long)pad.ul); else printf("0\t(default)\n"); break; case CDF_REAL4: case CDF_FLOAT: status = CDFvarGetpad(id, Z, varNum, &pad.f); printf("float\t"); if (status == CDF_OK) printf("%f\n", pad.f); else printf("0.0\t(default)\n"); break; case CDF_REAL8: case CDF_EPOCH: case CDF_DOUBLE: status = CDFvarGetpad(id, Z, varNum, &pad.d); printf("double\t"); if (status == CDF_OK) printf("%lf\n", pad.d); else printf("0.0\t(default)\n"); break; default: printf("unknown type (%ld)\n", type); } if (status != NO_PADVALUE_SPECIFIED) CheckStatus("3.1 GET/VAR_NUM"); } /* convert day of year to month and date or vice versa SHC 4/12/95 */ void doy_month(int *year,int *doy,int *month,int *date,int index) { int i,dom[13],yr; yr=*year; dom[0]=0; dom[1]=31; dom[2]=59; dom[3]=90; dom[4]=120; dom[5]=151; dom[6]=181; dom[7]=212; dom[8]=243; dom[9]=273; dom[10]=304; dom[11]=334; dom[12]=365; if((yr%4 == 0 && yr%100 !=0) || (yr%400 ==0)) for(i=2;i<=12;i++) dom[i]++; if(index>0){ for(i=0;i<12;i++){ if(*doy > dom[i] && *doy <= dom[i+1]){ *month=i+1; *date=*doy-dom[i]; goto TheEnd; } } printf(" wrong parameter doy given in doy_month \n"); } else { switch(*month){ case 1: *doy=dom[0]+*date; break; case 2: *doy=dom[1]+*date; break; case 3: *doy=dom[2]+*date; break; case 4: *doy=dom[3]+*date; break; case 5: *doy=dom[4]+*date; break; case 6: *doy=dom[5]+*date; break; case 7: *doy=dom[6]+*date; break; case 8: *doy=dom[7]+*date; break; case 9: *doy=dom[8]+*date; break; case 10: *doy=dom[9]+*date; break; case 11: *doy=dom[10]+*date; break; case 12: *doy=dom[11]+*date; break; default: printf(" wrong parameter month given in doy_month \n"); } } TheEnd: return; } void WriteAscii(id,fw) FILE *fw; CDFid id; { double Epoch; long NumRec; float BF1,BRMSF1,BGSM[4],BRMSGSM[4],BGSE[4],PGSM[4],PGSE[4],Re,sec; int yr,month,day,hr,min; CDFstatus status; int i,j,k,NUM_PTS,Time[3]; status=CDFlib(SELECT_,CDF_,id, zVAR_NAME_,"Epoch3", GET_, zVAR_MAXREC_,&NumRec, NULL_); printf("\nTotal number of records for 3-s data: %d\n",NumRec+1); /* * * Note: to increase the conversion speed, read all the records * at a time and store in a larger array for each component * instead of one record at a time if the memory is not a concern. * * examples; * status=CDFlib(SELECT_,CDF_,id, * zVAR_NAME_,"B3GSE", * zVARs_RECNUMBER_,i, * zVARs_RECCOUNT_,NumRec, * GET_, zVAR_HYPERDATA_,BGSE, NULL_); * * where BGSE has a size of float [NumRec][3] * */ for(i=0;i<=NumRec;i++){ status=CDFlib(SELECT_,CDF_,id, zVAR_NAME_,"Time3_PB5", zVARs_RECNUMBER_,i, GET_, zVAR_HYPERDATA_,Time, NULL_); status=CDFlib(SELECT_,CDF_,id, zVAR_NAME_,"B3GSE", zVARs_RECNUMBER_,i, GET_, zVAR_HYPERDATA_,BGSE, NULL_); status=CDFlib(SELECT_,CDF_,id, zVAR_NAME_,"B3GSM", zVARs_RECNUMBER_,i, GET_, zVAR_HYPERDATA_,BGSM, NULL_); status=CDFlib(SELECT_,CDF_,id, zVAR_NAME_,"B3F1", zVARs_RECNUMBER_,i, GET_, zVAR_DATA_,&BF1, NULL_); status=CDFlib(SELECT_,CDF_,id, zVAR_NAME_,"B3RMSGSM", zVARs_RECNUMBER_,i, GET_, zVAR_HYPERDATA_,BRMSGSM, NULL_); status=CDFlib(SELECT_,CDF_,id, zVAR_NAME_,"B3F1", zVARs_RECNUMBER_,i, GET_, zVAR_DATA_,&BF1, NULL_); status=CDFlib(SELECT_,CDF_,id, zVAR_NAME_,"B3RMSF1", zVARs_RECNUMBER_,i, GET_, zVAR_DATA_,&BRMSF1, NULL_); status=CDFlib(SELECT_,CDF_,id, zVAR_NAME_,"NUM3_PTS", zVARs_RECNUMBER_,i, GET_, zVAR_DATA_,&NUM_PTS, NULL_); j=i/20; if((j*20-i) == 0){ status=CDFlib(SELECT_,CDF_,id, zVAR_NAME_,"PGSE", zVARs_RECNUMBER_,j, GET_, zVAR_HYPERDATA_,PGSE, NULL_); status=CDFlib(SELECT_,CDF_,id, zVAR_NAME_,"PGSM", zVARs_RECNUMBER_,j, GET_, zVAR_HYPERDATA_,PGSM, NULL_); } yr=Time[0]; sec=(float) Time[2]*0.001; /* convert milliseconds to seconds */ doy_month(&Time[0],&Time[1],&month,&day,1);/* convert doy to mon,day */ hr=(int)sec/3600; min=(int) (sec-hr*3600)/60; sec=sec-hr*3600-min*60; fprintf(fw,"%d %d %d %d %d %.1f %.6g %.6g %.6g", yr,month,day,hr,min,sec,BGSE[0],BGSE[1],BGSE[2]); fprintf(fw," %.6g %.6g %.6g %.6g", BGSM[1],BGSM[2],BF1,BRMSGSM[0]); fprintf(fw," %.6g %.6g %.6g %d",BRMSGSM[1],BRMSGSM[2],BRMSF1,NUM_PTS); fprintf(fw," %.6g %.6g %.6g", PGSE[0],PGSE[1],PGSE[2]); fprintf(fw," %.6g %.6g",PGSM[1],PGSM[2]); fprintf(fw,"\n"); } fclose(fw); } /* * Function: GetCDFInfo * * Purpose: Get CDF information * * Params: CDFname - name of CDF to open */ void GetCDFInfo (CDFname,fw) char *CDFname; FILE *fw; { CDFid id; CDFstatus status; int i; long numVars, numZvars, numRvars, maxRecs, numAttrs; long version, release, numDims, format, majority, encoding; long dimSizes[CDF_MAX_DIMS]; char *s; /* Remove CDF extension (.cdf, .CDF;1, ...) from filename as required * by the CDF library. */ if ((s = strrchr(CDFname, '.')) != 0 && (!strncmp(s,".CDF",4) || !strncmp(s, ".cdf",4))) { *s = '\0'; } printf("------------------------------------------------------\n"); printf("CDF name: %s\n", CDFname); /*************************************************************************** * Open CDF. ***************************************************************************/ status = CDFlib (OPEN_, CDF_, CDFname, &id, NULL_); CheckStatus("1.0 OPEN"); /* Get CDF metadata */ status = CDFlib (SELECT_, CDF_, id, GET_, CDF_ENCODING_, &encoding, CDF_MAJORITY_, &majority, CDF_FORMAT_, &format, CDF_VERSION_, &version, CDF_RELEASE_, &release, CDF_NUMDIMS_, &numDims, CDF_NUMrVARS_, &numRvars, CDF_NUMzVARS_, &numZvars, CDF_NUMATTRS_, &numAttrs, CDF_DIMSIZES_, dimSizes, rVARs_MAXREC_, &maxRecs, NULL_); CheckStatus("2.0 GET/CDF info"); /* Print CDF metadata */ printf("CDF Version: %ld.%ld\n", version, release); printf("CDF Format: %s FILE\n", (format==SINGLE_FILE) ? "SINGLE" : "MULI"); printf("Data Encoding: %s ENCODING\n", (encoding==NETWORK_ENCODING) ? "NETWORK" : "HOST"); printf("Variable Majority: %s MAJOR\n", (majority==ROW_MAJOR) ? "ROW" : "COLUMN"); printf("Number of dimensions: %ld [", numDims); for (i=0; i < numDims; i++) printf(" %ld", dimSizes[i]); printf(" ]\n"); printf("Max. number of records for r variables: %ld\n", maxRecs + 1); printf("Number of variables: %ld [%ldr/%ldz]\n", numRvars + numZvars, numRvars, numZvars); printf("Number of attributes: %ld\n", numAttrs); if (numRvars > 0 || numZvars > 0) { printf("\nvariable \tnumber\trecords\ttype\tpadvalue\n"); printf("------------------\t------\t-------\t----\t--------\n"); for (i=0; i < numRvars; i++) GetVarInfo(id, (long)i, 0); for (i=0; i < numZvars; i++) GetVarInfo(id, (long)i, 1); } if (numAttrs > 0) { printf("\nattribute \t# entries scope\n"); printf("--------------------\t--------- -----\n"); for (i=0; i < numAttrs; i++) { char attrName[CDF_ATTR_NAME_LEN+1]; long scope, num_rEntries, num_gEntries, num_zEntries; status = CDFlib (SELECT_, CDF_, id, ATTR_, (long)i, GET_, ATTR_NAME_, attrName, ATTR_SCOPE_, &scope, NULL_); CheckStatus("4.0 Get/ATTR_NAME"); if (GLOBALscope(scope)) { status = CDFlib (SELECT_, CDF_, id, GET_, ATTR_NUMgENTRIES_, &num_gEntries, NULL_); printf("%-20s\t%3ld\t GLOBAL\n", attrName, num_gEntries); } else { status = CDFlib (SELECT_, CDF_, id, GET_, ATTR_NUMrENTRIES_, &num_rEntries, ATTR_NUMzENTRIES_, &num_zEntries, NULL_); printf("%-20s\t%3ld/%ld\t VARIABLE\n", attrName, num_rEntries, num_zEntries); } CheckStatus("4.1 Get/ATTR_NUMENTRIES"); } putchar('\n'); } WriteAscii(id,fw); /*************************************************************************** * Close CDF. ***************************************************************************/ status = CDFlib(SELECT_, CDF_, id, CLOSE_, CDF_, NULL_); CheckStatus("5.0 CLOSE"); } /* end GetCDFInfo */ FILE *openoutfile(output_file,index) char *output_file; int index; { FILE *fw; char yon; if(index==0){ if((fw = fopen(output_file,"w")) == NULL){ printf("Cannot open the file : %s \n",output_file); exit(1); } } else{ Request: if(index==2){printf("Output file ? "); scanf("%s",output_file);} if(fopen(output_file,"r") != NULL){ printf("\n%s is exist, overwrite it (y/n)? ",output_file); scanf("%1s",&yon); if(yon=='N' || yon=='n'){ if(index==1){ printf("Output file ? "); scanf("%s",output_file); } goto Request; } } if((fw=fopen(output_file,"w")) == NULL){ printf("Cannot open the file : %s \n",output_file); goto Request; } } return fw; } main (argc, argv) int argc; char **argv; { int i; FILE *fw; char output_file[80]; if (argc == 1) { printf("\nToo few arguments\n"); printf("Usage: cdf2asc_wi3smfi cdf_inputfile ascii_outputfile\n"); exit(1); } else if(argc >3){ printf("\nToo many arguments!\n"); exit(1); } else if(argc == 3){ fw=openoutfile(argv[2],1); } else if(argc <= 2){ fw=openoutfile(output_file,2); } GetCDFInfo(argv[1],fw); }