/****************************************************************************/ /* */ /* IAGA_change_baselines.c */ /* */ /****************************************************************************/ /****************************************************************************/ /* This program changes baselines of given components in IMAGE data files. */ /* */ /* Usage: */ /* IAGA_change_baselines [-s] [-e] [-x] [-y] [-z] [-X] [-Y] [-Z] [-o] */ /* [<] IAGAFile > NewIAGAFile */ /* [-s YYYYMMDDHHMMSS] Time of the first record to be changed. */ /* If missing then start of file is assumed. */ /* [-e YYYYMMDDHHMMSS] Time of the last record to be changed. If */ /* missing then end of file is assumed. */ /* [-o StationList] List of stations whose data is changed. */ /* If missing then all stations are changed. */ /* [-x X-shift] Baseline shift in X-component in nT's. If */ /* missing then no change is baseline. */ /* [-y Y-shift] Baseline shift in Y-component in nT's. If */ /* missing then no change is baseline. */ /* [-z Z-shift] Baseline shift in Z-component in nT's. If */ /* missing then no change is baseline. */ /* [-X X-baseline] New X value at time defined in -s option. All */ /* subsequent values (until -e option) are shifted */ /* by the difference Xnew-Xold. */ /* [-Y Y-baseline] Same as above but with Y-component. */ /* [-Z Z-baseline] Same as above but with Z-component. */ /* IAGAFile Name of IAGA-format daily 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 09.01.2020 */ /****************************************************************************/ /****************************************************************************/ /* Version history: */ /* */ /* 1.02 09.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 8.4.1997 First official release */ /****************************************************************************/ #include #include #include #include "Usage.h" #include "MagnData.h" #include "IAGA.h" char *version = "1.01"; char *date = "09.01.2020"; #define HeaderLineCount 4 #define UsageLineCount 20 char *HeaderText[HeaderLineCount] = { "**************************************************************************", " This program shifts the baselines of given stations and given components ", " for specified time interval. ", "**************************************************************************", }; char *UsageText[UsageLineCount] = { " [-s] [-e] [-x] [-y] [-z] [-X] [-Y] [-Z] [-o] [<] IAGAFile > NewIAGAFile ", " [-s YYYYMMDDHHMMSS] Time of the first record to be changed. ", " If missing then start of file is assumed. ", " [-e YYYYMMDDHHMMSS] Time of the last record to be changed. ", " If missing then end of file is assumed. ", " [-o StationList] List of stations whose data is changed. ", " If missing then all stations are changed. ", " [-x X-shift] Baseline shift in X-component in nT's. ", " If missing then no change is baseline. ", " [-y Y-shift] Baseline shift in Y-component in nT's. ", " If missing then no change is baseline. ", " [-z Z-shift] Baseline shift in Z-component in nT's. ", " If missing then no change is baseline. ", " [-X X-baseline] New X value at time defined in -s option. All ", " subsequent values (until -e option) are shifted ", " by the difference Xnew-Xold. ", " [-Y Y-baseline] Same as above but with Y-component. ", " [-Z Z-baseline] Same as above but with Z-component. ", " IAGAFile Name of IAGA-format file. ", " NewIAGAFile Name of new IAGA-format file. ", }; /*--------------------------------------------------------------------------*/ /* Shift data for given station and component */ /*--------------------------------------------------------------------------*/ void ShiftData(StationPtr s, Time_sec t0, Time_sec t1, long dB, char Comp) { long *DataPtr; long Value; Time_sec T; DataPtr = GetDataPtr(s,t0,Comp); T = t0; while (T <= t1) { Value = *DataPtr; if (Value != MissingValue) { *DataPtr = Value+dB; } *DataPtr++; T += s->TimeStep; } } /*--------------------------------------------------------------------------*/ /* Change the baseline for the given station and component and report */ /* possible errors. */ /*--------------------------------------------------------------------------*/ long ChangeBase(StationPtr Station,Time_sec StartTime, Time_sec EndTime, long Base, long dB, char Comp) { long Value; if ((dB != 0) || (Base != 999999)) { if (Base != 999999) { Value = GetDataValue(Station,StartTime,Comp); if (Value == MissingValue) { fprintf(stderr,"### There is no data at specified "); fprintf(stderr,"start time !\n"); fprintf(stderr," Program execution stopped.\n"); return 1; } dB = Base - Value; } ShiftData(Station,StartTime,EndTime,dB,Comp); } return 0; } /*--------------------------------------------------------------------------*/ /* The main procedure */ /*--------------------------------------------------------------------------*/ int main(int argc, char *argv[]) { long params; long status = 0; long FileCount = 0; char FileName[100] = ""; /* Name of the original data file */ 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 */ Network_struct IMAGE; /* Structure containing the data */ /* for all stations. */ StationPtr Station; /* Pointer to the current station */ long Comp; /* Current magnetic component */ Time_sec T; /* Current time */ long dX = 0; /* X baseline shift */ long dY = 0; /* Y baseline shift */ long dZ = 0; /* Z baseline shift */ long Xbase = 999999; /* New X-value at StartTime */ long Ybase = 999999; /* New Y-value at StartTime */ long Zbase = 999999; /* New Z-value at StartTime */ /*==========================*/ /* 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' : StartTime = StrToSecsC(argv[++params],0); break; case 'e' : EndTime = StrToSecsC(argv[++params],0); break; case 'o' : strcpy(StationList,argv[++params]); break; case 'x' : dX = 10*atof(argv[++params]); break; case 'y' : dY = 10*atof(argv[++params]); break; case 'z' : dZ = 10*atof(argv[++params]); break; case 'X' : Xbase = 10*atof(argv[++params]); break; case 'Y' : Ybase = 10*atof(argv[++params]); break; case 'Z' : Zbase = 10*atof(argv[++params]); 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 there is at most one data file */ /*===========================================*/ if (FileCount>1) { PrintUsage(argv[0],1,HeaderLineCount,UsageLineCount); return FAIL; } /*====================================================*/ /* Read the 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; } /*======================================*/ /* Go through all stations in NETWORK */ /*======================================*/ Station = IMAGE.StationList; if (StartTime == MIN_TIME) StartTime = Station->StartTime; if (EndTime == MAX_TIME) EndTime = Station->EndTime - Station->TimeStep; while (Station != NULL) { if (StationInList(Station->StationID,StationList)) { /*==================================================*/ /* Go through all components and break the program */ /* execution if errors are found. */ /*==================================================*/ if (ChangeBase(Station,StartTime,EndTime,Xbase,dX,'X')) return 1; if (ChangeBase(Station,StartTime,EndTime,Ybase,dY,'Y')) return 1; if (ChangeBase(Station,StartTime,EndTime,Zbase,dZ,'Z')) return 1; } Station = Station->Next; } /*======================================*/ /* Write corrected data into stdout */ /*======================================*/ WriteIAGA(NULL,&IMAGE,NULL,NULL,NULL); FreeNetwork(&IMAGE); return OK; }