/****************************************************************************/ /* */ /* WDChour_to_Matrix.c */ /* */ /****************************************************************************/ /****************************************************************************/ /* This is a filter program that reads an 1 hour WDC-format data file and */ /* writes out the same data in pure text file where the field values are */ /* put into a matrix format (24 values per line). */ /* */ /* Usage: */ /* WDChour_to_Matrix [-s] [-e | -h] [-o] [-c] [<] WDChour_file */ /* > TEXT_file */ /* [-s YYMMDDHH] Time of the first record included. If missing */ /* then start of file is assumed. */ /* [-e YYMMDDHH] Time of the record not included anymore. If */ /* missing then end of file is assumed. */ /* [-h HH] Number of hours included. Either -e or -h can */ /* be specified, not both. */ /* [-c Component] Component to be written. Only one component is */ /* allowed. */ /* [-o 'Station list'] List of stations delimited by aposthropes */ /* If missing then all stations included. */ /* Stations are identified by three-letter code */ /* and separated by exactly one space. */ /* WDChour_file Name of one hour WDC-format file. */ /* TEXT_file Name of TEXT format file. */ /* */ /****************************************************************************/ /****************************************************************************/ /* Lasse Hakkinen */ /* Finnish Meteorological Institute */ /* Department of Geophysics */ /* P.O.Box 503 */ /* FIN-00101, Helsinki, Finland */ /* e-mail: Lasse.Hakkinen@fmi.fi */ /* phone : (+358)-9-19294634 */ /* fax : (+358)-9-19294603 */ /* */ /* version 1.04 14.02.2020 */ /****************************************************************************/ /****************************************************************************/ /* Version history: */ /* */ /* 1.04 14.02.2020 Date strings must be YYYYMMDD (four digits for year) */ /* Replaced StrToSecs -> StrToSecsC and */ /* SecsToStr -> SecsToStrC. */ /* 1.03 03.11.2014 Added XYZ <-> HDZ conversion and century handling. */ /* Reads now correctly old data (year < 1900). */ /* Removed -a option. */ /* 1.02 28.09.2001 Added the -a option so that old data (1830 - 1929) is */ /* correctly handled. */ /* 1.01 13.12.2000 D is now written in nT (0.1 not in arcmin) */ /* 1.0 25.10.2000 First release */ /****************************************************************************/ #include #include #include #include "Usage.h" #include "MagnData.h" #include "WDChour.h" char *version = "1.04"; char *date = "14.02.2020"; #define HeaderLineCount 5 #define UsageLineCount 19 char *HeaderText[HeaderLineCount] = { "***************************************************************************", " This program converts magnetometer data from one hour WDC format into TEXT", " format where the data values are put into a matrix with each line as ", " YYYY MM DD + 24 hour values ", "***************************************************************************", }; char *UsageText[UsageLineCount] = { " [-s] [-e | -h] [-c] [-o] [<] WDChour_file > TEXT_file", " [-s YYYYMMDDHH] Time of the first record included. If missing ", " then start of file is assumed. ", " [-e YYYYMMDDHH] Time of the record not included anymore. ", " If missing then end of file is assumed. ", " [-h HH] Number of hours included. Either -e or -h can ", " be specified, not both. ", " [-c Component] Component to be written. Only one component is ", " allowed. For D unit is 0.1 arcmin. For other ", " components unit is nT. ", " If you would like to have D in nT then set ", " Component as 'DnT' ", " [-o 'Station list'] List of stations enclosed in quotes ", " If missing then all stations included. ", " Stations are identified by three-letter code ", " and separated by exactly one space. ", " e.g. 'SOR KEV KIL'. ", " WDChour_file Name of one hour WDC-format file. ", " TEXT_file Name of TEXT-format file. ", }; /*--------------------------------------------------------------------------*/ /* Write data in a matrix format into stdout. */ /*--------------------------------------------------------------------------*/ void ConvertD(StationPtr s) { long *HPtr, *DPtr; long H,D; Time_sec T; double coeff = 2.90888e-5; /* = Pi/(180*60*10) */ HPtr = s->H; DPtr = s->D; T = s->StartTime; while (T < s->EndTime) { H = *HPtr; D = *DPtr; if ((H == MissingValue) || (D == MissingValue)) { *DPtr = MissingValue; } else { *DPtr = RoundFloat(H*coeff*D); } HPtr++; DPtr++; T += s->TimeStep; } } /*--------------------------------------------------------------------------*/ /* Write data in a matrix format into stdout. */ /*--------------------------------------------------------------------------*/ void WriteMatrix(StationPtr s, char Component, long Century) { long *DataPtr; long i; long Cent = 100*Century; Time_sec T; Time_struct MyTime = {0,0,0,1,0,0}; /* {secs,mins,...,years} */ switch (Component) { case 'X' : DataPtr = (s->X); break; case 'Y' : DataPtr = (s->Y); break; case 'Z' : DataPtr = (s->Z); break; case 'H' : DataPtr = (s->H); break; case 'D' : DataPtr = (s->D); break; case 'F' : DataPtr = (s->F); break; } if (Century == 20) Cent = 1900; T = s->StartTime; while (T < s->EndTime) { /* Write the date */ SecsToTm(T,&MyTime); printf("%4d %2d %2d", Cent+MyTime.tm_year,MyTime.tm_mon+1,MyTime.tm_mday); /* Write hour values (24 numbers) */ for (i=0;i<24;i++) { if (*DataPtr == MissingValue) printf(" NaN"); else { if (Component == 'D') printf(" %5d",*DataPtr); /* unit = 0.1 arcmin */ else printf(" %5d",*DataPtr/10); /* unit = 1 nT */ } DataPtr++; } printf("\n"); T += 24*s->TimeStep; } } /*--------------------------------------------------------------------------*/ /* The main procedure */ /*--------------------------------------------------------------------------*/ int main(int argc, char *argv[]) { long params; long status = 0; long FileCount = 0; long HourCount = 0; long OldData = 0; char FileName[100] = ""; char StartTimeStr[20] = ""; char EndTimeStr[20] = ""; char ComponentStr[10] = "H"; char StationStr[200] = ""; Network_struct NETWORK; long Century; /*==========================*/ /* Analyse the command line */ /*==========================*/ if (argc == 1) { /* No arguments, show the usage text */ PrintUsage(argv[0],0,HeaderLineCount,UsageLineCount); return OK; } for (params = 1; params < argc; params++) { if (*argv[params] != '-') { strcpy(FileName,argv[params]); FileCount++; } else { switch (*(argv[params]+1)) { case 's' : strcpy(StartTimeStr,argv[++params]); break; case 'e' : strcpy(EndTimeStr,argv[++params]); break; case 'h' : HourCount = atol(argv[++params]); break; case 'o' : strcpy(StationStr,argv[++params]); break; case 'c' : strcpy(ComponentStr,argv[++params]); break; case 'a' : OldData = 1; break; default : fprintf(stderr,"\n### %s: \"%s\" is not an option.\n\n", argv[0], argv[params]); PrintUsage(argv[0],1,HeaderLineCount,UsageLineCount); return FAIL; break; } } } /*====================================*/ /* Check the values of the parameters */ /*====================================*/ if (FileCount > 1) { PrintUsage(argv[0],1,HeaderLineCount,UsageLineCount); return FAIL; } if ((HourCount != 0) && (strlen(EndTimeStr) > 0)) { PrintUsage(argv[0],1,HeaderLineCount,UsageLineCount); return FAIL; } if ((HourCount != 0) && (strlen(StartTimeStr) == 0)) { PrintUsage(argv[0],1,HeaderLineCount,UsageLineCount); return FAIL; } if (HourCount != 0) { SecsToStrC(StrToSecsC(StartTimeStr,0)+3600*HourCount,EndTimeStr); } /*==================================================*/ /* Read the data from a WDC format file into memory */ /*==================================================*/ status = ReadWDChour(FileName,&NETWORK,StartTimeStr,EndTimeStr,StationStr, &Century); if (status != 0) { if (status == FileError) fprintf(stderr,"Error in reading WDC file\n"); if (status == OutOfMemory) fprintf(stderr,"Out of memory while reading WDC file\n"); if (status == IllegalComponent) fprintf(stderr,"Illegal component used in WDC file. Must be XYZ or HDZ\n"); return FAIL; } if (strcmp(ComponentStr,"DnT") == 0) ConvertD(NETWORK.StationList); /*===============================================*/ /* Write the data in a matrix format into stdout */ /*===============================================*/ WriteMatrix(NETWORK.StationList, ComponentStr[0], Century); FreeNetwork(&NETWORK); return OK; }