source: trunk/src/seismic_processing/gmew/gm_config.c @ 8019

Revision 8019, 41.9 KB checked in by kevin, 3 months ago (diff)

Added Arias Intensity and ColorPGA option

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/*
2 *   THIS FILE IS UNDER RCS - DO NOT MODIFY UNLESS YOU HAVE
3 *   CHECKED IT OUT USING THE COMMAND CHECKOUT.
4 *
5 *    $Id$
6 *
7 *    Revision history:
8 *     $Log$
9 *     Revision 1.11  2009/08/25 00:10:40  paulf
10 *     added extraDelay parameter go gmew
11 *
12 *     Revision 1.10  2007/05/15 17:32:42  paulf
13 *     fixed qsort call (thanks to Ali M. from Utah for the catch
14 *
15 *     Revision 1.9  2006/03/15 14:21:54  paulf
16 *     SCNL version of gmew v0.2.0
17 *
18 *     Revision 1.8  2002/09/25 17:34:56  dhanych
19 *     added default value (3.0) for parameter snrThresh to initGM()
20 *
21 *     Revision 1.7  2002/02/28 17:03:36  lucky
22 *     Moved gma.c and gma.h to libsrc and main include
23 *
24 *     Revision 1.6  2001/07/18 19:41:36  lombard
25 *     Changed XMLDir, TempDir and MappingFile in GMPARAMS struct from string
26 *     arrays to string pointers. Changed gm_config.c and gm_util.c to support thes
27 *     changes. This solved a problem where the GMPARAMS structure was getting
28 *     corrupted when a pointer to it was passed into getGMFromTrace().
29 *     It's not clear why this was necessary; purify didn't complain.
30 *
31 *     Revision 1.5  2001/07/18 19:18:25  lucky
32 *     *** empty log message ***
33 *
34 *     Revision 1.4  2001/06/11 01:27:27  lombard
35 *     cleanup
36 *
37 *     Revision 1.3  2001/06/10 21:27:36  lombard
38 *     Changed single transport ring to input and output rings.
39 *     Added ability to handle multiple getEventsFrom commands.
40 *     Fixed handling of waveservers in config file.
41 *
42 *     Revision 1.2  2001/04/11 21:12:20  lombard
43 *     ../localmag/site.h ../localmag/lm_site.h
44 *
45 *     Revision 1.1  2001/03/30 19:14:25  lombard
46 *     Initial revision
47 *
48 *
49 *
50 */
51/*
52 * gm_config.c: routines to configure the gm module.
53 */
54
55
56#include <stdio.h>
57#include <stdlib.h>
58#include <string.h>
59
60#include "earthworm.h"
61#include "kom.h"
62#include "tlay.h"
63#include "ws_clientII.h"
64#include "gma.h"
65#include "gm_sac.h"
66#include "gm_util.h"
67#include "gm_ws.h"
68#include "gm_xml.h"
69#include "../localmag/lm_site.h"
70
71/* Internal Function Prototypes */
72static void initGM(GMPARAMS *);
73static int ReadConfig (GMPARAMS *, char * );
74
75#ifdef _WINNT
76/* Handle deprecation of strdup in windows */
77static char* mystrdup( const char* src ) {
78        char* dest = malloc( strlen(src) + 1 );
79        if ( dest != NULL )
80                strcpy( dest, src );
81        return dest;
82}
83#else
84#define mystrdup strdup
85#endif
86
87/*
88 * Configure: do all the configuration of gmew.
89 * This includes initializing the GMPARAMS structure, parsing the command-line
90 * arguments, parsing the config file, and checking configuration settings
91 * for consistency.
92 *    Returns: 0 on success
93 *            -1 on failure
94 */
95int Configure( GMPARAMS *pgmParams, int argc, char **argv, EVENT *pEvt, char *vsn)
96{
97  int rc = 0, logSwitch = 1;
98  int lenT, lenX;
99  char *configFile;
100  char *str, servDir[GM_MAXTXT];
101 
102  /* Set initial values, then parse the command-line options */
103  initGM( pgmParams );
104  if (argc == 2)
105    configFile = argv[1];
106  else
107  {
108    fprintf(stderr, "Usage: %s config-file\n", argv[0]);
109    fprintf(stderr, "   Version %s\n", vsn );
110    exit( -1 );
111  }
112   
113  /* Initialize the Earthworm logit system */
114  logit_init(configFile, 0, MAX_BYTES_PER_EQ, logSwitch);
115
116  /* Read the configuration file */
117  if ( (rc = ReadConfig( pgmParams, configFile )) < 0)
118    return rc;   /* Error; ReadConfig already complained */
119
120  /* Set defaults if they weren't already set */
121  if (pgmParams->traceSource == GM_UNDEF )
122    pgmParams->traceSource = GM_TS_WS;
123  if (pgmParams->saveTrace == GM_UNDEF)
124    pgmParams->saveTrace = GM_ST_NO;
125
126  /* Initialize the trace arrays.                                        */
127  if ( (rc = initBufs( pgmParams->maxTrace )) < 0)
128  {     /* initBufs already complained, so be silent here */
129    return rc;
130  }
131
132  switch( pgmParams->traceSource)
133  {
134  case GM_TS_WS:
135    if (pgmParams->pWSV == (WS_ACCESS *)NULL)
136    {   /* Set the default traceSource to wave_servers listed in *
137         * ${EW_PARAMS}/servers                                  */
138      if ( (str = getenv("EW_PARAMS")) == NULL)
139      {
140        logit("e", "Configure: environment variable EW_PARAMS not defined\n");
141        return -1;
142      }
143      if (strlen(str) > GM_MAXTXT - (strlen(DEF_SERVER) + 2))
144      {
145        logit("e", "Configure: environment variable EW_PARAMS too long;"
146              " increase GM_MAXTXT and recompile\n");
147        return -1;
148      }
149      sprintf(servDir, "%s/%s", str, DEF_SERVER);
150      if ( (pgmParams->pWSV = 
151            (WS_ACCESS *)calloc(1, sizeof(WS_ACCESS))) == 
152           (WS_ACCESS *)NULL)
153      {
154        logit("e", "Configure: out of memory for WS_ACCESS\n");
155        return -1;
156      }
157      if ( (pgmParams->pWSV->serverFile = mystrdup(servDir)) == NULL)
158      {
159        logit("e", "Configure: out of memory for serverFile\n");
160        return -1;
161      }
162    }
163    if (pgmParams->pWSV->pList == (SERVER *)NULL)
164    {
165      if (readServerFile(pgmParams) < 0)
166        return -1;
167    }
168    if (initWsBuf(pgmParams->maxTrace) < 0)
169    {
170      logit("e", "Configure: out of memory for trace_buf buffer\n");
171      return -1;
172    }
173    if (pgmParams->wsTimeout == 0)
174      pgmParams->wsTimeout = 5000;  /* Default, 5 seconds */
175    break;
176#ifdef EWDB
177  case GM_TS_EWDB:
178    if (pgmParams->pDBaccess == (DBACCESS *)NULL)
179    {
180      logit("e", 
181            "Configure: traceSource is EWDB but EWDBaccess not given\n");
182      rc = -1;
183    }
184    break;
185#endif
186  default:
187    logit("e", "Configure: unknown trace source <%d>.\n", 
188          pgmParams->traceSource);
189    rc = -1;
190  }
191
192  switch( pgmParams->respSource )
193  {
194  case GM_UNDEF:
195    logit("e", "Configure: required response source not specified\n");
196    rc = -1;
197    break;
198  case GM_RS_FILE:
199    /* Nothing to do for this */
200    break;
201#ifdef EWDB
202  case GM_RS_EWDB:
203    if (pgmParams->pDBaccess == NULL)
204    {
205      logit("e", 
206            "Configure: response source is EWDB but EWDBaccess not given\n");
207      rc = -1;
208    }
209    break;
210#endif
211  default:
212    logit("e", "Configure: unknown response source %d\n", 
213          pgmParams->respSource);
214    rc = -1;
215  }
216
217  /* Station Location Source: readConfig requires that it be set,
218        unless we're only responding to alarm messages */
219  switch (pgmParams->staLoc)
220  {
221  case GM_UNDEF:
222    break;
223  case GM_SL_HYP:
224    if ( site_read(pgmParams->staLocFile) < 0)
225      rc = -1;
226    break;
227#ifdef EWDB
228  case GM_SL_EWDB:
229    if ( pgmParams->pDBaccess == (DBACCESS *)NULL)
230    {
231      logit("e", "Configure: staLoc is EWDB but EWDBaccess not given\n");
232      rc = -1;
233    }
234    break;
235#endif
236  default:
237    logit("e", "Configure: unknown staLoc <%d>\n", pgmParams->staLoc);
238    rc = -1;
239  }
240 
241  if (pgmParams->saveTrace == GM_ST_SAC)
242  {  /* Initialize the SAC data array */
243    if ( initSACBuf( pgmParams->maxTrace ) < 0)
244    {
245      logit("e", "Configure: out of memory for SAC data\n");
246      return -1;
247    }
248  }
249
250  lenT = lenX = 0;
251  if (pgmParams->TempDir)
252    lenT = strlen(pgmParams->TempDir);
253  if (pgmParams->XMLDir)
254    lenX = strlen(pgmParams->XMLDir);
255  if ( lenT == 0 && lenX != 0)
256  {
257    logit("e", "XMLDir given but TempDir is missing\n");
258    rc = -1;
259  }
260
261  if (rc == 0)
262  {    /* Initialize the station list */
263    if ( (pEvt->Sta = (STA *)calloc( pgmParams->maxSta, sizeof(STA))) == 
264         (STA *)NULL)
265    {
266      logit("et", "Configure: out of memory for STA array\n");
267      return -1;
268    }
269
270    /* Turn on some debugging options */
271    if (pgmParams->debug & GM_DBG_WSC)
272      (void)setWsClient_ewDebug(1);
273 
274    if (pgmParams->debug & (GM_DBG_PZG | GM_DBG_TRS | GM_DBG_ARS))
275      transferDebug(pgmParams->debug >> 5);
276
277    /* Sort the SCNLPAR array to make searching more efficient */
278    if (pgmParams->numSCNLPar > 0)
279      qsort(pgmParams->pSCNLPar, pgmParams->numSCNLPar, sizeof(SCNLPAR),
280            CompareSCNLPARs);
281   
282    /* Initialize the XML mapping file */
283    if (lenX > 0)
284    {
285      if (pgmParams->MappingFile && strlen(pgmParams->MappingFile) != 0)
286      {
287        if (initMappings( pgmParams->MappingFile ) < 0)
288        {
289          logit("et", "gmew: error initializing mappings; exitting!\n");
290          rc = -1;
291        }
292      }
293    }
294  }
295 
296  return rc;
297}
298
299
300
301#define NUMREQ 9       /* Number of parameters that MUST be    */
302/*   set from the config file.          */
303
304/*      Function: ReadConfig                                            */
305static int ReadConfig (GMPARAMS *pgmParams, char *configfile )
306{
307  char     init[NUMREQ];  /* init flags, one byte for each required command */
308  int      nmiss;         /* number of required commands that were missed   */
309  char     *com;
310  char     *str;
311  char     *processor;
312  int      nfiles, rc;
313  int      i;
314  int      err = 0;
315  double dummy;
316  SCNLSEL   *newSel, *pAdd, *pDel;
317  char configPath[GM_MAXTXT], *paramsDir;
318  GMEW *pEW;
319 
320 
321  pEW = pgmParams->pEW;
322
323  pgmParams->waitTime=0;        /* don't wait by default since this seems to work for many small networks */
324 
325  pgmParams->LookAtVersion = vAll;   /* Look at all versions of all events */
326
327  pgmParams->alarmDuration=0; /* default: ignore alarm messages */
328  pgmParams->allowDuplicates=0; /* default: ignore dup channel names (including location code diffs) */
329  pgmParams->sendActivate=0; /* default: do not send ACTIVATE messages when done with XML files */
330  pgmParams->ariasIntensity=0; /* default: do not calculate the arias intensity */
331 
332  /* Set to zero one init flag for each required command */
333  for (i = 0; i < NUMREQ; i++)
334    init[i] = 0;
335
336  /* Open the main configuration file
337**********************************/
338  nfiles = k_open (configfile); 
339  if (nfiles == 0) 
340  {
341    if ( (paramsDir = getenv("EW_PARAMS")) == NULL)
342    {
343      fprintf(stderr, "gma: Error opening command file <%s>; EW_PARAMS not set\n", 
344              configfile);
345      return -1;
346    }
347    strcpy(configPath, paramsDir);
348    if (configPath[strlen(configPath)-1] != '/' || 
349        configPath[strlen(configPath)-1] != '\\')
350      strcat(configPath, "/");
351    strcat(configPath, configfile);
352    nfiles = k_open (configPath); 
353    if (nfiles == 0) 
354    {
355      fprintf(stderr, "gma: Error opening command file <%s> or <%s>\n", 
356              configfile, configPath);
357      return -1;
358    }
359  }
360
361  /* Process all command files
362***************************/
363  while (nfiles > 0)   /* While there are command files open */
364  {
365    while (k_rd ())        /* Read next line from active file  */
366    { 
367      com = k_str ();         /* Get the first token from line */
368
369      processor = "ReadConfig";
370     
371      /* Ignore blank lines & comments
372*******************************/
373      if (!com)
374        continue;
375      if (com[0] == '#')
376        continue;
377
378     
379     
380      /* Open a nested configuration file */
381      if (com[0] == '@') 
382      {
383        if ( (rc = k_open (&com[1])) == 0)
384        {
385          fprintf(stderr, "gma: Error opening command file <%s>\n", 
386                  &com[1]);
387          return -1;
388        }
389        nfiles = rc;
390        continue;
391      }
392
393      /* Station location source: required to process HYP2000ARC messages */
394      else if (k_its("staLoc") )
395      {
396        if ( (str = k_str()) )
397        {
398          if (k_its("File") )
399          {
400            if ( (str = k_str()) )
401            {
402              if ( (pgmParams->staLocFile = mystrdup(str)) == NULL)
403              {
404                logit("e", "ReadConfig: out of memory for staLoc\n");
405                return -1;
406              }
407              pgmParams->staLoc = GM_SL_HYP;
408              init[0] = 1;
409            }
410            else
411            {
412              logit("e", "ReadConfig: \"staLoc File\" missing filename\n");
413              err = -1;
414            }
415          }
416#ifdef EWDB
417          else if (k_its("EWDB") )
418          {
419            pgmParams->staLoc = GM_SL_EWDB;
420            init[0] = 1;
421          }
422#endif
423          else
424          {
425            logit("e", "ReadConfig: Unknown \"staLoc\": <%s>\n", str);
426            err = -1;
427          }
428        }
429        else
430        {
431          logit("e", "ReadConfig: \"staLoc\" missing argument\n");
432          err = -1;
433        }
434      }
435     
436      /* MaxSta: required */
437      else if (k_its("maxSta") )
438      {
439        pgmParams->maxSta = k_int();
440        /* tell lm_site.c about max size */
441        set_maxsite( pgmParams->maxSta );
442        init[1] = 1;
443      }
444     
445      /* MaxDist: required to process HYP2000ARC messages */
446      else if (k_its("maxDist") )
447      {
448        pgmParams->maxDist = k_val();
449        init[2] = 1;
450      }
451     
452      /* maxTrace: required */
453      else if (k_its("maxTrace") )
454      {
455        pgmParams->maxTrace = (long)k_int();
456        init[3] = 1;
457      }
458
459      else if (k_its("ChannelNumberMap") )
460      {
461        if ( (str = k_str()) )
462        {
463          if (strlen(str) > 3) 
464          {
465            logit("e", "ReadConfig: ChannelNumberMap is too long, only 3 chars allowed\n");
466            err = -1;
467          }
468          else 
469          {
470            /* note this copies the string to position 1, so that numbers can be mapped to chars easily */
471            strcpy(&pgmParams->ChannelNumberMap[1], str);
472            pgmParams->ChannelNumberMap[0]='_'; 
473          }
474        }
475      }
476     
477      /* Trace length (time): optional */
478      else if (k_its("traceTimes") )
479      {
480        pgmParams->traceStart = k_val();
481        pgmParams->traceEnd = k_val();
482      }
483     
484      /* Peak Search window parameters: optional */
485      else if (k_its("searchWindow") )
486      {
487        pgmParams->peakSearchStart = k_val();
488        pgmParams->peakSearchStartMin = k_val();
489        pgmParams->peakSearchEnd = k_val();
490        pgmParams->peakSearchEndMin = k_val();
491      }
492     
493      /* SNR threshold */
494      else if (k_its("snrThresh") )
495        pgmParams->snrThresh = k_val();
496
497      /* waitTime is in seconds to wait before processing an event */
498      else if (k_its("extraDelay") )
499      {
500        pgmParams->waitTime = k_val();
501      }
502     
503      /* LookAtVersion: optional */
504      else if (k_its("LookAtVersion") )
505      {
506        if ( (str = k_str()) )
507        {
508            if(strcmp(str, "All") == 0 ) {
509                pgmParams->LookAtVersion = vAll;   /* Look at all versions of all events */
510                logit("t", "readConfig: looking at all versions of the events.\n");
511            } else if(strcmp(str, "Prelim") == 0 ) {
512                pgmParams->LookAtVersion = vPrelim;   /* Look only at version Prelim of all events */
513                logit("t", "readConfig: looking only at version Prelim of the events.\n");
514            } else if(strcmp(str, "Rapid") == 0 ) {
515                pgmParams->LookAtVersion = vRapid;   /* Look only at version Rapid of all events */
516                logit("t", "readConfig: looking only at version Rapid of the events.\n");
517            } else if(strcmp(str, "Final") == 0 ) {
518                pgmParams->LookAtVersion = vFinal;   /* Look only at version Final of all events */
519                logit("t", "readConfig: looking only at version Final of the events.\n");
520            } else {
521                logit("e", "readConfig: value for optional parameter LookAtVersion is not valid. Possible values are the string: All, Prelim, Rapid or Final.\n");
522                return -1;
523            }
524        }
525      }
526
527      /* SCNL Selectors: optional */
528      else if (k_its("Add") )
529      {
530        if ( (str = k_str()) )  /* sta */
531        {
532          if ( (newSel = (SCNLSEL *)calloc(1, sizeof(SCNLSEL))) == NULL)
533          {
534            fprintf(stderr, "ReadConfig: out of memory for SCNLSEL\n");
535            return -1;
536          }
537          strncpy(newSel->sta, str, 6);
538          if ( (str = k_str()) )  /* comp */
539          {
540            strncpy(newSel->comp, str, 8);
541            if ( (str = k_str()) )  /* net */
542            {
543              strncpy(newSel->net, str, 8);
544              if ( (str = k_str()) )  /* loc */
545              {
546               strncpy(newSel->loc, str, 3);
547               if (pgmParams->pAdd == (SCNLSEL *)NULL)
548               {
549                 pgmParams->pAdd = newSel;
550                 pAdd = newSel;   /* Leave it pointing at the end of list */
551               }
552               else
553               {
554                 pAdd->next = newSel;
555                 pAdd = newSel;
556               }
557              }
558              else
559              {
560                fprintf(stderr, "ReadConfig: \"Add\" missing 1 of 5 arguments\n");
561                err = -1;
562                free(newSel);
563              }
564            }
565            else
566            {
567              fprintf(stderr, "ReadConfig: \"Add\" missing 2 of 5 arguments\n");
568              err = -1;
569              free(newSel);
570            }
571          }
572          else
573          {
574            fprintf(stderr, 
575                    "ReadConfig: \"Add\" missing 3 of 5 arguments\n");
576            err = -1;
577            free(newSel);
578          }
579        }
580        else
581        {
582          fprintf(stderr, "ReadConfig: \"Add\" missing 4 of 5 arguments\n");
583          err = -1;
584        }
585      }
586
587      /* SCN Deleteions: optional */
588      else if (k_its("Del") )
589      {
590        if ( (str = k_str()) )  /* sta */
591        {
592          if ( (newSel = (SCNLSEL *)calloc(1, sizeof(SCNLSEL))) == NULL)
593          {
594            fprintf(stderr, "ReadConfig: out of memory for SCNLSEL\n");
595            return -1;
596          }
597          strncpy(newSel->sta, str, 6);
598          if ( (str = k_str()) )  /* comp */
599          {
600            strncpy(newSel->comp, str, 8);
601            if ( (str = k_str()) )  /* net */
602            {
603              strncpy(newSel->net, str, 8);
604             if ( (str = k_str()) )  /* loc */
605              {
606                strncpy(newSel->loc, str, 3);
607                if (pgmParams->pDel == (SCNLSEL *)NULL)
608                {
609                  pgmParams->pDel = newSel;
610                  pDel = newSel;   /* Leave it pointing at the end of list */
611                }
612                else
613                {
614                  pDel->next = newSel;
615                  pDel = newSel;
616                }
617              }
618            else
619            {
620              fprintf(stderr, "ReadConfig: \"Del\" missing 1 of 5 arguments\n");
621              err = -1;
622              free(newSel);
623            }
624          }
625            else
626            {
627              fprintf(stderr, "ReadConfig: \"Del\" missing 2 of 5 arguments\n");
628              err = -1;
629              free(newSel);
630            }
631          }
632          else
633          {
634            fprintf(stderr, 
635                    "ReadConfig: \"Del\" missing 3 of 5 arguments\n");
636            err = -1;
637            free(newSel);
638          }
639        }
640        else
641        {
642          fprintf(stderr, "ReadConfig: \"Del\" missing 4 arguments\n");
643          err = -1;
644        }
645      }
646
647      /* Trace Source: optional */
648      else if (k_its( "traceSource" ))
649      {
650        if (pgmParams->traceSource == GM_UNDEF)
651        {                 /* Let command-line take precedence */
652          if ( (str = k_str()) )
653          {
654            if (k_its("waveServer"))
655            {
656              pgmParams->traceSource = GM_TS_WS;
657              if ( (str = k_str()) )
658              {
659                if ( (pgmParams->pWSV = 
660                      (WS_ACCESS *)calloc(1, sizeof(WS_ACCESS))) == NULL)
661                {
662                  logit("e", 
663                        "ReadConfig: out of memory for SERVER\n");
664                  return -1;
665                }
666                if (k_its("File"))
667                {
668                  if ( (str = k_str()) )
669                  {
670                    if ( (pgmParams->pWSV->serverFile = mystrdup(str)) == NULL)
671                    {
672                      logit("e", 
673                            "ReadConfig: out of memory for serverFile\n");
674                      return -1;
675                    }
676                  }
677                  else
678                  {
679                    logit("e", 
680                          "ReadConfig: \"traceSource waveServer file\" missing filename\n");
681                    err = -1;
682                  }
683                }
684                else
685                {
686                  int ws_err;
687                  while(str)
688                  {
689                    if (Add2ServerList(str, pgmParams) < 0)
690                      err = -1;  /* Add2ServerList already complained */
691                    str = k_str();
692                    /* We have to catch the kom error here since we are *
693                     * intentionally trying to read to the end of the   *
694                     * string.                                          */
695                    ws_err = k_err();
696                    if (ws_err == -17 && pgmParams->pWSV->pList != 
697                        (PSERVER) NULL)
698                      continue;
699                    else if (ws_err < 0)
700                    {
701                      logit("e", 
702                            "ReadConfig: Bad <%s> command in <%s>\n\t%s\n",
703                            processor, configfile, k_com());
704                      return -1;
705                    }
706                  }
707                }
708                /* else default waveServer file is "servers" in $EW_PARAMS dir */
709              }
710            }
711          }
712          else
713          {
714            logit("e", "ReadConfig: Missing traceSource argument\n");
715            err = -1;
716          }
717        } /* else already set from command-line */
718      }
719     
720      /* Response Source: optional */
721      else if (k_its("respSource") )
722      {
723        if ( (str = k_str()) )
724        {
725          if (k_its("File") )
726          {
727            if ( (str = k_str()) )
728            {
729              if ( (pgmParams->respDir = mystrdup(str)) == NULL)
730              {
731                logit("e", "ReadConfig: out of memory for respDir\n");
732                return -1;
733              }
734              if ( (str = k_str()) )
735              {
736                if ( (pgmParams->respNameFormat = mystrdup(str)) == NULL)
737                {
738                  logit("e", 
739                        "ReadConfig: out of memory for respNameFormat\n");
740                  free(pgmParams->respDir);
741                  pgmParams->respDir = NULL;
742                  return -1;
743                }
744                pgmParams->respSource = GM_RS_FILE;
745              }
746              else
747              {
748                logit("e", 
749                      "ReadConfig: \"respSource FILE\" missing pz-filename-format\n");
750                err = -1;
751              }
752            }
753            else
754            {
755              logit("e", 
756                    "ReadConfig: \"respSource File\" missing 2 arguments\n");
757              err = -1;
758            }
759          }
760#ifdef EWDB
761          else if (k_its("EWDB") )
762          {
763            pgmParams->respSource = GM_RS_EWDB;
764          }
765#endif
766          else
767          {
768            logit("e", "ReadConfig: unknown \"respSource\" <%s>\n", str);
769            err = -1;
770          }
771        }
772        else
773        {
774          logit("e", "ReadConfig: \"respSource\" missing argument\n");
775          err = -1;
776        }
777      }
778     
779      /* the responses are in meters, from rdseed -pf, convert them to nanometers when read in */
780      else if (k_its("ResponseInMeters") )
781        setResponseInMeters( 1 );
782
783      /* Save Trace: optional */
784      else if (k_its("saveTrace") )
785      {
786        if (pgmParams->saveTrace == GM_UNDEF)
787        {
788          if ( (str = k_str()) )
789          {
790            if (k_its("None") )
791              pgmParams->saveTrace = GM_ST_NO;
792            else if (k_its("SAC") )
793            {
794              pgmParams->saveTrace = GM_ST_SAC;
795              if ( (str = k_str()) )
796              {
797                if ( (pgmParams->sacOutDir = mystrdup(str)) == (char *)NULL)
798                {
799                  logit("e", "readConfig: out of memory for sacOutDir\n");
800                  return -1;
801                } 
802                if ( (str = k_str()) )
803                {
804                  if ( (pgmParams->saveDirFormat = mystrdup(str)) == 
805                       (char *)NULL)
806                  {
807                    logit("e", "readConfig: out of memory for saveDirFormat\n");
808                    return -1;
809                  }
810                  if ( (str = k_str()) )
811                  {
812                    if ( (pgmParams->saveNameFormat = mystrdup(str)) == NULL)
813                    {
814                      logit("e", 
815                            "ReadConfig: out of memory for saveNameFormat\n");
816                      return -1;
817                    }
818                  }
819                  else
820                  {
821                    logit("e", 
822                          "ReadConfig: \"saveTrace SAC\" missing 1 argument\n");
823                    err = -1;
824                  }
825                }
826                else
827                {
828                  logit("e",
829                        "ReadConfig: \"saveTrace SAC\" missing 2 arguments\n");
830                  err = -1;
831                }
832              }
833              else
834              {
835                logit("e",
836                      "ReadConfig: \"saveTrace SAC\" missing 3 arguments\n");
837                err = -1;
838              }
839            }
840            else
841            {
842              logit("e", "ReadConfig: unknown \"saveTrace\" arg <%s>\n", str);
843              err = -1;
844            }
845          }
846          else
847          {
848            logit("e", "ReadConfig: \"saveTrace\" missing argument\n");
849            err = -1;
850          }
851        }
852      }
853     
854
855      /* SCNL Parameters: optional */
856      else if (k_its("SCNLpar") )
857      {
858        if (pgmParams->numSCNLPar >= pgmParams->maxSCNLPar)
859        {
860          pgmParams->maxSCNLPar += 10;
861          if ( (pgmParams->pSCNLPar = 
862                (SCNLPAR *)realloc(pgmParams->pSCNLPar, sizeof(SCNLPAR) *
863                                  pgmParams->maxSCNLPar)) == (SCNLPAR *)NULL)
864          {
865            fprintf(stderr, "ReadConfig: out of memory for %d SCNLPARs\n",
866                    pgmParams->maxSCNLPar);
867            return -1;
868          }
869        }
870        if ( (str = k_str()) == NULL)
871        {
872          fprintf(stderr, "ReadConfig: Bad \"SCNLPar\" command\n");
873          return -1;
874        }
875        strncpy(pgmParams->pSCNLPar[pgmParams->numSCNLPar].sta, str, 
876                TRACE_STA_LEN);
877        if ( (str = k_str()) == NULL)
878        {
879          fprintf(stderr, "ReadConfig: Bad \"SCNLPar\" command\n");
880          return -1;
881        }
882        strncpy(pgmParams->pSCNLPar[pgmParams->numSCNLPar].comp, str, 
883                TRACE_CHAN_LEN);
884        if ( (str = k_str()) == NULL)
885        {
886          fprintf(stderr, "ReadConfig: Bad \"SCNLPar\" command\n");
887          return -1;
888        }
889        strncpy(pgmParams->pSCNLPar[pgmParams->numSCNLPar].net, str,
890                TRACE_NET_LEN);
891        if ( (str = k_str()) == NULL)
892        {
893          fprintf(stderr, "ReadConfig: Bad \"SCNLPar\" command\n");
894          return -1;
895        }
896        strncpy(pgmParams->pSCNLPar[pgmParams->numSCNLPar].loc, str,
897                TRACE_LOC_LEN);
898        dummy = k_val(); /* Throw away the station magnitude correction */
899        pgmParams->pSCNLPar[pgmParams->numSCNLPar].fTaper[0] = k_val();
900        pgmParams->pSCNLPar[pgmParams->numSCNLPar].fTaper[1] = k_val();
901        pgmParams->pSCNLPar[pgmParams->numSCNLPar].fTaper[2] = k_val();
902        pgmParams->pSCNLPar[pgmParams->numSCNLPar].fTaper[3] = k_val();
903        pgmParams->pSCNLPar[pgmParams->numSCNLPar].clipLimit = k_val();
904        pgmParams->pSCNLPar[pgmParams->numSCNLPar].taperTime = k_val();
905        pgmParams->numSCNLPar++;
906      }
907       
908#ifdef EWDB
909      /* Earthworm Database access: optional */
910      else if (k_its("EWDBaccess") )
911      {
912        if ( (str = k_str()) )
913        {
914          if ( (pgmParams->pDBaccess = 
915                (DBACCESS *)calloc(1, sizeof(DBACCESS))) == NULL)
916          {
917            logit("e", "ReadConfig: out of memory for DBACCESS\n");
918            return -1;
919          }
920          if ( (pgmParams->pDBaccess->user = mystrdup(str)) == NULL)
921          {
922            logit("e", "ReadConfig: out of memory for DBA user\n");
923            return -1;
924          }
925          if ( (str = k_str()) )
926          {
927            if ( (pgmParams->pDBaccess->pwd = mystrdup(str)) == NULL)
928            {
929              logit("e", "ReadConfig: out of memory for DBA password\n");
930              return -1;
931            }
932            if (  (str = k_str()) )
933            {
934              if ( (pgmParams->pDBaccess->service = mystrdup(str)) == NULL)
935              {
936                logit("e", "ReadConfig: out of memory for DBA service\n");
937                return -1;
938              }
939            }
940            else
941            {
942              logit("e", 
943                    "ReadConfig: \"EWDBaccess\" missing arguments; 3 required\n");
944              err = -1;
945            }
946          }
947          else
948          {
949            logit("e", 
950                  "ReadConfig: \"EWDBaccess\" missing arguments; 3 required\n");
951            err = -1;
952          }
953        }
954        else
955        {
956          logit("e", 
957                "ReadConfig: \"EWDBaccess\" missing arguments; 3 required\n");
958          err = -1;
959        }
960      }
961#endif     
962
963      /* Earthworm transport stuff */
964      else if (k_its("HeartBeatInterval") )
965      {
966        pgmParams->HeartBeatInterval = k_int();
967        init[4] = 1;       
968      }
969
970      else if (k_its("RingInName") )
971      {
972        if ((str = k_str ()) != NULL)
973        {
974          if( ( pEW->RingInKey = GetKey(str) ) == -1 ) 
975          {
976            logit("e", "ReadConfig:  Invalid input ring name <%s>", str);
977            err = -1;
978          }
979          init[5] = 1;
980        }
981        else
982        {
983          logit("e", "ReadConfig: \"RingInName\" missing argument\n");
984          err = -1;
985        }
986      }
987
988      else if (k_its("RingOutName") )
989      {
990        if ((str = k_str ()) != NULL)
991        {
992          if( ( pEW->RingOutKey = GetKey(str) ) == -1 ) 
993          {
994            logit("e", "ReadConfig:  Invalid output ring name <%s>", str);
995            err = -1;
996          }
997          init[6] = 1;
998        }
999        else
1000        {
1001          logit("e", "ReadConfig: \"RingOutName\" missing argument\n");
1002          err = -1;
1003        }
1004      }
1005
1006      else if (k_its ("MyModId")) 
1007      {
1008        if ((str = k_str ()) != NULL)
1009        {
1010          if ( GetModId( str, &pEW->hrtLogo.mod ) != 0 ) 
1011          {
1012            logit("e", "ReadConfig: Invalid module name <%s>", str );
1013            return( -1 );
1014          }
1015          if ( GetLocalInst( &pEW->hrtLogo.instid ) != 0 ) 
1016          {
1017            logit("e", "ReadConfig: error getting local installation id" );
1018            return( -1 );
1019          }
1020          if ( GetType( "TYPE_HEARTBEAT", &pEW->hrtLogo.type ) != 0 ) 
1021          {
1022            logit("e", 
1023          "ReadConfig: Invalid message type <TYPE_HEARTBEAT>; exiting!\n" );
1024            return( -1 );
1025          }
1026          pEW->errLogo.mod = pEW->hrtLogo.mod;
1027          pEW->errLogo.instid = pEW->hrtLogo.instid;
1028          if ( GetType( "TYPE_ERROR", &pEW->errLogo.type ) != 0 ) 
1029          {
1030            logit("e", "ReadConfig: Invalid message type <TYPE_ERROR>" );
1031            return( -1 );
1032          }
1033
1034          pEW->gmLogo.mod =  pEW->hrtLogo.mod;
1035          pEW->gmLogo.instid =  pEW->hrtLogo.instid;
1036          if ( GetType( "TYPE_STRONGMOTIONII", &pEW->gmLogo.type ) != 0)
1037          {
1038            logit("e", "ReadConfig: Invalid msg type <TYPE_STRONGMOTIONII>" );
1039            return( -1 );
1040          }
1041
1042          pEW->ha2kLogo.mod =  pEW->hrtLogo.mod;
1043          pEW->ha2kLogo.instid =  pEW->hrtLogo.instid;
1044
1045          pEW->amLogo.mod =  pEW->hrtLogo.mod;
1046          pEW->amLogo.instid =  pEW->hrtLogo.instid;
1047
1048          pEW->threshLogo.mod =  pEW->hrtLogo.mod;
1049          pEW->threshLogo.instid =  pEW->hrtLogo.instid;
1050        }
1051        init[7] = 1;
1052      }
1053      else if (k_its("getEventsFrom") )
1054      {
1055        MSG_LOGO *tLogo = NULL;
1056        tLogo = (MSG_LOGO *)realloc( pEW->GetLogo, (pEW->nGetLogo+1) * 
1057                                     sizeof(MSG_LOGO));
1058        if( tLogo == NULL )
1059        {
1060          logit("e", "ReadConfig: getEventsFrom: error reallocing"
1061                " %zu bytes; exiting!\n",
1062                (pEW->nGetLogo+1)*sizeof(MSG_LOGO) );
1063          return( -1 );
1064        }
1065        pEW->GetLogo = tLogo;
1066        if ((str = k_str ()) != NULL)
1067        {
1068          if ( GetInst( str, &(pEW->GetLogo[pEW->nGetLogo].instid) ) != 0 )
1069          {
1070            logit("e", "ReadConfig: getEventsFrom: invalid installation `%s'\n",
1071                  str );
1072            return( -1 );
1073          }
1074        }
1075        if( ( str = k_str() ) != NULL )
1076        {
1077          if ( GetModId( str, &(pEW->GetLogo[pEW->nGetLogo].mod) ) != 0 )
1078          {
1079            logit("e", "ReadConfig: getEventsFrom: invalid module id `%s'\n",
1080                  str );
1081            return( -1 );
1082          }
1083        }
1084        if ( GetType( "TYPE_HYP2000ARC", &(pEW->GetLogo[pEW->nGetLogo].type) ) != 0 )
1085        {
1086          logit("e", "ReadConfig: getEventsFrom: invalid msgtype `%s'\n", 
1087                "TYPE_HYP2000ARC");
1088          return( -1 );
1089        }
1090        pEW->ha2kLogo.type = pEW->GetLogo[pEW->nGetLogo].type;
1091        pEW->nGetLogo++;
1092        init[8] = 1;
1093      }
1094       
1095      /* Optional: wave_server timeout */
1096      else if (k_its("wsTimeout") )
1097      {
1098        pgmParams->wsTimeout = k_int();
1099      }
1100
1101      /* Optional XML stuff */
1102      else if (k_its( "XMLDir" ) )
1103      {
1104        if ( (str = k_str()) )
1105        {
1106          if ( (pgmParams->XMLDir = mystrdup(str)) == NULL)
1107          {
1108            logit("e", "ReadConfig: out of memory for XMLDir\n");
1109            return -1;
1110          }
1111        }
1112        else
1113        {
1114          fprintf( stderr, "gmew: Bad <XMLDir> command in <%s>;"
1115                   " exiting!\n", configfile );
1116          err = -1;
1117        }
1118      }
1119      else if (k_its( "TempDir" ) )
1120      {
1121        if ( (str = k_str()) )
1122        {
1123          if ( ( pgmParams->TempDir = mystrdup(str)) == NULL)
1124          {
1125            logit("e", "ReadConfig: out of memory for TempDir\n");
1126            return -1;
1127          }
1128        }
1129        else
1130        {
1131          fprintf( stderr, "gmew: Bad <TempDir> command in <%s>;"
1132                   " exiting!\n", configfile );
1133          err = -1;
1134        }
1135      }
1136      else if (k_its( "MappingFile" ) )
1137      {
1138        if ( (str = k_str()) )
1139        {
1140          if ( ( pgmParams->MappingFile = mystrdup(str)) == NULL)
1141          {
1142            logit("e", "ReadConfig: out of memory for MappingFile\n");
1143            return -1;
1144          }
1145        }
1146        else
1147        {
1148          fprintf( stderr, "gmew: Bad <MappingFile> command in <%s>;"
1149                   " exiting!\n", configfile );
1150          err = -1;
1151        }
1152      }
1153     
1154      /* Optional: debug command */
1155      else if (k_its( "Debug") )
1156      {
1157        pgmParams->debug |= k_int();
1158      }
1159     
1160      /* Optional: Respond to dup SCNs - note location code was ignored otherwise if multiple at a sta */
1161      else if (k_its( "allowDuplicates") )
1162      {
1163        pgmParams->allowDuplicates = 1;
1164      }
1165      /* Optional: send activation requests */
1166      else if (k_its( "sendActivateLogo") )
1167      {
1168      /* get the module ide to use for send activate */
1169        str = k_str();
1170        if ( GetModId( str, &(pEW->amLogo.mod) ) != 0 )
1171        {
1172          logit("e", "ReadConfig: sendActivateLogo: invalid module  string %s\n", str);
1173          return( -1 );
1174        }
1175      }
1176      /* Optional: arias intensity */
1177      else if (k_its( "ariasIntensity") )
1178      {
1179        pgmParams->ariasIntensity = 1;
1180      }
1181      else if (k_its( "sendActivate") )
1182      {
1183        if ( GetType( "TYPE_ACTIVATE_MODULE", &(pEW->amLogo.type) ) != 0 )
1184        {
1185          logit("e", "ReadConfig: sendAlarm: invalid msgtype `TYPE_ACTIVATE_MODULE'\n");
1186          return( -1 );
1187        }
1188        pgmParams->sendActivate = 1;
1189      }
1190     /* Optional: Respond to thresh alarms */
1191     else if (k_its( "watchForThreshAlert") )
1192     {
1193       MSG_LOGO *tLogo = NULL;
1194       tLogo = (MSG_LOGO *)realloc( pEW->GetLogo, (pEW->nGetLogo+1) * 
1195                                    sizeof(MSG_LOGO));
1196       if( tLogo == NULL )
1197       {
1198         logit("e", "ReadConfig: watchForThreshAlert: error reallocing"
1199               " %zu bytes; exiting!\n",
1200               (pEW->nGetLogo+1)*sizeof(MSG_LOGO) );
1201         return( -1 );
1202       }
1203       pEW->GetLogo = tLogo;
1204if ( GetInst( "INST_WILDCARD", &(pEW->GetLogo[pEW->nGetLogo].instid) ) != 0 )
1205{
1206  logit("e", "ReadConfig: watchForThreshAlert: invalid installation `INST_WILDCARD'\n");
1207  return( -1 );
1208}
1209   if ( GetModId( "MOD_WILDCARD", &(pEW->GetLogo[pEW->nGetLogo].mod) ) != 0 )
1210       {
1211         logit("e", "ReadConfig: watchForThreshAlert: invalid module id `MOD_WILDCARD'\n");
1212         return( -1 );
1213       }
1214       if ( GetType( "TYPE_THRESH_ALERT", &(pEW->GetLogo[pEW->nGetLogo].type) ) != 0 )
1215       {
1216         logit("e", "ReadConfig: watchForThreshAlert: invalid msgtype `TYPE_THRESH_ALERT'\n");
1217         return( -1 );
1218       }
1219       pEW->threshLogo.type = pEW->GetLogo[pEW->nGetLogo].type;
1220        str = k_str();
1221        if ( str ) {
1222                pgmParams->threshDuration = atoi( str );
1223                if ( pgmParams->threshDuration <= 0 ) {
1224                        logit("e", "ReadConfig: watchForThreshAlert: invalid duration '%s'; ignoring\n",
1225                                str );
1226                        pgmParams->threshDuration = 0;
1227                }
1228        } else {
1229            k_err();    /* Clear the error of not finding a duration argument */
1230                pgmParams->threshDuration = 20;
1231        }
1232       pEW->nGetLogo++;
1233     }
1234     /* Optional: Respond to activation requests */
1235      else if (k_its( "watchForAlarm") )
1236      {
1237        MSG_LOGO *tLogo = NULL;
1238        tLogo = (MSG_LOGO *)realloc( pEW->GetLogo, (pEW->nGetLogo+1) * 
1239                                     sizeof(MSG_LOGO));
1240        if( tLogo == NULL )
1241        {
1242          logit("e", "ReadConfig: watchForAlarm: error reallocing"
1243                " %zu bytes; exiting!\n",
1244                (pEW->nGetLogo+1)*sizeof(MSG_LOGO) );
1245          return( -1 );
1246        }
1247        pEW->GetLogo = tLogo;
1248            if ( GetInst( "INST_WILDCARD", &(pEW->GetLogo[pEW->nGetLogo].instid) ) != 0 )
1249            {
1250                  logit("e", "ReadConfig: watchForAlarm: invalid installation `INST_WILDCARD'\n");
1251                  return( -1 );
1252            }
1253        if ( GetModId( "MOD_WILDCARD", &(pEW->GetLogo[pEW->nGetLogo].mod) ) != 0 )
1254        {
1255          logit("e", "ReadConfig: watchForAlarm: invalid module id `MOD_WILDCARD'\n");
1256          return( -1 );
1257        }
1258        if ( GetType( "TYPE_ACTIVATE_MODULE", &(pEW->GetLogo[pEW->nGetLogo].type) ) != 0 )
1259        {
1260          logit("e", "ReadConfig: watchForAlarm: invalid msgtype `TYPE_ACTIVATE_MODULE'\n");
1261          return( -1 );
1262        }
1263        pEW->amLogo.type = pEW->GetLogo[pEW->nGetLogo].type;
1264        str = k_str();
1265        if ( str ) {
1266                pgmParams->alarmDuration = atoi( str );
1267                if ( pgmParams->alarmDuration <= 0 ) {
1268                        logit("e", "ReadConfig: watchForAlarm: invalid duration '%s'; ignoring\n",
1269                                str );
1270                        pgmParams->alarmDuration = 0;
1271                }
1272        } else
1273                pgmParams->alarmDuration = 60;
1274        pEW->nGetLogo++;
1275      }
1276     
1277      /* Optional: additional spectral response frequency */
1278      else if (k_its( "AddSpectraResponseAt") )
1279      {
1280        addSR2list( k_val() );
1281          }
1282
1283      /* Optional: additional spectral response frequency */
1284      else if (k_its( "PreTriggerSeconds") )
1285      {
1286        pgmParams->preTriggerSeconds = k_int();
1287          }
1288
1289      else if( t_com()      ) processor = "t_com";
1290
1291      /* Unknown command */ 
1292      else 
1293      {
1294        fprintf(stderr, "ReadConfig: <%s> Unknown command in <%s>.\n", 
1295                com, configfile);
1296        continue;
1297      }
1298
1299      /* See if there were any errors processing the command */
1300      if (k_err ()) 
1301      {
1302        fprintf(stderr, 
1303                "gma: Bad <%s> command in <%s>\n\t%s\n",
1304                processor, configfile, k_com());
1305        return -1;
1306      }
1307
1308    } /** while k_rd() **/
1309
1310    nfiles = k_close ();
1311
1312  } /** while nfiles **/
1313
1314 
1315  if ( pgmParams->alarmDuration ) {
1316        /* WatchForAlarm present, so might not need to handle HYP2000ARC messages */
1317        if ( !init[0] || !init[2] ) {
1318                fprintf( stderr, "Warning: program cannot respond to HYP2000ARC messages:\n" );
1319                if ( !init[0] )
1320                        fprintf( stderr, "\tmissing <staLoc> command\n");
1321                if ( !init[0] )
1322                        fprintf( stderr, "\tmissing <maxDist> command\n");
1323                /* Make it look like these have been supplied */
1324                init[0] = init[2] = 1;
1325        }
1326  }
1327 
1328  /* After all files are closed, check init flags for missed commands */
1329  nmiss = 0;
1330  for (i = 0; i < NUMREQ; i++) 
1331    if (!init[i]) 
1332      nmiss++;
1333
1334  if (nmiss) 
1335  {
1336    fprintf(stderr, "gma: ERROR, no ");
1337    if (!init[0])  fprintf(stderr, "<staLoc> ");
1338    if (!init[1])  fprintf(stderr, "<maxSta> ");
1339    if (!init[2])  fprintf(stderr, "<maxDist> ");
1340    if (!init[3])  fprintf(stderr, "<maxTrace> ");
1341    if (!init[4])  fprintf(stderr, "<HeartBeatInterval> ");
1342    if (!init[5])  fprintf(stderr, "<RingInName> ");
1343    if (!init[6])  fprintf(stderr, "<RingOutName> ");
1344    if (!init[7])  fprintf(stderr, "<MyModId> ");
1345    if (!init[8])  fprintf(stderr, "<getEventsFrom> ");
1346   
1347    fprintf(stderr, "command(s) in <%s>; exitting!\n", configfile);
1348    return -1;
1349  }
1350
1351  /* Sort the SCNLPAR array to make searching more efficient */
1352  if (pgmParams->numSCNLPar > 0)
1353    qsort(pgmParams->pSCNLPar, pgmParams->numSCNLPar, sizeof(SCNLPAR), 
1354          CompareSCNLPARs);
1355
1356  /* If no spectra periods defined, use the old hard-coded ones */
1357  checkSRlist();
1358 
1359  return err;
1360}
1361
1362static void initGM(GMPARAMS *pgmParams)
1363{
1364  pgmParams->peakSearchStart = 0.0;
1365  pgmParams->peakSearchStartMin = 2.0;
1366  pgmParams->peakSearchEnd = 0.0;
1367  pgmParams->peakSearchEndMin = 30.0;
1368  pgmParams->traceStart = 5.0;
1369  pgmParams->traceEnd = 60.0; 
1370  pgmParams->pAdd = NULL;
1371  pgmParams->pDel = NULL;
1372  pgmParams->pSCNLPar = NULL;
1373  pgmParams->pWSV = NULL;      /* assign default "servers" file later */
1374  pgmParams->HeartBeatInterval = 0;
1375  pgmParams->debug = 0;
1376  pgmParams->maxSCNLPar = 0;
1377  pgmParams->maxSta = 0;
1378  pgmParams->numSCNLPar = 0;
1379  pgmParams->snrThresh = 3.0;
1380  pgmParams->respSource = GM_UNDEF;
1381  pgmParams->saveTrace = GM_UNDEF;
1382  pgmParams->staLoc = GM_UNDEF;
1383  pgmParams->traceSource = GM_UNDEF;
1384  pgmParams->wsTimeout = 5000; 
1385  pgmParams->eventID = NULL;
1386  pgmParams->respDir = NULL;
1387  pgmParams->respNameFormat = NULL;
1388  pgmParams->saveNameFormat = NULL;
1389  pgmParams->staLocFile = NULL;
1390  pgmParams->TempDir = NULL;
1391  pgmParams->XMLDir = NULL;
1392  pgmParams->MappingFile = NULL;
1393  pgmParams->pEW->nGetLogo = 0;
1394  pgmParams->pEW->GetLogo = (MSG_LOGO *)NULL;
1395  pgmParams->pEW->RingInKey = 0l;
1396  pgmParams->pEW->RingOutKey = 0l;
1397  pgmParams->pEW->ha2kLogo.type = 0;
1398  pgmParams->pEW->amLogo.type = 0;
1399  pgmParams->pEW->threshLogo.type = 0;
1400  pgmParams->preTriggerSeconds = 10;
1401  pgmParams->ChannelNumberMap[0]=0; /* map 1 2 3 channel cars to N E and Z respecitvely */
1402  return;
1403}
Note: See TracBrowser for help on using the repository browser.