/****************************************************************************/ /* */ /* IAGA_interpolate.c */ /* */ /****************************************************************************/ /****************************************************************************/ /* This program fills the given records in an IAGA-format file by */ /* interpolating the data values from the values at the end points of the */ /* interval. Corrected data is then written into standard output. */ /* */ /* Usage: */ /* IAGA_interpolate [-s -e] | [-a] [-v] [-o] [-c] IAGAFile > NewIAGAFile */ /* -s YYYYMMDDHHMMSS First point to be interpolated */ /* -e YYYYMMDDHHMMSS Last point to be interpolated */ /* -a MaxGap Automatically interpolate every gap whose */ /* length is <= MaxGap seconds. */ /* -v Verbose. Display information about interpolated */ /* gaps. */ /* -o StationID Three letter ID of the station. */ /* -c Components Components to be interpolated */ /* IAGAFile Name of IAGA-format file. */ /* NewIAGAFile Name of corrected IAGA-format file. */ /* */ /****************************************************************************/ /****************************************************************************/ /* Lasse Hakkinen */ /* Finnish Meteorological Institute */ /* Geophysical Research Division */ /* P.O.Box 503 */ /* FIN-00101, Helsinki, Finland */ /* e-mail: Lasse.Hakkinen@fmi.fi */ /* phone : (+358)-9-19294634 */ /* fax : (+358)-9-19294603 */ /* */ /* version 1.02 10.01.2020 */ /****************************************************************************/ /****************************************************************************/ /* Version history: */ /* */ /* 1.02 10.01.2020 Date strings must be YYYYMMDD (four digits for year) */ /* Replaced StrToSecs -> StrToSecsC and */ /* SecsToStr -> SecsToStrC. */ /* 1.01 09.09.1999 Fixed a Y2K bug in NewTime.h file which resulted in */ /* incorrect year in date strings if year >= 2000. */ /* 1.0 11.02.1997 First official release */ /****************************************************************************/ #include #include #include #include "Usage.h" #include "MagnData.h" #include "IAGA.h" char *version = "1.02"; char *date = "10.01.2020"; #define HeaderLineCount 6 #define UsageLineCount 16 char *HeaderText[HeaderLineCount] = { "**************************************************************************", "IAGA_interpolate fills given records in an IAGA-format data file by ", "interpolating the data values from the values at the end points of the ", "interval. This program may be used e.g. to remove spikes. It may also be ", "used to automatically fill data gaps in data files. ", "**************************************************************************", }; char *UsageText[UsageLineCount] = { " [-s -e] | [-a] [-v] [-c] [-o] [<] IAGAFile > NewIAGAFile", " [-s YYYYMMDDHHMMSS] First point to be replaced with interpolated data.", " [-e YYYYMMDDHHMMSS] Last point to be replaced with interpolated data.", " [-a MaxGap] Automatically interpolate every gap whose length", " is less than or equal to MaxGap.", " If -s and -e are specified then -a should not be", " specified. If -a is specified then it is illegal", " to give -s and -e.", " [-v] Verbose. Display information about interpolated", " gaps.", " [-c XYZ] Components to be interpolated.", " If missing then all components (XYZ) filled.", " [-o StationList] Three letter ID's of the stations. If missing", " then all stations interpolated.", " IAGAFile Name of IAGA-format file.", " NewIAGAFile Name of new IAGA-format file.", }; /*--------------------------------------------------------------------------*/ /* Write station, component, start time and length of the interpolated gap */ /*--------------------------------------------------------------------------*/ void WriteGapInfo(StationPtr Station,Time_sec T1, Time_sec T2, char Comp) { char StartStr[20]; SecsToStrC(T1,StartStr); fprintf(stderr,"%s %c %.8s %s %u secs\n",Station->StationID,Comp, StartStr,StartStr+8,T2-T1); } /*--------------------------------------------------------------------------*/ /* The main procedure */ /*--------------------------------------------------------------------------*/ int main(int argc, char *argv[]) { long params; long status = 0; long FileCount = 0; long MaxGap = -1; /* Largest gap to be interpolated */ char FileName[100] = ""; /* Name of the original data file */ Time_sec T,GapStart,GapEnd; Time_sec StartTime = MIN_TIME; /* Time of first data block (secs) */ Time_sec EndTime = MAX_TIME; /* Time of last data block */ char StationList[100] = ""; /* List of stations in command line */ char CompStr[5] = "XYZ"; /* List of components */ Network_struct IMAGE; /* Structure containing the data */ /* for all stations. */ StationPtr Station; /* Pointer to the corrected station */ long Comp; /* Current magnetic component */ long VerboseFlag = 0; /* Display information about gaps */ /*==========================*/ /* 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 'a' : MaxGap = atol(argv[++params]); break; case 's' : StartTime = StrToSecsC(argv[++params],0); break; case 'e' : EndTime = StrToSecsC(argv[++params],0); break; case 'o' : strcpy(StationList,argv[++params]); break; case 'c' : strcpy(CompStr,argv[++params]); break; case 'v' : VerboseFlag = 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 that all necessary parameters are defined */ /*=================================================*/ if (FileCount>1) { PrintUsage(argv[0],1,HeaderLineCount,UsageLineCount); return FAIL; } if (((StartTime == MIN_TIME) || (EndTime == MAX_TIME)) && (MaxGap == -1)) { PrintUsage(argv[0],1,HeaderLineCount,UsageLineCount); return FAIL; } /*================================================*/ /* Read data from an IAGA format file into memory */ /*================================================*/ status = ReadIAGA(FileName,&IMAGE,NULL,NULL,NULL); if (status != 0) { if (status == FileError) fprintf(stderr,"Error in reading file %s\n",FileName); if (status == OutOfMemory) fprintf(stderr,"Out of memory while reading file %s\n",FileName); if (status == FileFormatError) fprintf(stderr,"%s is not an IAGA format file\n",FileName); return FAIL; } /*=======================================================*/ /* Check that the values of the parameters are resonable */ /*=======================================================*/ Station = IMAGE.StationList; if ((MaxGap == -1) && (StartTime > EndTime)) { fprintf(stderr,"StartTime > EndTime !?\n"); return FAIL; } if ((MaxGap == -1) && ((StartTime-Station->StartTime) % Station->TimeStep) != 0) { fprintf(stderr, "Illegal StartTime. There is no such data point in the datafile\n"); return FAIL; } if ((MaxGap == -1) && ((EndTime-Station->StartTime) % Station->TimeStep) != 0) { fprintf(stderr, "Illegal EndTime. There is no such data point in the datafile\n"); return FAIL; } /*======================================*/ /* Go through all stations in NETWORK */ /*======================================*/ while (Station != NULL) { if (StationInList(Station->StationID,StationList)) { /*======================================*/ /* Go through all specified components */ /*======================================*/ for (Comp=0;CompStartTime; while (T < Station->EndTime) { if (FindGap(Station,CompStr[Comp],T,&GapStart,&GapEnd)) { if (GapEnd-GapStart <= MaxGap) { InterpolateData(Station,GapStart, GapEnd-Station->TimeStep,CompStr[Comp]); if (VerboseFlag == 1) WriteGapInfo(Station,GapStart,GapEnd,CompStr[Comp]); } } T = GapEnd; } } else { /*** Interpolate single interval ***/ InterpolateData(Station,StartTime,EndTime,CompStr[Comp]); if (VerboseFlag == 1) WriteGapInfo(Station,StartTime,EndTime,CompStr[Comp]); } } } /* End of if */ Station = Station->Next; } /* End of Station Loop */ /*==========================================*/ /* Write the corrected data into stdout */ /*==========================================*/ WriteIAGA(NULL,&IMAGE,NULL,NULL,NULL); FreeNetwork(&IMAGE); return OK; }