/****************************************************************************/ /* */ /* IAGA_make_average.c */ /* */ /****************************************************************************/ /****************************************************************************/ /* This program computes averages over specified time length from an IAGA */ /* format file and writes the results in IAGA format into standard output. */ /* */ /* Usage: */ /* IAGA_make_average [-s] [-e | -h ] -t [-m] [-o ] [-p] [<] IAGAFile */ /* > NewIAGAFile */ /* -s YYYYMMDDHHMM Time of first record to be written. If */ /* missing then start of file is assumed. */ /* -e YYYYMMDDHHMM Time of the block not anymore written. If */ /* missing then end of file is assumed. */ /* -h HH Number of hours included. Either -e or -h */ /* can be specified, not both. */ /* -t AveragingLength Length of averaging interval. Must be */ /* greater than sample rate in the file. */ /* -m AveragingMode Determines how average is computed: */ /* 'S' : average over [T,T+∆T] */ /* 'M' : average over [T-∆T/2,T+∆T/2] */ /* 'E' : average over [T-∆T,T] */ /* Default is 'S'. */ /* -p Percentage Percentage of valid data points in the */ /* averaging interval before an average can */ /* can be computed. If percentage of valid */ /* data points is less than 'Percentage' then */ /* a missing value is returned as the value */ /* for that particular interval. */ /* -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. */ /* Format : 'SOR MAS KIL KEV' */ /* IAGAFile Name of IAGA-format file. */ /* NewIAGAFile Name of averaged 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.04 10.01.2020 */ /****************************************************************************/ /****************************************************************************/ /* Version history: */ /* */ /* 1.04 10.01.2020 Date strings must be YYYYMMDD (four digits for year) */ /* Replaced StrToSecs -> StrToSecsC and */ /* SecsToStr -> SecsToStrC. */ /* 1.03 10.09.2019 Added -m option. */ /* 1.02 10.08.2005 Added -p option. */ /* 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 21.2.1996 First official release */ /****************************************************************************/ #include #include #include #include "Usage.h" #include "MagnData.h" #include "IAGA.h" char *version = "1.04"; char *date = "10.01.2020"; #define HeaderLineCount 6 #define UsageLineCount 27 char *HeaderText[HeaderLineCount] = { "**************************************************************************", " This program computes averages over specified time period for an IAGA", " format file and writes the results in IAGA format into standard output", " This program may be used e.g. to generate one minute averaged data files", " from 10 second data files.", "**************************************************************************", }; char *UsageText[UsageLineCount] = { " [-s] [-e | -h] -t [-o] [<] IAGA_file > NewIAGA_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.", " -t AveragingTime Length of averaging period. Must be larger", " than the sample rate in the data file.", " [-m] AveragingMode Determines how averages are computed:", " 'S' : average over [T,T+∆T]", " 'M' : average over [T-∆T/2,T+∆T/2]", " 'E' : average over [T-∆T,T]", " Default is 'S'", " [-p] Percentage Percentage of valid data points in the", " averaging interval before an average can", " can be computed. If percentage of valid", " data points is less than 'Percentage' then", " a missing value is returned as the value", " for that particular interval.", " [-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'.", " IAGA_file Name of IAGA-format file.", " NewIAGA_file Name of averaged IAGA-format file.", }; /*--------------------------------------------------------------------------*/ /* The main procedure */ /*--------------------------------------------------------------------------*/ int main(int argc, char *argv[]) { long params; /* Dummy index variable */ long status = 0; /* Status variable for file operations */ long FileCount = 0; /* Number of files in command line */ long HourCount = 0; /* Number of hours to be processed */ long Percentage = 0; /* Percentage of valid data points */ long AveLength = 99999; /* Averaging length in seconds */ char AveMode[10] = "S"; /* Averaging mode */ char FileName[100] = ""; /* Name of IAGA file */ char StartTimeStr[20] = ""; /* Time of first block to be processed */ char EndTimeStr[20] = ""; /* Time of last block to be processed */ char StationStr[400] = ""; /* List of stations to be processed */ Network_struct EISCAT; /* List of station structures */ StationPtr Station; /* Pointer to station structure */ /*==========================*/ /* 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 't' : AveLength = atol(argv[++params]); break; case 'm' : strcpy(AveMode,argv[++params]); break; case 'p' : Percentage = atol(argv[++params]); break; case 'o' : strcpy(StationStr,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 the values of the parameters */ /*====================================*/ if ((FileCount > 1) || (AveLength == 99999)) { 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 an IAGA format file into memory */ /*====================================================*/ status = ReadIAGA(FileName,&EISCAT,StartTimeStr,EndTimeStr,StationStr); 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 the averaging parameter value */ /*==================================================*/ Station = EISCAT.StationList; if ((AveLength % Station->TimeStep) != 0) { fprintf(stderr,"### Illegal parameter value ###\n"); fprintf(stderr,"Averaging length must be a multiple of sample rate"); fprintf(stderr,"\nAveraging length : %d",AveLength); fprintf(stderr,"\nDatafile sample rate : %d\n",Station->TimeStep); fprintf(stderr,"Program execution terminated\n\n"); return FAIL; } /*==================================================*/ /* Compute the averages */ /*==================================================*/ while (Station != NULL) { ComputeStationAveragesMode(Station,AveLength,Percentage,AveMode[0]); Station = Station->Next; } /*======================================================*/ /* Write the averaged data in IAGA format into stdout */ /*======================================================*/ WriteIAGA(NULL,&EISCAT,NULL,NULL,NULL); FreeNetwork(&EISCAT); return OK; }