/****************************************************************************/ /* */ /* IL_index_gram.c */ /* */ /****************************************************************************/ /****************************************************************************/ /* This program reads a columnar text file containing IMAGE electrojet */ /* index (IU, IL and IE) data and generates a postscript (PS) file */ /* containing plots of these indices. */ /* */ /* Usage: */ /* IL_index_gram [-s] [-e | -h] [-c] [-i] |-a] [-p] [-r] [-t] [-z] */ /* [<] IL_index_file > EPS-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 Gramtypes] List of different gram types to be plotted. */ /* Each gram will be plotted in a separate page. */ /* If missing then all types will be plotted. */ /* Possible values are: */ /* 'L' : Plot of IL */ /* 'U' : Plot of IU */ /* 'E' : Plot of IE */ /* 'A' : Plot of IL and IU */ /* 'S' : Plot station statistics */ /* [-i IAGA_file] Include individual station grams in IL+IU plot. */ /* Data of individual stations is in IAGA_file. */ /* [-a AverageTime] Don't plot each data point but instead average */ /* values over given period (seconds). This will */ /* reduce the size of the postscript file. */ /* If missing then each data point will be plotted.*/ /* [-p Parameter_file] Name of the parameter file containing values of */ /* several parameters used in the plotting. If one */ /* wants to override the default values then the */ /* new values must be defined here. The structure */ /* of the parameter file may be best found by */ /* investigating the example parameter file. */ /* [-r FieldAmpl] Length of vertical axis in nT. This defines the */ /* scale used in the plots. If FieldAmplitude is */ /* not defined then the grams will be autoscaled */ /* so that all components will totally fit inside */ /* their boxes. */ /* [-t TitleStr] Text used as the title of the figure. Default */ /* value is 'I? index YYYY-MM-DD' */ /* [-z] For FMI internal use only. This option plots the*/ /* curves using Finnish local time and also prints */ /* the texts in Finnish. The times defined in -s */ /* and -e options must be, however, in UT. */ /* IL_index_file Name of IL index data file generated by */ /* IAGA_IL_index . */ /* EPS-File Name of Encapsulated PostScript (EPS) 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 11.02.2020 */ /****************************************************************************/ /****************************************************************************/ /* Version history: */ /* */ /* 1.02 11.02.2020 Date strings must be YYYYMMDD (four digits for year) */ /* Replaced StrToSecs -> StrToSecsC and */ /* SecsToStr -> SecsToStrC. */ /* 1.01 15.05.2019 Added count to prevent infinite loop. */ /* 1.0 26.10.2006 First official release. */ /****************************************************************************/ #include #include #include #include #include "Usage.h" #include "MagnData.h" #include "IL_index.h" #include "PScript.h" #include "IAGA.h" #define mm_to_inch72 2.835 char *version = "1.02"; char *date = "11.02.2020"; #define HeaderLineCount 4 #define UsageLineCount 45 char *HeaderText[HeaderLineCount] = { "**************************************************************************", "This program reads in IMAGE electrojet index (IU, IL and IE) data file and", "writes out a PostScript containing plots of indices of the given data. ", "**************************************************************************", }; char *UsageText[UsageLineCount] = { " [-s] [-e | -h] [-c] [-i] [-a] [-p] [-r] [-t] [-z] ", " [<] IL_index_file > PS_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 Gramtypes] List of different gram types to be plotted. ", " Each gram will be plotted in a separate page. ", " If missing then all types will be plotted. ", " Possible values are: ", " 'L' : Plot of IL ", " 'U' : Plot of IU ", " 'E' : Plot of IE ", " 'A' : Plot of IL and IU ", " 'S' : Plot of station statistics ", " [-i IAGA_file] Include individual station grams in IL+IU plot. ", " Data of individual stations is in IAGA_file. ", " [-a AverageTime] Don't plot each data point but instead average ", " values over given period (seconds). This will ", " reduce the size of the postscript file. ", " If missing then each data point will be plotted.", " [-p Parameter_file] Name of the parameter file containing values of ", " several parameters used in the plotting. If one ", " wants to override the default values then the ", " new values must be defined here. The structure ", " of the parameter file may be best found by ", " investigating the example parameter file. ", " [-r FieldAmplitude] Length of vertical axis in nT. This defines the ", " scale used in the plots. If FieldAmplitude is ", " not defined then the grams will be autoscaled ", " so that all components will totally fit inside ", " their boxes. ", " [-t TitleString] Text to be used as the title of the figure. ", " Default title is 'I? index YYYY-MM-DD'. ", " If -t option is used then the value defined in ", " the parameter file is neglected. ", " [-z] For FMI internal use only. Print the grams using", " Finnish local time. Also prints the texts in ", " Finnish. The times defined in -s and -e options ", " must be, however, in UT. ", " IL_index_file Name of IL index data file generated by ", " IAGA_IL_index ", " PS_File Name of PostScript (PS) file. " }; /*==========================================================================*/ /* There are a lot of global variables here (for simplicity !). They are */ /* divided into two groups: 1. Boolean variables which control whether some */ /* parts are printed or not and 2. variables that control how different */ /* parts of the grams are printed (e.g. linewidth). */ /* Most of the variables are also given a default value which will be */ /* replaced by a value read from the parameter file (if defined). Values */ /* for some of the parameters (def value = -1) are computed during program */ /* execution. */ /*==========================================================================*/ /*------------------------*/ /* Boolean variables */ /*------------------------*/ long PrintFrame = 1; /* Print the frame enclosing the stack plot */ long PrintTitle = 1; /* Print the title string */ long PrintVerGridLines = 1; /* Print vertical grid lines */ long PrintHorGridLines = 1; /* Print horizontal grid lines */ long PrintTimeAxis = 1; /* Print time axis with tick marks */ long PrintLowerTicks = 1; /* Print tick marks in the lower time axis */ long PrintUpperTicks = 1; /* Print tick marks in the upper time axis */ long PrintTimeLabels = 1; /* Print time labels under the time axis */ long PrintIndexName = 1; /* Print name of index in the left axis */ long PrintFieldValues = 1; /* Print the field values in the ver. axis */ long PrintAverageValue = 1; /* Print the averaging value used in plots */ long PlotMode = 1; /* 1 : continuous line; 0: single dots */ long LandscapeMode = 0; /* 1 : long side horizontal 0: vertical */ /*------------------------*/ /* Other global variables */ /*------------------------*/ /* --- Title --- */ char TitleStr[200] = ""; /* Title of the magnetogram plot */ char TitleFont[20] = "Helvetica"; /* Title string font type */ float TitleFontSize = 18.0; /* Font size of title string (in points) */ float TitleOffset = 10.0; /* Distance of Title string from frame top */ /* --- Frame --- */ float FrameLeft = 40.0; /* x-coordinate of the left edge of frame */ float FrameBottom = 35.0; /* y-coordinate of the bottom edge of frame */ float FrameWidth = 140.0; /* Width of the enclosing frame (140.0) */ float FrameHeight = 220.0; /* Height of the enclosing frame (220.0) */ float FrameLineWidth = 0.2; /* Line width of the enclosing frame */ /* --- Data line/points --- */ float DataLineWidth = 0.2; /* Width of the dataline */ float DotRadius = 0.2; /* Radius of data points if PlotMode = 0 */ /* --- Time tickmarks --- */ long MajorTickPeriod = -1; /* Period of successive major time ticks */ long MinorTickPeriod = -1; /* Period of successive minor time ticks */ float MajorTickLength = 3.5; /* Length of the major time tick marks */ float MinorTickLength = 2.5; /* Length of the minor time tick marks */ float TickMarkWidth = 0.2; /* Width of the tick marks in time axis */ float TimeTickLeft = 0.0; /* Distance of first tick from left edge */ float TimeTickRight = 0.0; /* Distance of last tick from right edge */ /* --- Time axis title --- */ char TimeTitleFont[20] = "Helvetica"; float TimeTitleFontSize = 15.0; /* Font size of time labels (in points) */ float TimeTitleOffset = 13.0; /* Dist of time unit text from bottom axis */ /* --- Time labels --- */ char TimeLabelFont[20] = "Helvetica"; float TimeLabelFontSize = 13.0; /* Font size of time labels (in points) */ float TimeLabelOffset = 5.0; /* Distance from time labels to time axis */ /* --- Field axis tickmarks --- */ long MajorFieldPeriod = -1; /* Period of successive major field ticks */ long MinorFieldPeriod = -1; /* Period of successive minor field ticks */ float MajorFieldLength = 3.5; /* Length of the major field axis tick mark */ float MinorFieldLength = 2.0; /* Length of the minor field axis tick mark */ float FieldTickMarkWidth = 0.2;/* Width of the tick marks in field axis */ float yTopMargin = 10.0;/* Space from frame top to uppermost tick */ float yBottomMargin = 10.0;/* Space from frame bottom to lowest tick */ /* --- Field axis title --- */ char FieldTitle[20] = "Helvetica"; /* Field component string font type */ float FieldTitleSize = 15.0; /* Font size of the component string */ float FieldTitleOffset = 15.0; /* Distance of Comp string from Frame edge */ /* --- Field axis labels --- */ char FieldLabelFont[20] = "Helvetica"; float FieldLabelFontSize = 13.0;/* Font size of field value labels */ float FieldLabelOffset = 2.0;/* Distance of field values from field axis */ /* --- Averaging period --- */ char AverageFont[20] = "Helvetica";/* Font used in writing averaging value */ float AverageFontSize = 9.0;/* Font size of the baseline value text */ float AverageOffset = 2.0; /* Distance of averagevalue from top edge */ /* --- Other variables --- */ float ZoomFactor = 1.0; /* Zoom entire figure by this factor */ float GridLineWidth = 0.1;/* Width of the vertical grid line */ long GridLineType = 5; /* Line type of grid lines. see Pscript.h */ float GridLinePeriod = 3.0; /* Length of one period in dashed grid line */ /* --- Station statistics page --- */ float StatFrameLeft = 40.0; /* x-coordinate of the left edge of frame */ float StatFrameBottom = 100.0; /* y-coordinate of the bottom edge of frame */ float StatFrameWidth = 120.0; /* Width of the enclosing frame (140.0) */ float StatFrameHeight = 160.0; /* Height of the enclosing frame (200.0) */ float StatFrameLineWidth = 0.2; /* Line width of the enclosing frame */ char StatTitleStr[200] = ""; /* Title of the statistics plot */ char StatTitleFont[20] = "Helvetica"; /* Title string font type */ float StatTitleFontSize = 18.0; /* Font size of title string (in points) */ float StatTitleOffset = 10.0; /* Distance of Title string from frame top */ char StatLabelFont[20] = "Helvetica"; float StatLabelFontSize = 13.0;/* Font size of field value labels */ float StatLabelOffset = 2.0;/* Distance of field values from field axis */ char PercLabelFont[20] = "Helvetica"; float PercLabelFontSize = 13.0; /* Font size of percentage (in points) */ float PercLabelOffset = 5.0; /* Distance of percentage labels from axis */ char PercTitleFont[20] = "Helvetica"; float PercTitleFontSize = 13.0;/* Font size of field value labels */ float PercTitleOffset = 2.0;/* Distance of field values from field axis */ float StatBarWidth = 0.3; /* Bar width parameter */ long Finnish = 0; /* Use Finnish local time. -z option */ /*--------------------------------------------------------------------------*/ /* Skip given number of lines in the given text-file. */ /*--------------------------------------------------------------------------*/ static void SkipLines(FILE *ParamFile, long LineCount) { long i; for (i=0;i0) strcpy(ChrStr,ChrArray); /* If string length > 0 */ } /*--------------------------------------------------------------------------*/ /* Read plotting parameters from a parameter file. The structure of the */ /* parameter file is explained in the example parameter file. */ /*--------------------------------------------------------------------------*/ long ReadParameterFile(char *ParamFileName) { FILE *ParamFile; if ((ParamFile = fopen(ParamFileName,"r")) == NULL) return FileError; SkipLines(ParamFile,18); PrintFrame = GetNextLong(ParamFile); PrintTitle = GetNextLong(ParamFile); PrintVerGridLines = GetNextLong(ParamFile); PrintHorGridLines = GetNextLong(ParamFile); PrintTimeAxis = GetNextLong(ParamFile); PrintLowerTicks = GetNextLong(ParamFile); PrintUpperTicks = GetNextLong(ParamFile); PrintTimeLabels = GetNextLong(ParamFile); PrintIndexName = GetNextLong(ParamFile); PrintFieldValues = GetNextLong(ParamFile); PrintAverageValue = GetNextLong(ParamFile); PlotMode = GetNextLong(ParamFile); LandscapeMode = GetNextLong(ParamFile); SkipLines(ParamFile,7); GetNextStr(ParamFile,TitleStr); GetNextStr(ParamFile,TitleFont); TitleFontSize = GetNextFloat(ParamFile); TitleOffset = GetNextFloat(ParamFile); SkipLines(ParamFile,2); FrameLeft = GetNextFloat(ParamFile); FrameBottom = GetNextFloat(ParamFile); FrameWidth = GetNextFloat(ParamFile); FrameHeight = GetNextFloat(ParamFile); FrameLineWidth = GetNextFloat(ParamFile); SkipLines(ParamFile,2); DataLineWidth = GetNextFloat(ParamFile); DotRadius = GetNextFloat(ParamFile); SkipLines(ParamFile,2); MajorTickPeriod = GetNextLong(ParamFile); MinorTickPeriod = GetNextLong(ParamFile); MajorTickLength = GetNextFloat(ParamFile); MinorTickLength = GetNextFloat(ParamFile); TickMarkWidth = GetNextFloat(ParamFile); TimeTickLeft = GetNextFloat(ParamFile); TimeTickRight = GetNextFloat(ParamFile); SkipLines(ParamFile,2); GetNextStr(ParamFile,TimeTitleFont); TimeTitleFontSize = GetNextFloat(ParamFile); TimeTitleOffset = GetNextFloat(ParamFile); SkipLines(ParamFile,2); GetNextStr(ParamFile,TimeLabelFont); TimeLabelFontSize = GetNextFloat(ParamFile); TimeLabelOffset = GetNextFloat(ParamFile); SkipLines(ParamFile,2); MajorFieldPeriod = GetNextLong(ParamFile); MinorFieldPeriod = GetNextLong(ParamFile); MajorFieldLength = GetNextFloat(ParamFile); MinorFieldLength = GetNextFloat(ParamFile); FieldTickMarkWidth = GetNextFloat(ParamFile); yTopMargin = GetNextFloat(ParamFile); yBottomMargin = GetNextFloat(ParamFile); SkipLines(ParamFile,2); GetNextStr(ParamFile,FieldTitle); FieldTitleSize = GetNextFloat(ParamFile); FieldTitleOffset = GetNextFloat(ParamFile); SkipLines(ParamFile,2); GetNextStr(ParamFile,FieldLabelFont); FieldLabelFontSize = GetNextFloat(ParamFile); FieldLabelOffset = GetNextFloat(ParamFile); SkipLines(ParamFile,2); GetNextStr(ParamFile,AverageFont); AverageFontSize = GetNextFloat(ParamFile); AverageOffset = GetNextFloat(ParamFile); SkipLines(ParamFile,2); ZoomFactor = GetNextFloat(ParamFile); GridLineWidth = GetNextFloat(ParamFile); GridLineType = GetNextLong(ParamFile); GridLinePeriod = GetNextFloat(ParamFile); SkipLines(ParamFile,2); StatFrameLeft = GetNextFloat(ParamFile); StatFrameBottom = GetNextFloat(ParamFile); StatFrameWidth = GetNextFloat(ParamFile); StatFrameHeight = GetNextFloat(ParamFile); StatFrameLineWidth = GetNextFloat(ParamFile); GetNextStr(ParamFile,StatTitleStr); GetNextStr(ParamFile,StatTitleFont); StatTitleFontSize = GetNextFloat(ParamFile); StatTitleOffset = GetNextFloat(ParamFile); GetNextStr(ParamFile,StatLabelFont); StatLabelFontSize = GetNextFloat(ParamFile); StatLabelOffset = GetNextFloat(ParamFile); GetNextStr(ParamFile,PercLabelFont); PercLabelFontSize = GetNextFloat(ParamFile); PercLabelOffset = GetNextFloat(ParamFile); GetNextStr(ParamFile,PercTitleFont); PercTitleFontSize = GetNextFloat(ParamFile); PercTitleOffset = GetNextFloat(ParamFile); StatBarWidth = GetNextFloat(ParamFile); fclose(ParamFile); return 0; } /*--------------------------------------------------------------------------*/ /* Find if summer time is in effect in Finland at the specified time. */ /* Returns 1 if yes and 0 if not. */ /* Summer time in Finland starts on last sunday in March and ends on last */ /* sunday on October. */ /*--------------------------------------------------------------------------*/ long SummerTime(Time_sec T) { Time_struct SummerStart = {0,0,1,31, 2, 0}; /* {secs,mins,...,years} */ Time_struct SummerEnd = {0,0,1,31, 9, 0}; /* {secs,mins,...,years} */ Time_struct CurrentTime; Time_struct RefSunday = {0,0,0, 4, 0,81}; Time_sec SummerStartSec,SummerEndSec,RefSundaySec; SecsToTm(T,&CurrentTime); SummerStart.tm_year = CurrentTime.tm_year; SummerEnd.tm_year = CurrentTime.tm_year; SummerStartSec = TmToSecs(&SummerStart); SummerEndSec = TmToSecs(&SummerEnd); RefSundaySec = TmToSecs(&RefSunday); SummerStartSec -= 86400*(((SummerStartSec - RefSundaySec)/86400) % 7); SummerEndSec -= 86400*(((SummerEndSec - RefSundaySec)/86400) % 7); if ((T > SummerStartSec) && (T < SummerEndSec)) return 1; else return 0; } /*--------------------------------------------------------------------------*/ /* Create the title string using the plot type, start time and end time. */ /* If the plot contains data for a single date then the title string is of */ /* the form: IL index 1997-01-12 00-24 UT */ /* If the plot covers several days then the title string is of the form: */ /* 'IL index 1997-01-12 12 UT - 1997-01-13 12 UT' */ /*--------------------------------------------------------------------------*/ void FindTitleStr(StationPtr Station,char *Title, char GramType, Time_sec StartTime, Time_sec EndTime) { char DateStr[20]; long PrintMinutes; /* Does plot start or end at full hour ? */ long OneDay; /* Does the plot fill into a single day ? */ PrintMinutes = (((StartTime % 3600) != 0) || ((EndTime % 3600) != 0)); /* First handle the gram type and start time */ switch (GramType) { case 'L' : strcpy(Title,"IL index "); break; case 'U' : strcpy(Title,"IU index "); break; case 'E' : strcpy(Title,"IE index "); break; case 'A' : strcpy(Title,"IL and IU indices "); break; case 'S' : strcpy(Title,"Station statistics "); break; } if (Finnish) { /* Display time in Finnish time */ StartTime += (2 + SummerTime(StartTime))*3600; EndTime += (2 + SummerTime(StartTime))*3600; } SecsToStrC(StartTime,DateStr); // YYYYMMDD if (Finnish) { strncat(Title,DateStr+4,2); /* Day */ strcat(Title,"."); strncat(Title,DateStr+2,2); /* Month */ strcat(Title,"."); // if (StartTime < YEAR2000) // strcat(Title,"19"); // else // strcat(Title,"20"); // strncat(Title,DateStr,2); /* Year */ strncat(Title,DateStr,4); } else { // if (StartTime < YEAR2000) // strcat(Title,"19"); // else // strcat(Title,"20"); // strncat(Title,DateStr,2); /* Year */ strncat(Title,DateStr,4); /* Year */ strcat(Title,"-"); strncat(Title,DateStr+4,2); /* Month */ strcat(Title,"-"); strncat(Title,DateStr+6,2); /* Day */ } strcat(Title," "); strncat(Title,DateStr+8,2); /* Hour */ if (PrintMinutes) { /* add minutes */ strcat(Title,":"); strncat(Title,DateStr+10,2); } /* Handle the end time */ OneDay = ((StartTime/86400) == ((EndTime-Station->TimeStep)/86400)); SecsToStrC(EndTime,DateStr); if (OneDay) { /* One day */ strcat(Title," - "); if (strncmp(DateStr+8,"0000",4) == 0) strncat(Title,"24",2); else strncat(Title,DateStr+8,2); /* Hour */ if (PrintMinutes) { /* add minutes */ strcat(Title,":"); strncat(Title,DateStr+10,2); } } else { /* Many days */ if (Finnish) { strcat(Title," - "); strncat(Title,DateStr+6,2); /* Day */ strcat(Title,"."); strncat(Title,DateStr+4,2); /* Month */ strcat(Title,"."); // if (StartTime < YEAR2000) // strcat(Title,"19"); // else // strcat(Title,"20"); strncat(Title,DateStr,4); /* Year */ } else { strcat(Title," UT - "); // if (EndTime < YEAR2000) // strcat(Title,"19"); // else // strcat(Title,"20"); strncat(Title,DateStr,4); /* Year */ strcat(Title,"-"); strncat(Title,DateStr+4,2); /* Month */ strcat(Title,"-"); strncat(Title,DateStr+6,2); /* Day */ } strcat(Title," "); strncat(Title,DateStr+8,2); /* Hour */ if (PrintMinutes) { /* add minutes */ strcat(Title,":"); strncat(Title,DateStr+10,2); } } if (!Finnish) strcat(Title," UT"); } /*--------------------------------------------------------------------------*/ /* Find the current time and put it into DateStr. This is used only in the */ /* eps file header in the CreationDate parameter. */ /*--------------------------------------------------------------------------*/ void GetCurrentTime(char *DateStr) { time_t t; time(&t); strcpy(DateStr,asctime(localtime(&t))); } /*--------------------------------------------------------------------------*/ /* Compute the bounding box for eps-file. Bounding box is the smallest */ /* rectangle which totally encloses the figure. */ /*--------------------------------------------------------------------------*/ void ComputeBoundingBox(char *GramTypes, long *left,long *bottom,long *right,long *top) { if ((strlen(GramTypes) == 1) && (GramTypes[0] == 'S')) { /* Only statistics page */ *left = (long) (ZoomFactor*mm_to_inch72*(StatFrameLeft-StatLabelOffset -0.35*StatLabelFontSize-13.0)); *bottom = (long) (ZoomFactor*mm_to_inch72*(StatFrameBottom-PercLabelOffset-13.0)); *right = (long) (ZoomFactor*mm_to_inch72*(StatFrameLeft+StatFrameWidth+10.0)); if (PrintTitle == 1) *top = (long) (ZoomFactor*mm_to_inch72*(StatFrameBottom+StatFrameHeight+StatTitleOffset +0.35*StatTitleFontSize+3.0)); else *top = (long) (ZoomFactor*mm_to_inch72*(StatFrameBottom+StatFrameHeight+AverageOffset +0.35*AverageFontSize+1.0)); } else { *left = (long) (ZoomFactor*mm_to_inch72*(FrameLeft-FieldTitleOffset -0.35*FieldTitleSize-3.0)); *bottom = (long) (ZoomFactor*mm_to_inch72*(FrameBottom-TimeTitleOffset-3.0)); *right = (long) (ZoomFactor*mm_to_inch72*(FrameLeft+FrameWidth+10.0)); if (PrintTitle == 1) *top = (long) (ZoomFactor*mm_to_inch72*(FrameBottom+FrameHeight+TitleOffset +0.35*TitleFontSize+3.0)); else *top = (long) (ZoomFactor*mm_to_inch72*(FrameBottom+FrameHeight+AverageOffset +0.35*AverageFontSize+1.0)); } } /*--------------------------------------------------------------------------*/ /* Write the Title, Creation date and Bounding box into eps-file and do */ /* other PS-initializations. */ /*--------------------------------------------------------------------------*/ void WritePSHeader(char *GramTypes) { char PSTitleStr[100]; char CreationDateStr[100]; long BBleft,BBbottom,BBright,BBtop; strcpy(PSTitleStr,"IMAGE electrojet indices"); GetCurrentTime(CreationDateStr); ComputeBoundingBox(GramTypes, &BBleft,&BBbottom,&BBright,&BBtop); InitializePS(PSTitleStr,"IL_index_gram-program",CreationDateStr,BBleft,BBbottom,BBright,BBtop); } /*--------------------------------------------------------------------------*/ /* Set the MajorTickPeriod and MinorTickPeriod. If their values are -1 */ /* then new values will be substituted, otherwise the values read from */ /* the parameter file will be used. */ /*--------------------------------------------------------------------------*/ void SetTickPeriods(long Major, long Minor) { if (MajorTickPeriod == -1) MajorTickPeriod = Major; if (MinorTickPeriod == -1) MinorTickPeriod = Minor; } /*--------------------------------------------------------------------------*/ /* Find reasonable MajorTickPeriod and MinorTickPeriod based on StartTime */ /* and EndTime. */ /*--------------------------------------------------------------------------*/ void FindTickPeriods(Time_sec StartTime,Time_sec EndTime) { long TotalHours,TotalMins; TotalMins = (EndTime-StartTime)/60; TotalHours = (EndTime-StartTime)/3600; if (TotalHours == 0) SetTickPeriods(5,1); else if (TotalHours == 1) SetTickPeriods(10,5); else if (TotalHours <= 3) SetTickPeriods(30,10); else if (TotalHours <= 6) SetTickPeriods(60,10); else if (TotalHours <= 12) SetTickPeriods(120,30); else if (TotalHours <= 24) SetTickPeriods(360,60); else if (TotalHours <= 96) SetTickPeriods(1440,240); else SetTickPeriods(1440,1440); } /*--------------------------------------------------------------------------*/ /* Draw the frame enclosing the magnetograms. */ /*--------------------------------------------------------------------------*/ void DrawFrame(void) { if (PrintFrame) { LineWidthPS(FrameLineWidth); RectPS(FrameLeft,FrameBottom,FrameWidth,FrameHeight,0.0); } } /*--------------------------------------------------------------------------*/ /* Draw the frame enclosing the magnetograms. */ /*--------------------------------------------------------------------------*/ void DrawTitle(void) { float x,y; if (PrintTitle) { x = FrameLeft+FrameWidth/2; y = FrameBottom+FrameHeight+TitleOffset; FontPS(TitleFont,TitleFontSize); TextPS(x,y,0.0,'C',TitleStr); } } /*--------------------------------------------------------------------------*/ /* Draw time labels under the time axis */ /*--------------------------------------------------------------------------*/ void DrawTimeLabels(Time_sec StartTime, Time_sec EndTime) { float x,y,dx; float TimeScale; Time_sec CurrTime; char FullDateStr[16]; char DateStr[16]; long count = 0; if ((! PrintTimeAxis) || (! PrintTimeLabels)) return; FontPS(TimeLabelFont,TimeLabelFontSize); TimeScale = (FrameWidth-TimeTickLeft-TimeTickRight)/(EndTime-StartTime); x = FrameLeft+TimeTickLeft; dx = 60*TimeScale*MajorTickPeriod; if (Finnish) { /* Display time in Finnish time */ StartTime += (2 + SummerTime(StartTime))*3600; EndTime += (2 + SummerTime(StartTime))*3600; } CurrTime = StartTime; // Fix 12.12.2018. The first tick mark doesn't have to be at StartTime if (StartTime % (60*MajorTickPeriod) != 0) { // if (StartTime % (60*MajorTickPeriod) < 60*MajorTickPeriod/2) // CurrTime -= (StartTime % (60*MajorTickPeriod)); // else CurrTime += 60*MajorTickPeriod - (StartTime % (60*MajorTickPeriod)); } x = FrameLeft+TimeTickLeft + TimeScale*(CurrTime - StartTime); do { SecsToStrC(CurrTime,FullDateStr); strcpy(DateStr,""); if ((EndTime-StartTime) <= 86400L) {/* Print hours, not day numbers */ strncat(DateStr,FullDateStr+8,2); if (MajorTickPeriod < 60) { /* Print minutes */ strcat(DateStr,":"); strncat(DateStr,FullDateStr+10,2); } TextPS(x,FrameBottom-TimeLabelOffset,0,'C',DateStr); } else { /* Print day numbers, not hours */ strncat(DateStr,FullDateStr+6,2); /* If MajorTickPeriod is one day print day */ /* number between the tick marks */ // if (MajorTickPeriod == 1440) { // if (CurrTime < EndTime) // TextPS(x+dx/2,FrameBottom-TimeLabelOffset,0,'C',DateStr); // } else TextPS(x,FrameBottom-TimeLabelOffset,0,'C',DateStr); } x += dx; CurrTime += 60*MajorTickPeriod; count++; } while ((CurrTime <= EndTime) && (count < 200)); /* Print the text indicating time unit */ x = FrameLeft+FrameWidth/2; y = FrameBottom-TimeTitleOffset; FontPS(TimeTitleFont,TimeTitleFontSize); if ((EndTime-StartTime) <= 86400L) { /* Print hour text */ if (Finnish) TextPS(x,y,0.0,'C',"Tunti (Suomen aika)"); else TextPS(x,y,0.0,'C',"Hour (UT)"); } else { /* Print day text */ if (Finnish) TextPS(x,y,0.0,'C',"Kuukauden pŠivŠ"); else TextPS(x,y,0.0,'C',"Day of month"); } } /*--------------------------------------------------------------------------*/ /* Draw the time axis, tick marks and vertical grid lines */ /*--------------------------------------------------------------------------*/ void DrawTimeAxis(Time_sec StartTime, Time_sec EndTime) { float x,dx; float TimeScale; Time_sec CurrTime; long count = 0; if (!PrintTimeAxis) return; TimeScale = (FrameWidth-TimeTickLeft-TimeTickRight)/(EndTime-StartTime); CurrTime = StartTime; // Fix 12.12.2018. The first tick mark doesn't have to be at StartTime if (StartTime % (60*MinorTickPeriod) != 0) { CurrTime += 60*MinorTickPeriod - (StartTime % (60*MinorTickPeriod)); } x = FrameLeft+TimeTickLeft + TimeScale*(CurrTime - StartTime); dx = 60*TimeScale*MinorTickPeriod; do { // if ((CurrTime-StartTime) % (60*MajorTickPeriod) == 0) { /* Major */ if (CurrTime % (60*MajorTickPeriod) == 0) { /* Major */ if (PrintVerGridLines) { LineWidthPS(GridLineWidth); LineTypePS(GridLineType,GridLinePeriod); LinePS(x,FrameBottom,x,FrameBottom+FrameHeight); } LineWidthPS(TickMarkWidth); LineTypePS(0,0); if (PrintLowerTicks) LinePS(x,FrameBottom,x,FrameBottom+MajorTickLength); if (PrintUpperTicks) LinePS(x,FrameBottom+FrameHeight,x, FrameBottom+FrameHeight-MajorTickLength); } else { /* Minor */ LineWidthPS(TickMarkWidth); LineTypePS(0,0); if (PrintLowerTicks) LinePS(x,FrameBottom,x,FrameBottom+MinorTickLength); if (PrintUpperTicks) LinePS(x,FrameBottom+FrameHeight,x, FrameBottom+FrameHeight-MinorTickLength); } x += dx; CurrTime += 60*MinorTickPeriod; count++; } while ((CurrTime <= EndTime) && (count < 200)); } /*--------------------------------------------------------------------------*/ /* Draw text displaying the current component in the left part of the plot */ /*--------------------------------------------------------------------------*/ void DrawIndexName(char GramType) { float x,y; char Title[20]; if (!PrintIndexName) return; if (Finnish) { switch (GramType) { case 'L' : strcpy(Title,"IL"); break; case 'U' : strcpy(Title,"IU"); break; case 'E' : strcpy(Title,"IE"); break; case 'A' : strcpy(Title,"IL ja IU"); break; case 'S' : strcpy(Title,"Asemakoodi"); break; } } else { switch (GramType) { case 'L' : strcpy(Title,"IL"); break; case 'U' : strcpy(Title,"IU"); break; case 'E' : strcpy(Title,"IE"); break; case 'A' : strcpy(Title,"IL and IU"); break; case 'S' : strcpy(Title,"Station code"); break; } } FontPS(FieldTitle,FieldTitleSize); x = FrameLeft-FieldTitleOffset; y = FrameBottom+0.5*FrameHeight; TextPS(x,y,90.0,'C',Title); } /*--------------------------------------------------------------------------*/ /* Draw text displaying the current averaging value used in the data plots */ /*--------------------------------------------------------------------------*/ void DrawAveragingValue(long AveragingValue) { float x,y; char AverageStr[100]; if (!PrintAverageValue) return; FontPS(AverageFont,AverageFontSize); x = FrameLeft+FrameWidth; y = FrameBottom+FrameHeight+AverageOffset; if (AveragingValue < 60) { if (Finnish) sprintf(AverageStr,"%d sekunnin keskiarvot",AveragingValue); else sprintf(AverageStr,"%d second averages",AveragingValue); } else { if (Finnish) sprintf(AverageStr,"%d minuutin keskiarvot",AveragingValue/60); else sprintf(AverageStr,"%d minute averages",AveragingValue/60); } TextPS(x,y,0.0,'R',AverageStr); } /*--------------------------------------------------------------------------*/ /* Get the FieldAmpitude from FieldAmplitudeStr */ /*--------------------------------------------------------------------------*/ long GetAmplitude(long GramIndex, char *AmplitudeStr) { char *p = AmplitudeStr; long i, value; if (strlen(AmplitudeStr) == 0) return 0; /* search proper amplitude by scanning ',' */ for (i=0;i 0) Min = 0; return RoundFieldAmplitude(Max-Min); } if (CurrentGram == 'U') { FindMaxMin(Station,'Y',StartTime,EndTime-StartTime,&Max,&Min); if (Max < 0) Max = 0; if (Min > 0) Min = 0; return RoundFieldAmplitude(Max-Min); } if (CurrentGram == 'E') { FindMaxMin(Station,'Z',StartTime,EndTime-StartTime,&Max,&Min); return RoundFieldAmplitude(Max); } if (CurrentGram == 'A') { FindMaxMin(Station,'X',StartTime,EndTime-StartTime,&Max,&Min); FindMaxMin(Station,'Y',StartTime,EndTime-StartTime,&Max2,&Min2); return RoundFieldAmplitude(Max2-Min); } } /*--------------------------------------------------------------------------*/ /* Get the field base line */ /*--------------------------------------------------------------------------*/ void GetFieldBase(StationPtr Station,Time_sec StartTime,Time_sec EndTime,char CurrentGram, float *yCoord, long *Baseline) { long IUMax,IUMin; long ILMax,ILMin; char Comp; if (CurrentGram == 'L') { FindMaxMin(Station,'X',StartTime,EndTime-StartTime,&ILMax,&ILMin); *Baseline = 0; if (ILMax < 0) ILMax = 0; if (ILMin > 0) ILMin = 0; *yCoord = FrameBottom + yBottomMargin - (ILMin*(FrameHeight-yTopMargin-yBottomMargin))/(ILMax-ILMin); /* *yCoord = FrameBottom + FrameHeight - yTopMargin; */ } if (CurrentGram == 'U') { FindMaxMin(Station,'Y',StartTime,EndTime-StartTime,&IUMax,&IUMin); *Baseline = 0; if (IUMax < 0) IUMax = 0; if (IUMin > 0) IUMin = 0; *yCoord = FrameBottom + yBottomMargin - (IUMin*(FrameHeight-yTopMargin-yBottomMargin))/(IUMax-IUMin); /* *yCoord = FrameBottom + yBottomMargin; */ } if (CurrentGram == 'E') { *Baseline = 0; *yCoord = FrameBottom + yBottomMargin; } if (CurrentGram == 'A') { FindMaxMin(Station,'X',StartTime,EndTime-StartTime,&ILMax,&ILMin); FindMaxMin(Station,'Y',StartTime,EndTime-StartTime,&IUMax,&IUMin); *Baseline = 0; *yCoord = FrameBottom + yBottomMargin - (ILMin*(FrameHeight-yTopMargin-yBottomMargin))/(IUMax-ILMin); } } /*--------------------------------------------------------------------------*/ /* Set the MajorFieldPeriod and MinorFieldPeriod. If their values are -1 */ /* then new values will be substituted, otherwise the values read from */ /* the parameter file will be used. */ /*--------------------------------------------------------------------------*/ void SetFieldTickPeriods(long Major, long Minor) { /* if (MajorFieldPeriod == -1) MajorFieldPeriod = Major; if (MinorFieldPeriod == -1) MinorFieldPeriod = Minor; */ MajorFieldPeriod = Major; MinorFieldPeriod = Minor; } /*--------------------------------------------------------------------------*/ /* Find reasonable values for MajorFieldPeriod and MinorFieldPeriod based */ /* the total length (= Amplitude) of the vertical (= field) axis. */ /*--------------------------------------------------------------------------*/ void FindFieldTickPeriods(long Amplitude) { if (Amplitude <= 100) SetFieldTickPeriods( 50,10); else if (Amplitude <= 400) SetFieldTickPeriods( 100,50); else if (Amplitude <= 1000) SetFieldTickPeriods( 500,100); else if (Amplitude <= 4000) SetFieldTickPeriods(1000,500); else if (Amplitude <= 10000) SetFieldTickPeriods(5000,1000); else if (Amplitude <= 40000) SetFieldTickPeriods(5000,1000); else SetFieldTickPeriods(10000,5000); } /*--------------------------------------------------------------------------*/ /* Draw the field axis tick marks and horizontal grid lines and also the */ /* field values. */ /*--------------------------------------------------------------------------*/ void DrawFieldAxis(float yBase, long BaseValue, char GramType, long Amplitude) { float y,dy; float FieldScale; long CurrValue,StartValue; char FieldStr[20]; long count = 0; FontPS(FieldLabelFont,FieldLabelFontSize); FieldScale = (FrameHeight-yTopMargin-yBottomMargin)/Amplitude; dy = MinorFieldPeriod*FieldScale; /* Upwards from Basevalue */ StartValue = BaseValue; CurrValue = StartValue; y = yBase; do { if ((CurrValue-StartValue) % MajorFieldPeriod == 0) { /* Major */ if (PrintHorGridLines) { LineWidthPS(GridLineWidth); LineTypePS(GridLineType,GridLinePeriod); LinePS(FrameLeft,y,FrameLeft+FrameWidth,y); LineTypePS(0,0.0); /* Return the continuous line type */ } LineWidthPS(FieldTickMarkWidth); LinePS(FrameLeft,y,FrameLeft+MajorFieldLength,y); LinePS(FrameLeft+FrameWidth,y, FrameLeft+FrameWidth-MajorFieldLength,y); if (PrintFieldValues) { /* Field values */ sprintf(FieldStr,"%d",CurrValue/10); TextPS(FrameLeft-FieldLabelOffset,y-0.1*FieldLabelFontSize ,0,'R',FieldStr); } } else { /* Minor */ LineWidthPS(FieldTickMarkWidth); LinePS(FrameLeft,y,FrameLeft+MinorFieldLength,y); LinePS(FrameLeft+FrameWidth,y, FrameLeft+FrameWidth-MinorFieldLength,y); } y += dy; CurrValue += MinorFieldPeriod; count++; } while ((y <= FrameBottom + FrameHeight) && (count < 200)); /* Downwards from Basevalue */ StartValue = BaseValue; CurrValue = StartValue; y = yBase; count = 0; while ((y > FrameBottom) && (count < 200)) { if ((CurrValue-StartValue) % MajorFieldPeriod == 0) { /* Major */ if (PrintHorGridLines) { LineWidthPS(GridLineWidth); LineTypePS(GridLineType,GridLinePeriod); LinePS(FrameLeft,y,FrameLeft+FrameWidth,y); LineTypePS(0,0.0); /* Return the continuous line type */ } LineWidthPS(FieldTickMarkWidth); LinePS(FrameLeft,y,FrameLeft+MajorFieldLength,y); LinePS(FrameLeft+FrameWidth,y, FrameLeft+FrameWidth-MajorFieldLength,y); if (PrintFieldValues) { /* Field values */ sprintf(FieldStr,"%d",CurrValue/10); TextPS(FrameLeft-FieldLabelOffset,y-0.1*FieldLabelFontSize ,0,'R',FieldStr); } } else { /* Minor */ LineWidthPS(FieldTickMarkWidth); LinePS(FrameLeft,y,FrameLeft+MinorFieldLength,y); LinePS(FrameLeft+FrameWidth,y, FrameLeft+FrameWidth-MinorFieldLength,y); } y -= dy; CurrValue -= MinorFieldPeriod; count++; }; } /*--------------------------------------------------------------------------*/ /* Here is the most important routine, the drawing of a single magnetogram.*/ /* The y-coordinate of the baseline value is at yBase. If AverageTime is */ /* larger than the sampling rate then compute averages and plot them. */ /*--------------------------------------------------------------------------*/ void DrawMagnetogram(StationPtr Station,char GramType,float yBase, long BaseValue,Time_sec StartTime,Time_sec EndTime,long AverageTime, long Amplitude, float red, float green, float blue) { float x,y,dx; float TimeScale; float FieldScale; Time_sec CurrTime = StartTime; long first = 1; long DotCount = 0; long *DataPtr; long Value; char Component; long count = 0; LineWidthPS(DataLineWidth); LineTypePS(0,0); SetColorPS(red, green, blue); FieldScale = (FrameHeight-yTopMargin-yBottomMargin)/Amplitude; TimeScale = (FrameWidth-TimeTickLeft-TimeTickRight)/(EndTime-StartTime); x = FrameLeft+TimeTickLeft; dx = AverageTime*TimeScale; if (StartTime < Station->StartTime) { x += (Station->StartTime-StartTime)*TimeScale; CurrTime = Station->StartTime; } if (EndTime > Station->EndTime) EndTime = Station->EndTime; /* Find the pointer to the data point corresponding to CurrTime */ switch (GramType) { case 'L' : DataPtr = Station->X; Component = 'X'; break; case 'U' : DataPtr = Station->Y; Component = 'Y'; break; case 'E' : DataPtr = Station->Z; Component = 'Z'; break; } DataPtr += (CurrTime-Station->StartTime)/(Station->TimeStep); while ((CurrTime < EndTime) && (count < 86400)) { if (Station->TimeStep == AverageTime) Value = *DataPtr++; else Value = ComputeAverage(Station,Component,CurrTime,AverageTime); if (PlotMode == 1) { /* Draw continuous line between data points */ if (Value != MissingValue) { y = yBase+FieldScale*(Value-BaseValue); if (first) { MoveToPS(x,y); first = 0; } else { LineToPS(x,y); DotCount++; if (DotCount == 300) { /* This prevents stack overflow */ ClosePathPS(); /* in many PostScript printers */ MoveToPS(x,y); DotCount = 0; } } } else { if (!first) { ClosePathPS(); first = 1; } } } else { /* Draw every data point as single dot */ if (Value != MissingValue) { y = yBase+FieldScale*(Value-BaseValue); FillCirclePS(x,y,DotRadius,0.0,0); } } x += dx; CurrTime += AverageTime; count++; } if (!first) ClosePathPS(); SetColorPS(0.0,0.0,0.0); /* black */ } /*--------------------------------------------------------------------------*/ /* Round the given time to previous full hour or next full hour. If the */ /* time is already at full hour then don't do anything. */ /*--------------------------------------------------------------------------*/ Time_sec PreviousHour(Time_sec T) { Time_struct MyTime; SecsToTm(T,&MyTime); MyTime.tm_min = 0; MyTime.tm_sec = 0; return (TmToSecs(&MyTime)); } Time_sec NextHour(Time_sec T) { Time_struct MyTime; SecsToTm(T,&MyTime); if ((MyTime.tm_min == 0) && (MyTime.tm_sec == 0)) return (T); else return (PreviousHour(T+3600)); } /*--------------------------------------------------------------------------*/ /* Handle the station statistics in IU and IL plots. */ /*--------------------------------------------------------------------------*/ void HandleStatistics(char *StationList, char *IUStr, char *ILStr) { char StationID[100][5]; long IUtable[100]; long ILtable[100]; long StationCount = 0; long i,value; char *p = IUStr; char *q = ILStr; float dx,dy,x,y,BarWidth; long maxIU,maxIL,countIU,countIL; float maxIUPercentige,maxILPercentige,maxPercentage; float PercScale; long CurrPerc,MinorTick,MajorTick; char PercStr[10]; /* Collect station ID's and counts into arrays */ for (i=0;i< (strlen(StationList)+1)/5; i++) { /* Station ID */ strncpy(StationID[i],StationList+1+5*i,3); StationID[i][3] = '\0'; StationCount++; /* IU count */ while (*p == ' ') p++; /* Scan spaces */ value = 0; while ((*p >= '0') && (*p <= '9')) { /* get the number */ value = 10*value+(*p-'0'); p++; } IUtable[i] = value; /* IL count */ while (*q == ' ') q++; /* Scan spaces */ value = 0; while ((*q >= '0') && (*q <= '9')) { /* get the number */ value = 10*value+(*q-'0'); q++; } ILtable[i] = value; } /* Compute total counts and max values */ countIU = 0; countIL = 0; maxIU = 0; maxIL = 0; for (i=0;i maxILPercentige) maxPercentage = maxIUPercentige; else maxPercentage = maxILPercentige; if (maxPercentage > 50.0) { maxPercentage = 100.0; MinorTick = 10; MajorTick = 50; } else if (maxPercentage > 30.0) { maxPercentage = 50.0; MinorTick = 5; MajorTick = 10; } else { maxPercentage = 30.0; MinorTick = 5; MajorTick = 10; } /* Draw frame of the statistics gram */ LineWidthPS(StatFrameLineWidth); RectPS(StatFrameLeft,StatFrameBottom,StatFrameWidth,StatFrameHeight,0.0); /* Draw title of the statistics gram */ FontPS(StatTitleFont,StatTitleFontSize); TextPS(StatFrameLeft+StatFrameWidth/2,StatFrameBottom+StatFrameHeight+StatTitleOffset,0.0,'C',TitleStr); /* Draw station ID's and percentage bars */ dy = StatFrameHeight/(StationCount+1); y = StatFrameBottom + StatFrameHeight - dy; BarWidth = StatBarWidth*dy; FontPS(StatLabelFont,StatLabelFontSize); for (i=0;i 0.8*dy) dy = 1.2*BarWidth; x = StatFrameLeft+0.75*StatFrameWidth; y = StatFrameBottom+15.0; FontPS(StatLabelFont,StatLabelFontSize); TextPS(x,y+dy,0,'L',"IU:"); TextPS(x,y ,0,'L',"IL:"); FillColorRectPS(x+10.0,y+dy,dx,BarWidth,0.0,1.0,0.0,0.0,1); FillColorRectPS(x+10.0,y ,dx,BarWidth,0.0,0.0,0.0,1.0,1); } /*--------------------------------------------------------------------------*/ /* The main procedure */ /*--------------------------------------------------------------------------*/ int main(int argc, char *argv[]) { long params; /* Dummy index variable */ long status = 0; /* Result code for file reading */ long FileCount = 0; /* Number of files. Must be 0 or 1 */ Network_struct IL_INDEX; /* Read IL index data here */ Network_struct IMAGE; /* Read station data here */ Time_sec StartTime,EndTime; /* Start and End time in seconds */ long GramIndex,StatIndex; /* Dummy indices */ long CompFound; /* Flag for checking magnetic components*/ char CurrentGram; /* Current gram type */ char c; StationPtr Station; /* Station structure for IL index data */ float yBase; /* Y-coordinate of the baseline line */ long BaseValue; /* Value of the field baseline (0.1 nT) */ /* Parameters read from the command line */ long HourCount = 0; long AverageTime = 0; long FieldAmplitude = 0; char IL_FileName[200] = ""; char IAGA_FileName[200] = ""; char StartTimeStr[20] = ""; char EndTimeStr[20] = ""; char StationList[400] = ""; char ParamFileName[200] = ""; char GramTypes[20] = "LUEA"; char BaselineList[500] = ""; char HeaderStr[200] = ""; char FieldAmplitudeStr[100] = ""; char IUstatStr[400] = ""; char ILstatStr[400] = ""; /*==========================*/ /* 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(IL_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 'c' : strcpy(GramTypes,argv[++params]); break; case 'i' : strcpy(IAGA_FileName,argv[++params]); break; case 'a' : AverageTime = atol(argv[++params]); break; case 'p' : strcpy(ParamFileName,argv[++params]); break; case 'r' : strcpy(FieldAmplitudeStr,argv[++params]);break; case 't' : strcpy(HeaderStr,argv[++params]); break; case 'z' : Finnish = 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); } if (strlen(GramTypes) > 0) { for (GramIndex = 0; GramIndex < strlen(GramTypes); GramIndex++) { if (strchr("LUEAS",GramTypes[GramIndex]) == NULL) { fprintf(stderr,"Illegal gram type : \n", GramTypes[GramIndex]); PrintUsage(argv[0],1,HeaderLineCount,UsageLineCount); return FAIL; } } } /*===========================================*/ /* Read the data from data files into memory */ /*===========================================*/ /* --- IL index data file --- */ status = ReadIL(IL_FileName,&IL_INDEX,NULL,NULL,StationList,BaselineList,IUstatStr,ILstatStr); if (status != 0) { if (status == FileError) fprintf(stderr,"Error in reading data file\n"); if (status == OutOfMemory) fprintf(stderr,"Out of memory while reading data file\n"); if (status == FileFormatError) fprintf(stderr,"Wrong file format in input file\n"); return FAIL; } /* --- IAGA format data file --- */ if (strlen(IAGA_FileName) > 0) { status = ReadIAGA(IAGA_FileName,&IMAGE,NULL,NULL,NULL); if (status != 0) { if (status == FileError) fprintf(stderr,"Error in reading file %s\n",IAGA_FileName); if (status == OutOfMemory) fprintf(stderr,"Out of memory while reading file %s\n",IAGA_FileName); if (status == FileFormatError) fprintf(stderr,"%s is not an IAGA format file\n",IAGA_FileName); return FAIL; } } /*==========================================================*/ /* Determine the start,end and averaging times for the plot */ /*==========================================================*/ Station = IL_INDEX.StationList; if (strlen(StartTimeStr) == 0) { StartTime = Station->StartTime; StartTime = PreviousHour(StartTime); /* Round to the previous full hour */ } else StartTime = StrToSecsC(StartTimeStr,0); if (strlen(EndTimeStr) == 0) { EndTime = Station->EndTime; EndTime = NextHour(EndTime); /* Round to next full hour */ } else EndTime = StrToSecsC(EndTimeStr,0); if (AverageTime == 0) AverageTime = Station->TimeStep; if (AverageTime < Station->TimeStep) { fprintf(stderr,"Given average time (-a) %d s is smaller that sampling rate %d s \n", AverageTime,Station->TimeStep); fprintf(stderr,"No data is written into postscript file \n"); return FAIL; } /*==============================================*/ /* Read the parameter file if necessary */ /*==============================================*/ if (strlen(ParamFileName) > 0) { status = ReadParameterFile(ParamFileName); if (status == FileError) { fprintf(stderr,"Error in reading parameter file :%s\n",ParamFileName); return FAIL; } } /*======================================================*/ /* If HeaderStr is defined by -t option in the command */ /* line the use it as the figure title instead of what */ /* ever is defined in the parameter file. */ /*======================================================*/ if (strlen(HeaderStr) > 0) strcpy(TitleStr,HeaderStr); /*===============================================*/ /* Find the Major and Minor TickPeriods based on */ /* StartTime and EndTime. */ /*===============================================*/ FindTickPeriods(StartTime,EndTime); /*==============================================*/ /* Write the Title, Creator and Creation date */ /* and initialize the postscript file */ /*==============================================*/ WritePSHeader(GramTypes); /*==============================*/ /* Go through all gram types */ /*==============================*/ for (GramIndex = 0; GramIndex < strlen(GramTypes); GramIndex++) { NewPagePS(GramIndex+1); if (LandscapeMode) LandscapePS(); ZoomPS(ZoomFactor); CurrentGram = GramTypes[GramIndex]; if (strlen(HeaderStr) > 0) strcpy(TitleStr,HeaderStr); else FindTitleStr(Station,TitleStr,CurrentGram,StartTime,EndTime); if (CurrentGram != 'S') { DrawFrame(); DrawTitle(); DrawAveragingValue(AverageTime); DrawTimeAxis(StartTime,EndTime); DrawTimeLabels(StartTime,EndTime); DrawIndexName(CurrentGram); FieldAmplitude = GetAmplitude(GramIndex,FieldAmplitudeStr); if (FieldAmplitude == 0) FieldAmplitude = ComputeAmplitude(Station,CurrentGram,StartTime,EndTime); FindFieldTickPeriods(FieldAmplitude); GetFieldBase(Station,StartTime,EndTime,CurrentGram,&yBase,&BaseValue); DrawFieldAxis(yBase,BaseValue,CurrentGram,FieldAmplitude); if (CurrentGram == 'A') { DrawMagnetogram(Station,'U',yBase,BaseValue,StartTime,EndTime,AverageTime,FieldAmplitude,1.0,0.0,0.0); DrawMagnetogram(Station,'L',yBase,BaseValue,StartTime,EndTime,AverageTime,FieldAmplitude,0.0,0.0,1.0); } else { DrawMagnetogram(Station,CurrentGram,yBase,BaseValue,StartTime,EndTime,AverageTime,FieldAmplitude,0.0,0.0,0.0); } } else { /* CurrentGram == 'S' , Draw station statistics */ HandleStatistics(StationList,IUstatStr,ILstatStr); } ClosePagePS(); } ClosePS(); FreeNetwork(&IL_INDEX); return OK; }