Main Page Class Hierarchy Compound List File List Compound Members File Members

# sacputaway.c

Go to the documentation of this file.

    00001
    00002 /*
    00003  *   THIS FILE IS UNDER RCS - DO NOT MODIFY UNLESS YOU HAVE
    00004  *   CHECKED IT OUT USING THE COMMAND CHECKOUT.
    00005  *
    00006  *    $Id: sacputaway_8c-source.html 2161 2006-05-19 16:55:03Z paulf $
    00007  *
    00008  *    Revision history:
    00009  *     $Log$
    00009  *     Revision 1.1  2006/05/19 16:55:02  paulf
    00009  *     first inclusion
    00009  *
    00010  *     Revision 1.24  2002/03/22 18:38:13  lucky
    00011  *     Fixed SACPABase_init prototype
    00012  *
    00013  *     Revision 1.23  2002/03/22 18:25:24  lucky
    00014  *     Changed SACPABase_init to only create a new directory if told to do so. This way, files
    00015  *     can be added to a directory.
    00016  *
    00017  *     Revision 1.22  2001/08/02 22:48:50  davidk
    00018  *     Added explicit float casts to 4 statements to get rid of
    00019  *     compiler warnings on NT.
    00020  *
    00021  *     Revision 1.21  2001/08/02 22:42:01  lucky
    00022  *     *** empty log message ***
    00023  *
    00024  *     Revision 1.20  2001/06/06 20:56:43  lucky
    00025  *     Fixing support for many mag types and amplitude picks
    00026  *
    00027  *     Revision 1.19  2001/05/31 17:08:54  lucky
    00028  *     Added evdp for event depth - used to only write to evel.
    00029  *
    00030  *     Revision 1.18  2001/04/12 03:47:36  lombard
    00031  *     Major reorganization of SACPABase_write_trace to improve efficiency
    00032  *     Reformatted code; cleaned up lots of comments and logit calls
    00033  *     Removed mapping of NC component codes (only needed at UW)
    00034  *
    00035  *     Revision 1.17  2000/12/06 17:50:07  lucky
    00036  *     Added cOnset -- we keep track of the pick's onset in the fourth
    00037  *     character of the phase label (ka, or kt0)
    00038  *
    00039  *     Revision 1.16  2000/11/15 17:03:27  lucky
    00040  *     Added SACPABase_next_ev_review which sets SacDir variable. (needed this
    00041  *     to write PZ files correctly). As a result, we no longer need end_ev_review,
    00042  *     so I removed it.
    00043  *
    00044  *     Revision 1.15  2000/09/07 21:17:45  lucky
    00045  *     Final version after the Review pages have been demonstrated.
    00046  *
    00047  *     Revision 1.14  2000/08/25 18:20:41  lucky
    00048  *     Fixed to work with multiple arrival types (S and P)
    00049  *
    00050  *     Revision 1.13  2000/08/17 18:36:51  lucky
    00051  *     Fixed major potential bugs: Increased size of sacfile to 2*MAXTXT;
    00052  *     also, we now make sure that the target string is big enough for th
    00053  *     source and also the termination character.
    00054  *
    00055  *     Revision 1.12  2000/07/27 15:55:59  lucky
    00056  *     Changed MAX_PHS_PER_EQ to DB_MAX_PHS_PER_EQ
    00057  *
    00058  *     Revision 1.11  2000/07/03 18:26:24  lucky
    00059  *     Added SACPABase_end_scn_review for sac writing from inside the
    00060  *     review pages. This is necessary for the review applet to run.
    00061  *
    00062  *     Revision 1.10  2000/05/24 15:58:31  lucky
    00063  *     Changed calls to creat/write to fopen/fwrite. The old way would not write
    00064  *     correct SAC files under NT.
    00065  *
    00066  *     Revision 1.9  2000/04/13 17:12:58  lucky
    00067  *     Fixed several logit lines to only log to file.
    00068  *
    00069  *     Revision 1.8  2000/04/13 17:06:01  lucky
    00070  *     In CreateSACSupportFiles: took out the chdir call to SacDir. Instead, the support
    00071  *     files are opened from the current directory by appending SacDir to the name of the
    00072  *     file. This was necessary in order to allow for multiple events to be processed by
    00073  *     the archiver. Before, we would never chdir back to the top level directory, causing
    00074  *     all subsequent calls to the Sac putaway routines to bomb.
    00075  *
    00076  *     Also, fixed zCurEventIDACPABase_next_ev so that if dEventStartTime is 0 for some reason,
    00077  *     the directory created will have the current time. Before it would always create
    00078  *     a directory with 1970 date (i.e. time_t of 0).
    00079  *
    00080  *     Revision 1.7  2000/03/31 18:26:47  davidk
    00081  *     *** empty log message ***
    00082  *
    00083  *     Revision 1.6  2000/03/24 07:36:40  davidk
    00084  *     added code to pad the pick label field with blanks, instead of the default (-12345)
    00085  *
    00086  *     Revision 1.5  2000/03/14 18:34:41  lucky
    00087  *     Fixed a bug with creation of SAC directories: they were being created
    00088  *     as yyyymmmm, instead of yyyymm.
    00089  *
    00090  *     Revision 1.4  2000/03/13 21:36:05  lucky
    00091  *     Fixed error in SACPA_next_ev where pOrigin was used when it was
    00092  *     still set to NULL.
    00093  *
    00094  *     Revision 1.3  2000/03/10 23:27:33  davidk
    00095  *     Redesigned the sacputaway routines so that they could also be
    00096  *     used to write parametric event and station data in addition to
    00097  *     being used for trace disposal.  Moved most of the old functionality
    00098  *     into a SACPABase_XXX layer.  Now the SACPA_XXX routines serve as
    00099  *     wrappers for the SACPABase_XXX routines, which do the actual SAC
    00100  *     header filling and file writing.  Added code adapted from ora2sac
    00101  *     to write Origin and arrival data.  Added code to write Poles and Zeroes
    00102  *     station signal response data.  Changed the SACPA_XXX routines to
    00103  *     matche the new putaway interface in putaway.c
    00104  *
    00105  *     Revision 1.1  2000/02/14 18:51:48  lucky
    00106  *     Initial revision
    00107  *
    00108  *
    00109  */
    00110
    00111 /* sacputaway.c
    00112
    00113   Wed Feb 23 XX:XX:XX PST 2000 David Kragness
    00114     Modified the sacputaway routines to use an additional layer.
    00115         It was desired that the same core code be used to do all
    00116         data disposal into SAC, and some programs needed/wanted to
    00117         write parametric data as well as trace data.  In the putaway
    00118         interface, there is only room for trace data.  So the SACPA_XXX
    00119         routines have been modified so that the guts of the original
    00120         routines have gone into a layer of functions called
    00121         SACPABase_XXX, and the original SACPA_XXX routines have
    00122         become wrappers for those routines using the XXX_tracesave
    00123         "putaway" interface.  Additional functionality has been added
    00124         to the SACPABase_XXX routines for writing parametric data to
    00125         SAC in addition to the waveform data that was written by the
    00126         original SACPA_XXX routines.
    00127
    00128
    00129   Thu Dec 30 00:01:12 GMT 1999 Lucky Vidmar
    00130     Made the fixes necessary to produce SAC files on NT which
    00131     are readable on Solaris. For this, we needed to do some magic
    00132     with the SAC header, so that it can be byte-swapped correctly.
    00133     Namely, we now have two SAC headers floating around: one is
    00134     in the local machine format, and its values are copied to the
    00135     temporary header so that it can be swapped (the "problem" being
    00136     that byte-swapping is done in-place). Then, once we get back
    00137     a byte-swapped header, we memcpy it back to the memory that is
    00138     written out along with the previously byte-swapped data.
    00139
    00140   Thu Jul 22 14:56:37 MDT 1999 Lucky Vidmar
    00141     Major structural changes to accomodate making all putaway routines
    00142     into library calls so that they can be shared between trig2disk
    00143     and wave2disk. Eliminated global variables set and allocated outside
    00144     of this file. We should only have static globals from now on, with
    00145     everything else being passed in via the putaway.c calls.
    00146
    00147
    00148   Tue Apr 13 13:01:23 MDT 1999 Lucky Vidmar
    00149     Changed target directory names to reflect ora2sac. Also, we now
    00150     create a bunch of support files (sac macros) in the target directory,
    00151     much like ora2sac. As a matter of fact, most of the code which
    00152     creates sac macros was modelled after ora2sac code.
    00153
    00154
    00155  These are the routines which plug into routines in putaway.c, and cause
    00156  the trace data snippets to be put away into a SAC format trace files.
    00157
    00158    Written by: Pete Lombard, March 1998
    00159
    00160  Modified by withers to work with trig2disk Sep, 1998
    00161  Ported to NT withers Oct 1998
    00162
    00163    */
    00164
    00165 /************************************/
    00167 /************************************/
    00168 #include <stdio.h>
    00169 #include <stdlib.h>
    00170 #include <string.h>
    00171 #include <errno.h>
    00172 #include <earthworm.h>
    00173 #include <time.h>
    00174 #include <trace_buf.h>
    00175 #include <swap.h>
    00176 #include <ws_clientII.h>
    00177 #include <chron3.h>
    00178 #include <sacputaway.h>
    00179 #include <pa_subs.h>
    00180 #include <time_ew.h>
    00181
    00182
    00183 /*********************************************/
    00185 /*********************************************/
    00186 static SACFileListStruct   FileList[DB_MAX_PHS_PER_EQ];
    00187 static int                 FileIndex;
    00188 static char                szCurEventID[EVENTID_SIZE+1];
    00189 static int                 SACPAB_Debug=0;
    00190 static char                SAC_szOutDir[MAXTXT];
    00191 static char                SAC_szOutputFormat[20];
    00192 static double              SAC_starttime;
    00193 static SAC_OriginStruct    SAC_Origin;
    00194
    00195
    00196 /* use statically allocated SAC headers.  It's safer and faster
    00197    than dynamically mallocing them and it's not
    00198    that much space (6XX bytes each)
    00199 ****************************************************************/
    00200 static char default_sachead[SACHEADERSIZE];
    00201 static char sachead[SACHEADERSIZE];
    00202
    00203 /* sacheadp is where the "real" representation of the header is, i.e
    00204    the one that is valid on the architecture that executes the code
    00205 ****************************************************************/
    00206 static struct   SAChead *sacheadp=(struct SAChead *) sachead;
    00207
    00208 /* default_sacheadp is the default sac header image.  This way we don't
    00209    have to go through painful initialization each time, we just slam
    00210    the default into our target header.
    00211 ****************************************************************/
    00212 static struct   SAChead *default_sacheadp=(struct SAChead *) default_sachead;
    00213
    00214 static char  SacDir[2*MAXTXT + 4];
    00215 static char *SacBuffer;   /* buffer for storing output before writing */
    00216 static char  SAC_szSta[10], SAC_szChan[10], SAC_szNet[10];
    00217 static int   BufferLen;
    00218 static int   bSACPABase_init=FALSE;
    00219 static int   bSACPABase_scn_open=FALSE;
    00220
    00221
    00222 /************************************/
    00224 /************************************/
    00225
    00226 /* supporting routines
    00227 *************************************/
    00228 void sacinit (struct SAChead *);
    00229 void swapsac (struct SAChead *);
    00230 int SAC_Compare (const void *, const void *);
    00231 int CreateSACSupportFiles (char *, SACFileListStruct *, int);
    00232 int SACmac_init (void);
    00233 int SACmac_quicklook (SACFileListStruct *, int);
    00234 int SACmac_repick (SACFileListStruct *, int);
    00235 int SAC_filelist (SACFileListStruct *, int, char *);
    00236 int SAC_SwapDouble(double * pValue, char cDataType);
    00237 int SAC_SwapLong(long * pValue, char cDataType);
    00238 int SAC_SwapShort(short * pValue, char cDataType);
    00239
    00240
    00241 /********************************************************************
    00242 *********************************************************************
    00243 ###################### SAC PUTAWAY ROUTINES #########################
    00244 *********************************************************************
    00245 ********************************************************************/
    00246
    00247 /* Initialization function,
    00248 *       This is the Put Away startup intializer. This is called when    *
    00249 *       the system first comes up. Here is a chance to look around      *
    00250 *       and see if it's possible to do business, and to complain        *
    00251 *       if not ,BEFORE an event has to be processed.                    *
    00252 */
    00253 int SACPA_init(long OutBufferLen, char *OutDir, char * OutputFormat, int debug)
    00254 {
    00255   int rc;
    00256
    00257   rc=SACPABase_Debug(debug);
    00258   if(rc!=EW_SUCCESS)
    00259   {
    00260     logit("","%s(): %s() failed returning %d.\n",
    00261           "SACPA_init","SACPABase_Debug",rc);
    00262     return(EW_FAILURE);
    00263   }
    00264
    00265   rc=SACPABase_init(OutBufferLen,OutDir,TRUE,OutputFormat);
    00266   if(rc!=EW_SUCCESS)
    00267   {
    00268     logit("","%s(): %s() failed returning %d.\n",
    00269           "SACPA_init","SACPABase_init",rc);
    00270     return(EW_FAILURE);
    00271   }
    00272   return(EW_SUCCESS);
    00273 }
    00274
    00275 /****************************************************************************
    00276 *       This is the Put Away event initializer. It's called when a snippet  *
    00277 *       has been received, and is about to be processed.                    *
    00278 *       It gets to see the pointer to the TraceRequest array,               *
    00279 *       and the number of loaded trace structures.                          *
    00280 *****************************************************************************/
    00281 int SACPA_next_ev(char *EventID, TRACE_REQ *ptrReq, int nReq,
    00282                   char *OutDir, char *EventDate, char *EventTime, int debug)
    00283 {
    00284
    00285   int rc;
    00286   char szTime[40];
    00287   double dTime;
    00288
    00289   rc=SACPABase_Debug(debug);
    00290   if(rc!=EW_SUCCESS)
    00291   {
    00292     logit("","%s(): %s() failed returning %d.\n",
    00293           "SACPA_next_ev","SACPABase_Debug",rc);
    00294     return(EW_FAILURE);
    00295   }
    00296
    00297   sprintf(szTime,"%s%s",EventDate,EventTime);
    00298   if(epochsec17(&dTime,szTime))
    00299   {
    00300     logit("","SACPA_next_ev(): Error in epochsec17() parsing time:(%s)\n",
    00301           szTime);
    00302     return(EW_FAILURE);
    00303   }
    00304
    00305   rc=SACPABase_next_ev(EventID,dTime,NULL);
    00306   if(rc!=EW_SUCCESS)
    00307   {
    00308     logit("","%s(): %s() failed returning %d.\n",
    00309           "SACPA_next_ev","SACPABase_next_ev",rc);
    00310     return(EW_FAILURE);
    00311   }
    00312
    00313   return(EW_SUCCESS);
    00314 }
    00315
    00316
    00317 /*****************************************************************************
    00318  *   This is the working entry point into the disposal system. This routine  *
    00319  *   gets called for each trace snippet which has been recovered. It gets    *
    00320  *   to see the corresponding SNIPPET structure, and the event id            *
    00321  *****************************************************************************/
    00322 /* Process one channel of data */
    00323 int SACPA_next(TRACE_REQ *getThis, double GapThresh,
    00324                long OutBufferLen, int debug)
    00325      /*
    00326  * input:  getThis   pointer to buffer for the trace data request
    00327  *         eventId   not used here
    00328  */
    00329
    00330 {
    00331   int rc;
    00332
    00333   rc=SACPABase_Debug(debug);
    00334   if(rc!=EW_SUCCESS)
    00335   {
    00336     logit("","%s(): %s() failed returning %d.\n",
    00337           "SACPA_next","SACPABase_Debug",rc);
    00338     return(EW_FAILURE);
    00339   }
    00340
    00341   rc=SACPABase_next_scn(getThis->sta,getThis->chan,getThis->net);
    00342   if(rc!=EW_SUCCESS)
    00343   {
    00344     logit("","%s(): %s() failed returning %d.\n",
    00345           "SACPA_next","SACPABase_next_scn",rc);
    00346     return(EW_FAILURE);
    00347   }
    00348
    00349   rc=SACPABase_write_trace(getThis,GapThresh);
    00350   if(rc!=EW_SUCCESS)
    00351   {
    00352     logit("","%s(): %s() failed returning %d.\n",
    00353           "SACPA_next","SACPABase_write_trace",rc);
    00354     return(EW_FAILURE);
    00355   }
    00356
    00357   rc=SACPABase_end_scn();
    00358   if(rc!=EW_SUCCESS)
    00359   {
    00360     logit("","%s(): %s() failed returning %d.\n",
    00361           "SACPA_next","SACPABase_end_scn()",rc);
    00362     return(EW_FAILURE);
    00363   }
    00364
    00365   return(EW_SUCCESS);
    00366 }
    00367
    00368
    00369
    00370 /************************************************************************
    00371 *       This is the Put Away end event routine. It's called after we've     *
    00372 *       finished processing one event.                                  *
    00373 *************************************************************************/
    00374 int SACPA_end_ev (int debug)
    00375 {
    00376   int rc;
    00377
    00378   rc=SACPABase_Debug(debug);
    00379   if(rc!=EW_SUCCESS)
    00380   {
    00381     logit("","%s(): %s() failed returning %d.\n",
    00382           "SACPA_end_ev","SACPABase_Debug",rc);
    00383     return(EW_FAILURE);
    00384   }
    00385
    00386   rc=SACPABase_end_ev();
    00387   if(rc!=EW_SUCCESS)
    00388   {
    00389     logit("","%s(): %s() failed returning %d.\n",
    00390           "SACPA_end_ev","SACPABase_end_ev",rc);
    00391     return(EW_FAILURE);
    00392   }
    00393
    00394   return(EW_SUCCESS);
    00395 }
    00396
    00397
    00398 /************************************************************************
    00399 *       This is the Put Away close routine. It's called after when      *
    00400 *       we're being shut down.                                          *
    00401 *************************************************************************/
    00402 int SACPA_close (int debug)
    00403 {
    00404   int rc;
    00405
    00406   rc=SACPABase_Debug(debug);
    00407   if(rc!=EW_SUCCESS)
    00408   {
    00409     logit("","%s(): %s() failed returning %d.\n",
    00410           "SACPA_close","SACPABase_Debug",rc);
    00411     return(EW_FAILURE);
    00412   }
    00413
    00414   rc=SACPABase_close();
    00415   if(rc!=EW_SUCCESS)
    00416   {
    00417     logit("","%s(): %s() failed returning %d.\n",
    00418           "SACPA_close","SACPABase_close",rc);
    00419     return(EW_FAILURE);
    00420   }
    00421
    00422   return(EW_SUCCESS);
    00423 }
    00424
    00425
    00426
    00427 /********************************************************************
    00428 *********************************************************************
    00429 #################### SAC PUTAWAY BASE ROUTINES ######################
    00430 *********************************************************************
    00431 ********************************************************************/
    00432
    00433
    00434
    00435
    00436 /********************************************************************
    00437 *********************************************************************
    00438     Function:      SACPABase_Debug
    00439
    00440     Description:   Turns debugging on/off for SACPABase
    00441                    functions
    00442
    00443     Return Value:  success: EW_SUCCESS
    00444                    failure: EW_FAILURE
    00445                    others:  Undefined
    00446
    00447     Comments:
    00448 *********************************************************************
    00449 ********************************************************************/
    00450 int SACPABase_Debug(int bDebug)
    00451 {
    00452   SACPAB_Debug=bDebug;
    00453   return(EW_SUCCESS);
    00454 }
    00455
    00456 /********************************************************************
    00457 *********************************************************************
    00458     Function:      SACPABase_SetOutputFormat
    00459
    00460     Description:   Sets the output format for the SACPABase functions.
    00461                     ("intel" or "sparc")
    00462
    00463     Return Value:  success: EW_SUCCESS
    00464                    failure: EW_FAILURE
    00465                             SACPAB_OUTPUT_FORMAT_TOO_LONG
    00466                    others:  Undefined
    00467
    00468     Comments:
    00469 *********************************************************************
    00470 ********************************************************************/
    00471 int SACPABase_SetOutputFormat(char * szOutputFormat)
    00472 {
    00473   if(strlen(szOutputFormat) > sizeof(SAC_szOutputFormat))
    00474   {
    00475     logit("","SACPABase_SetOutputFormat():Error: %s output format is too long!\n",
    00476           szOutputFormat);
    00477     return(SACPAB_OUTPUT_FORMAT_TOO_LONG);
    00478   }
    00479   strcpy(SAC_szOutputFormat,szOutputFormat);
    00480   return(EW_SUCCESS);
    00481 }
    00482
    00483 /********************************************************************
    00484 *********************************************************************
    00485     Function:      SACPABase_init
    00486
    00487     Description:   SAC Putaway Base initializer.
    00488
    00489     Return Value:  success: EW_SUCCESS
    00490                    failure: EW_FAILURE (unknown error)
    00491                             SACPAB_ALREADY_INIT (SACPABase is already
    00492                              initialized.  Please call SACPABase_close()
    00493                              before calling SACPABase_init() again.
    00494
    00495                    others:  Undefined
    00496
    00497     Comments:      This should be called when the system first comes
    00498                    up.  It gives SACPABase  a chance to look around
    00499                    and see if it's possible to do business, and to
    00500                    complain if not ,BEFORE an event has to be
    00501                    processed.
    00502 *********************************************************************
    00503 ********************************************************************/
    00504 int SACPABase_init(int OutBufferLen, char *szOutDir, int CreateNewDir, char * szOutputFormat)
    00505 {
    00506   if (bSACPABase_init)
    00507   {
    00508     logit("","SACPABase_init() called multiple times.\n");
    00509     return(SACPAB_ALREADY_INIT);
    00510   }
    00511
    00512   if(!(szOutDir && szOutputFormat))
    00513   {
    00514     logit("","SACPABase_init():  Error: Null pointers passed.\n");
    00515     return(SACPAB_NULL_POINTERS);
    00516   }
    00517
    00518   if(OutBufferLen > MIN_OUTBUFFER_LEN)
    00519     BufferLen=OutBufferLen;
    00520   else
    00521     BufferLen=MIN_OUTBUFFER_LEN;
    00522
    00523   /* Allocate SacBuffer */
    00524   if ((SacBuffer = (char *) malloc (BufferLen * sizeof (char))) == NULL)
    00525   {
    00526     logit ("e", "SACPABase_init: couldn't malloc SacBuffer(%d)\n", BufferLen);
    00527     return EW_FAILURE;
    00528   }
    00529
    00530   /* set init flag here to minimize memory leaks. */
    00531   bSACPABase_init=TRUE;
    00532
    00533   if(strlen(szOutDir) > (sizeof(SAC_szOutDir) + 1))
    00534   {
    00535     logit("e","SACPABase_init():Error: %s directory name is too long!\n",
    00536           szOutDir);
    00537     return(SACPAB_DIRECTORY_TOO_LONG);
    00538   }
    00539   strcpy(SAC_szOutDir,szOutDir);
    00540
    00541   /* Make sure that the top level output directory exists */
    00542
    00543   if (CreateNewDir == TRUE)
    00544   {
    00545     if (CreateDir (SAC_szOutDir) != EW_SUCCESS)
    00546     {
    00547       logit ("e", "SACPABase_init: Call to CreateDir(%s) failed\n",SAC_szOutDir);
    00548       return EW_FAILURE;
    00549     }
    00550   }
    00551
    00552   if(strlen(szOutputFormat) > sizeof(SAC_szOutputFormat))
    00553   {
    00554     logit("e","SACPABase_init():Error: %s output format is too long!\n",
    00555           szOutputFormat);
    00556     return(SACPAB_OUTPUT_FORMAT_TOO_LONG);
    00557   }
    00558   strcpy(SAC_szOutputFormat,szOutputFormat);
    00559
    00560   /* Initialize all header values to SAC defaults */
    00561   sacinit(default_sacheadp);
    00562
    00563   /* the following sac header vars must be set, but not neccessarily
    00564      here:  npts,b,e,iftype,leven,delta
    00565   ******************************************************************/
    00566   /* Set some header values that will never change */
    00567   default_sacheadp->idep  = SAC_IUNKN;      /* unknown independent data type */
    00568   default_sacheadp->iztype = SAC_IBEGINTIME; /* Reference time is Begin time */
    00569   default_sacheadp->iftype = SAC_ITIME;    /* File type is time series */
    00570   default_sacheadp->leven  = 1;            /* evenly spaced data */
    00571   default_sacheadp->b      = 0; /* beginning time relative to reference time */
    00572   strncpy(default_sacheadp->ko, "origin ", K_LEN);
    00573
    00574   /* Initialize CurEventID */
    00575   strcpy(szCurEventID,"-1");
    00576
    00577   return(EW_SUCCESS);
    00578 }
    00579
    00580
    00581 /****************************************************************************
    00582 *       This is the Put Away event initializer. It's called when a snippet  *
    00583 *       has been received, and is about to be processed.                    *
    00584 *       It gets to see the pointer to the TraceRequest array,               *
    00585 *       and the number of loaded trace structures.                          *
    00586 *****************************************************************************/
    00587 int SACPABase_next_ev(char * szEventID, double dEventStartTime,
    00588                       SAC_OriginStruct * pOrigin)
    00589 {
    00590
    00591   char     tmpname[256];
    00592   char     tmp1[256];
    00593   time_t tTemp=(int)dEventStartTime;
    00594   struct tm tmTemp;
    00595
    00596
    00597   if (dEventStartTime == 0.0)
    00598     tTemp = time (NULL);
    00599
    00600   gmtime_ew(&tTemp,&tmTemp);
    00601
    00602   strncpy(szCurEventID,szEventID,EVENTID_SIZE);
    00603   szCurEventID[EVENTID_SIZE]=0;
    00604
    00605   /* Sac files will be written into the directory structure
    00606    * borrowed from ora2sac:
    00607    *   SacDir = OutDir/yyyymm/yyyymmdd_hhmmss-iiii/
    00608    *
    00609    *  If SacDir does not exist, it will be created
    00610    */
    00611
    00612   /* tmpname = OutDir/yyyymm */
    00613   sprintf (tmpname, "%s/%04d%02d", SAC_szOutDir,
    00614            tmTemp.tm_year+1900, tmTemp.tm_mon+1);
    00615
    00616   if (CreateDir (tmpname) != EW_SUCCESS)
    00617   {
    00618     logit ("e", "SACPA_init: Call to CreateDir failed\n");
    00619     return EW_FAILURE;
    00620   }
    00621
    00622   /* build the event directory name */
    00623   sprintf (tmp1, "%04d%02d%02d_%02d%02d%02d_%s",
    00624            tmTemp.tm_year+1900, tmTemp.tm_mon+1, tmTemp.tm_mday,
    00625            tmTemp.tm_hour, tmTemp.tm_min, tmTemp.tm_sec,
    00626            szCurEventID
    00627            );
    00628
    00629   sprintf (SacDir, "%s/%s", tmpname, tmp1);
    00630
    00631   if (CreateDir (SacDir) != EW_SUCCESS)
    00632   {
    00633     logit ("e", "SACPABase_next_ev: Call to CreateDir(%s)failed\n",
    00634            SacDir);
    00635     return EW_FAILURE;
    00636   }
    00637
    00638   /* reset file index to 0 (for support files) */
    00639   FileIndex = 0;
    00640
    00641   if(pOrigin)
    00642   {
    00643     memcpy(&SAC_Origin,pOrigin,sizeof(SAC_OriginStruct));
    00644     default_sacheadp->evla=(float)(pOrigin->dLat);
    00645     default_sacheadp->evlo=(float)(pOrigin->dLon);
    00646     default_sacheadp->evel=(float)(pOrigin->dElev);
    00647     default_sacheadp->evdp=(float)(pOrigin->dElev);
    00648   }
    00649   else
    00650   {
    00651     SAC_Origin.tOrigin=dEventStartTime;
    00652   }
    00653
    00654   return(EW_SUCCESS);
    00655 }
    00656
    00657 /****************************************************************************
    00658 *       This is the Put Away event initializer for the review system.       *
    00659 *       It doesn't do much except for setting the SacDir variable           *
    00660 *       which gets used a lot in the Sac putaway routines                   *
    00661 *****************************************************************************/
    00662 int SACPABase_next_ev_review (char *EventDir, int EventID, SAC_OriginStruct *pSacOrigin)
    00663 {
    00664
    00665         char    evtid[256];
    00666
    00667         if ((EventDir == NULL) || (pSacOrigin == NULL))
    00668         {
    00669                 logit ("", "Invalid arguments passed in.\n");
    00670                 return EW_FAILURE;
    00671         }
    00672
    00673         /* Set SacDir */
    00674         strcpy (SacDir, EventDir);
    00675
    00676         /* Set szCurEventID */
    00677         sprintf (evtid, "%d", EventID);
    00678         strncpy (szCurEventID, evtid, EVENTID_SIZE);
    00679         szCurEventID[EVENTID_SIZE] = 0;
    00680
    00681
    00682         /* Set event parameters */
    00683     memcpy (&SAC_Origin, pSacOrigin, sizeof(SAC_OriginStruct));
    00684     default_sacheadp->evla = (float)(pSacOrigin->dLat);
    00685     default_sacheadp->evlo = (float)(pSacOrigin->dLon);
    00686     default_sacheadp->evel = (float)(pSacOrigin->dElev);
    00687     default_sacheadp->evdp = (float)(pSacOrigin->dElev);
    00688
    00689         return EW_SUCCESS;
    00690
    00691 }
    00692
    00693
    00694 /*****************************************************************************
    00695  *   This is the working entry point into the disposal system. This routine  *
    00696  *   gets called for each trace snippet which has been recovered. It gets    *
    00697  *   to see the corresponding SNIPPET structure, and the event id            *
    00698  *****************************************************************************/
    00699 /* Process one channel of data */
    00700 int SACPABase_next_scn(char *szSta, char * szChan, char * szNet)
    00701 {
    00702   int i;
    00703
    00704   if(bSACPABase_scn_open)
    00705   {
    00706     logit("","SACPABase_next_scn(): ERROR! SCN record is already open,\n"
    00707           "please call SACPABase_scn_end() to close the existing record,\n"
    00708           "before calling SACPABase_next_scn() again.\n");
    00709     return(SACPAB_SCN_ALREADY_OPEN);
    00710   }
    00711
    00712   /* slam the default header into our working one. */
    00713   memcpy(sacheadp,default_sacheadp,SACHEADERSIZE);
    00714
    00715   /* Save the SCN for use by other SAC_PA routines */
    00716   strncpy(SAC_szSta,szSta,sizeof(SAC_szSta));
    00717   SAC_szSta[sizeof(SAC_szSta)-1]=0;
    00718   strncpy(SAC_szChan,szChan,sizeof(SAC_szChan));
    00719   SAC_szSta[sizeof(SAC_szChan)-1]=0;
    00720   strncpy(SAC_szNet,szNet,sizeof(SAC_szSta));
    00721   SAC_szSta[sizeof(SAC_szNet)-1]=0;
    00722
    00723   /* Copy the SCN into the header and blank bad the trailing chars */
    00724   strcpy(sacheadp->kstnm, SAC_szSta);   /* station name */
    00725   for (i = strlen(SAC_szSta); i < K_LEN; ++i)
    00726     sacheadp->kstnm[i] = ' ';
    00727
    00728   strcpy(sacheadp->kcmpnm, SAC_szChan);
    00729   for (i = strlen(SAC_szChan); i < K_LEN; ++i)
    00730     sacheadp->kcmpnm[i] = ' ';
    00731
    00732   strcpy(sacheadp->knetwk, SAC_szNet);
    00733   for (i = strlen(SAC_szNet); i < K_LEN; ++i)
    00734     sacheadp->knetwk[i] = ' ';
    00735
    00736   /* orientation of seismometer -
    00737      determine the orientation based on the third character
    00738      of the component name */
    00739   switch ((int) SAC_szChan[2])
    00740   {
    00741     /* vertical component */
    00742   case 'Z' :
    00743   case 'z' :
    00744     sacheadp->cmpaz = 0;
    00745     sacheadp->cmpinc = 0;
    00746     break;
    00747     /* north-south component */
    00748   case 'N' :
    00749   case 'n' :
    00750     sacheadp->cmpaz = 0;
    00751     sacheadp->cmpinc = 90;
    00752     break;
    00753     /* east-west component */
    00754   case 'E' :
    00755   case 'e' :
    00756     sacheadp->cmpaz = 90;
    00757     sacheadp->cmpinc = 90;
    00758     break;
    00759     /* anything else */
    00760   default :
    00761     sacheadp->cmpaz = SACUNDEF;
    00762     sacheadp->cmpinc = SACUNDEF;
    00763     break;
    00764   } /* switch */
    00765
    00766   /* so far we have the default header, plus SCN information */
    00767   /* no time or trace info */
    00768   bSACPABase_scn_open=TRUE;
    00769
    00770   return(EW_SUCCESS);
    00771 }
    00772
    00773
    00774 /*
    00775  * SACPABase_write_trace: transfer trace data from TRACE_REQ buffer into
    00776  *          SAC data section; fill in some header info.
    00777  *          The actual writing of the file happens in SACPABase_end_scn.
    00778  */
    00779 int SACPABase_write_trace(TRACE_REQ * pTrace, double dGapThresh)
    00780      /*
    00781  * input:  pTrace   pointer to buffer for the trace data request
    00782  *         eventId   not used here
    00783  */
    00784 {
    00785   TRACE_HEADER *wf;
    00786   char        *msg_p;        /* pointer into tracebuf data */
    00787   short       *s_data;
    00788   long        *l_data;
    00789   float       *f_data;
    00790   float       *sac_p;      /* the data part of the SAC buffer */
    00791   int          j;
    00792   int          gap_count = 0;
    00793   long         nsamp, nfill;
    00794   long         nfill_max = 0l;
    00795   long         nsamp_this_scn = 0l;
    00796   long         this_size;
    00797   double       starttime, endtime; /* times for current scn         */
    00798   double       samprate;
    00799   float        fill = (float)SACUNDEF;
    00800   struct tm    *time;
    00801   time_t       ltime;
    00802   char         datatype;  /* 's' for short, 'l' for long */
    00803
    00804   /* Check validity of the arguments */
    00805   if (pTrace == NULL)
    00806   {
    00807     logit ("e", "SACPABase_write_trace: Invalid arguments passed in\n");
    00808     return (EW_FAILURE);
    00809   }
    00810
    00811   if ((msg_p = pTrace->pBuf) == NULL)
    00812   {
    00813     logit ("e", "SACPABase_write_trace: message buffer is NULL\n");
    00814     return EW_FAILURE;
    00815   }
    00816
    00817   sac_p = (float *)(SacBuffer + SACHEADERSIZE);
    00818
    00819   wf = (TRACE_HEADER *) msg_p;
    00820   if (WaveMsgMakeLocal(wf) < 0)
    00821   {
    00822     logit("e", "SACPABase_write_trace: unknown trace data type: %s\n",
    00823           wf->datatype);
    00824     return( EW_FAILURE );
    00825   }
    00826
    00827   nsamp = wf->nsamp;
    00828   starttime = wf->starttime;
    00829   endtime = wf->endtime;
    00830   samprate = wf->samprate;
    00831   if (samprate < 0.01)
    00832   {
    00833     logit("et", "SACPABase_write_trace: unreasonable samplerate (%f) for <%s.%s.%s>\n",
    00834           samprate, SAC_szSta, SAC_szChan, SAC_szNet);
    00835     return( EW_FAILURE );
    00836   }
    00837
    00838   SAC_starttime = starttime;
    00839   datatype = 'n';
    00840   if (wf->datatype[0] == 's' || wf->datatype[0] == 'i')
    00841   {
    00842     if (wf->datatype[1] == '2') datatype = 's';
    00843     else if (wf->datatype[1] == '4') datatype = 'l';
    00844   }
    00845   else if (wf->datatype[0] == 't' || wf->datatype[0] == 'f')
    00846   {
    00847     if (wf->datatype[1] == '4') datatype = 'f';
    00848   }
    00849   if (datatype == 'n')
    00850   {
    00851     logit("et", "SACPABase_write_trace: unsupported datatype: %s\n", datatype);
    00852     return( EW_FAILURE );
    00853   }
    00854
    00855   /* loop through all the messages for this s-c-n */
    00856   while (1)
    00857   {
    00858     /* advance message pointer to the data */
    00859     msg_p += sizeof(TRACE_HEADER);
    00860
    00861     /* check for sufficient memory in output buffer */
    00862     this_size = (nsamp_this_scn + nsamp ) * sizeof(float);
    00863
    00864     if ( BufferLen < (this_size + SACHEADERSIZE) )
    00865     {
    00866       logit( "", "out of space for <%s.%s.%s>; saving short trace.\n",
    00867              SAC_szSta, SAC_szChan, SAC_szNet);
    00868       break;
    00869     }
    00870
    00871     switch( datatype )
    00872     {
    00873     case 's':
    00874       s_data = (short *)msg_p;
    00875       for ( j = 0; j < nsamp ; j++, nsamp_this_scn++ )
    00876         sac_p[nsamp_this_scn] = (float) s_data[j];
    00877       msg_p += sizeof(short) * nsamp;
    00878       break;
    00879     case 'l':
    00880       l_data = (long *)msg_p;
    00881       for ( j = 0; j < nsamp; j++, nsamp_this_scn++ )
    00882         sac_p[nsamp_this_scn] = (float) l_data[j];
    00883       msg_p += sizeof(long) * nsamp;
    00884       break;
    00885     case 'f':
    00886       f_data = (float *)msg_p;
    00887       for ( j = 0; j < nsamp; j++, nsamp_this_scn++ )
    00888         sac_p[nsamp_this_scn] = f_data[j];
    00889       msg_p += sizeof(float) * nsamp;
    00890       break;
    00891     }
    00892
    00893     /* End-check based on length of snippet buffer */
    00894     if ((long) msg_p >= ((long) pTrace->actLen + (long) pTrace->pBuf))
    00895     {
    00896       if (SACPAB_Debug == 1)
    00897         logit ("", "Setting done for <%s.%s.%s>\n", SAC_szSta, SAC_szChan,
    00898                SAC_szNet);
    00899       break;
    00900     }
    00901
    00902     /* msg_p has been advanced to the next TRACE_BUF; localize bytes *
    00903      * and check for gaps.                                           */
    00904     wf = (TRACE_HEADER *) msg_p;
    00905     if (WaveMsgMakeLocal(wf) < 0)
    00906     {
    00907       logit("e", "SACPABase_write_trace: unknown trace data type: %s\n",
    00908             wf->datatype);
    00909       return( EW_FAILURE );
    00910     }
    00911     nsamp = wf->nsamp;
    00912     starttime = wf->starttime;
    00913     /* starttime is set for new packet; endtime is still set for old packet */
    00914     if ( endtime + ( 1.0/samprate ) * dGapThresh < starttime )
    00915     {
    00916       /* there's a gap, so fill it */
    00917       nfill = (long) ((float)samprate *
    00918                                                 (float) (starttime - endtime) -(float) 1.0);
    00919
    00920       if (SACPAB_Debug == 1)
    00921         logit("e", "gap in %s.%s.%s: %lf: %lf, fill with %d samples\n",
    00922                                 SAC_szSta, SAC_szChan, SAC_szNet,
    00923                                 endtime, starttime - endtime, nfill);
    00924
    00925       if ( (nsamp_this_scn + nfill) * (long)sizeof(float) > BufferLen )
    00926       {
    00927         logit("e", "bogus gap (%d); skipping\n", nfill);
    00928         return(EW_FAILURE);
    00929       }
    00930       /* do the filling */
    00931       for ( j = 0; j < nfill; j++, nsamp_this_scn ++ )
    00932         sac_p[nsamp_this_scn] = fill;
    00933       /* keep track of how many gaps and the largest one */
    00934       gap_count++;
    00935       if (nfill_max < nfill)
    00936         nfill_max = nfill;
    00937     }
    00938     /* Advance endtime to the new packet;        *
    00939      * process this packet in the next iteration */
    00940     endtime = wf->endtime;
    00941
    00942   } /* while (1) */
    00943
    00944   /*  All trace data fed into SAC data section.  Now fill in header */
    00945   sacheadp->npts = (long) nsamp_this_scn;  /* samples in trace */
    00946   sacheadp->delta = (float) (1.0/samprate);   /* sample period */
    00947   sacheadp->e = (float) nsamp_this_scn * sacheadp->delta;  /* end time */
    00948   ltime = (time_t)SAC_starttime;
    00949   /* gmttime makes juldays starting with 0 */
    00950   time = gmtime( &ltime );
    00951   sacheadp->nzyear = (long)time->tm_year + 1900l; /* calendar year of reference time */
    00952   sacheadp->nzjday = (long)time->tm_yday + (long)1;  /* julian day, 0 - 365 */
    00953   sacheadp->nzhour = (long)time->tm_hour;
    00954   sacheadp->nzmin  = (long)time->tm_min;
    00955   sacheadp->nzsec  = (long)time->tm_sec;
    00956   sacheadp->nzmsec = (long)((SAC_starttime - (long)SAC_starttime) * 1000.0);
    00957
    00958   /* set the origin time */
    00959   sacheadp->o      = (float)(SAC_Origin.tOrigin - SAC_starttime);
    00960
    00961   if (gap_count)
    00962     logit("e", "%d gaps; largest %ld for <%s.%s.%s>\n",
    00963           gap_count, nfill_max, SAC_szSta, SAC_szChan, SAC_szNet);
    00964
    00965   return(EW_SUCCESS);
    00966 }
    00967
    00968 int SACPABase_write_parametric(SAC_ArrivalStruct * pArrival, int WaveType)
    00969 {
    00970   int i;
    00971
    00972   if (pArrival == NULL)
    00973   {
    00974     logit ("", "Invalid parameters passed in\n");
    00975     return EW_FAILURE;
    00976   }
    00977
    00978   if (WaveType == PWAVE)
    00979   {
    00980     for (i = 0; i < K_LEN; ++i)
    00981       sacheadp->ka[i] = ' ';
    00982
    00983     sacheadp->a    = (float)(pArrival->tPhase - SAC_starttime);
    00984     sacheadp->ka[0]= 'P';
    00985     sacheadp->ka[1]= pArrival->cFMotion;
    00986     sacheadp->ka[2]= pArrival->iPhaseWt + '0';
    00987     sacheadp->ka[3]= pArrival->cOnset;
    00988     sacheadp->f    = (float)(pArrival->dCodaLen + sacheadp->a);
    00989     sacheadp->dist = (float)(pArrival->dDist);
    00990     sacheadp->az   = (float)(pArrival->dAzm);
    00991   }
    00992   else if (WaveType == SWAVE)
    00993   {
    00994
    00995     for (i = 0; i < K_LEN; ++i)
    00996       sacheadp->kt0[i] = ' ';
    00997
    00998     sacheadp->t0    = (float)(pArrival->tPhase - SAC_starttime);
    00999     sacheadp->kt0[0]= 'S';
    01000     sacheadp->kt0[1]= pArrival->cFMotion;
    01001     sacheadp->kt0[2]= pArrival->iPhaseWt + '0';
    01002     sacheadp->kt0[3]= pArrival->cOnset;
    01003     sacheadp->f    = (float)(pArrival->dCodaLen + sacheadp->a);
    01004     sacheadp->dist = (float)(pArrival->dDist);
    01005     sacheadp->az   = (float)(pArrival->dAzm);
    01006   }
    01007   else
    01008   {
    01009     logit ("", "Invalid WaveType %d.\n", WaveType);
    01010     return EW_FAILURE;
    01011   }
    01012
    01013   return(EW_SUCCESS);
    01014 }
    01015
    01016 int SACPABase_write_amppicks(SAC_AmpPickStruct * pAmpPick)
    01017 {
    01018
    01019         double  tmp1, tmp2;
    01020
    01021         if (pAmpPick == NULL)
    01022         {
    01023                 logit ("", "Invalid arguments passed in.\n");
    01024                 return EW_FAILURE;
    01025         }
    01026
    01027         if (pAmpPick->PickType == 0)
    01028         {
    01029                 /* zero-to-peak case */
    01030                 sacheadp->t0 = (float ) (pAmpPick->ZP_time - SAC_starttime);
    01031                 sacheadp->user0 = (float) (pAmpPick->ZP_amp);
    01032
    01033                 sprintf (sacheadp->kt0, "0-P_max");
    01034                 sprintf (sacheadp->kuser0, "0-P_amp");
    01035         }
    01036         else if (pAmpPick->PickType == 1)
    01037         {
    01038                 /* peak-to-peak case */
    01039
    01040                 tmp1 = (pAmpPick->PPmin_time - SAC_starttime);
    01041                 tmp2 = (pAmpPick->PPmax_time - SAC_starttime);
    01042                 sacheadp->t1 = (float) tmp1;
    01043                 sacheadp->t2 = (float) tmp2;
    01044                 sacheadp->user1 = (float) (pAmpPick->PP_amp);
    01045
    01046                 sprintf (sacheadp->kt1, "P-P_min");
    01047                 sprintf (sacheadp->kt2, "P-P_max");
    01048                 sprintf (sacheadp->kuser1, "P-P_amp");
    01049         }
    01050         else
    01051         {
    01052                 logit ("", "Invalid PickType value: %d\n", pAmpPick->PickType);
    01053                 return EW_FAILURE;
    01054         }
    01055
    01056         sprintf (sacheadp->kinst, "W_A_(mm)");
    01057
    01058         return EW_SUCCESS;
    01059
    01060 }
    01061
    01062
    01063 int SACPABase_write_stainfo(SAC_StationStruct * pStation)
    01064 {
    01065   char szPZFilename[256];
    01066   FILE * fpPZ;
    01067   int i;
    01068   double dist, azm;
    01069   /*
    01070     SAMPLE POLES AND ZEROES FILE
    01071     ============================
    01072
    01073     ZEROS 4
    01074     -0.125  0.0
    01075     -50.0  0.0
    01076     POLES 4
    01077     -0.13 0.0
    01078     -6.02 0.0
    01079     -8.66 0.0
    01080     -35.2 0.0
    01081     CONSTANT -394.0
    01082   */
    01083
    01084   sacheadp->stla=pStation->dLat;
    01085   sacheadp->stlo=pStation->dLon;
    01086   sacheadp->stel=pStation->dElev;
    01087
    01088
    01089   /*
    01090    * This is a good time to make sure that distance and azm get set.
    01091    * Story: dist and azm are properties of Arrivals in the DB schema.
    01092    * This means that they don't get set for SAC traces without picks.
    01093    * This is not good. So, here we cloodge it. LV 6/2001.
    01094    */
    01095
    01096   if ((sacheadp->evla != (float) SACUNDEF)  && (sacheadp->evlo != (float) SACUNDEF)  &&
    01097       (sacheadp->stla != (float) SACUNDEF)  && (sacheadp->stlo != (float) SACUNDEF))
    01098   {
    01099         if (geo_to_km (sacheadp->evla, sacheadp->evlo,
    01100                         sacheadp->stla, sacheadp->stlo, &dist, &azm) != 1)
    01101         {
    01102             logit ("", "Call to geo_to_km failed - ignoring.\n");
    01103         }
    01104         else
    01105         {
    01106           if (sacheadp->dist == (float) SACUNDEF)
    01107           {
    01108              sacheadp->dist = (float) dist;
    01109           }
    01110           if (sacheadp->az == (float) SACUNDEF)
    01111           {
    01112              sacheadp->az = (float) azm;
    01113           }
    01114         }
    01115   }
    01116
    01117   if ((pStation->bResponseIsValid) &&
    01118                 ((pStation->pResponse->iNumPoles > 0) ||
    01119                         (pStation->pResponse->iNumZeroes > 0)))
    01120   {
    01121     /* create the full SAC file name for this SCN PZ file */
    01122     sprintf(szPZFilename,"%s/%s.%s.%s.pz",SacDir, SAC_szSta, SAC_szChan,
    01123             SAC_szNet);
    01124     fpPZ=fopen(szPZFilename,"w");
    01125     if(!fpPZ)
    01126     {
    01127       logit("e","SACPABase_write_stainfo():  Failed to open file: %s! Errno=%d\n",
    01128             szPZFilename,errno);
    01129       return(SACPAB_FOPEN_FAILED);
    01130     }
    01131
    01132     fprintf(fpPZ,"POLES %d\n",pStation->pResponse->iNumPoles);
    01133     for(i=0;i<pStation->pResponse->iNumPoles;i++)
    01134     {
    01135       fprintf(fpPZ,"%f %f\n",pStation->pResponse->Poles[i].dReal,
    01136               pStation->pResponse->Poles[i].dImag);
    01137     }
    01138
    01139     fprintf(fpPZ,"ZEROS %d\n",pStation->pResponse->iNumZeroes);
    01140     for(i=0;i<pStation->pResponse->iNumZeroes;i++)
    01141     {
    01142       fprintf(fpPZ,"%f %f\n",pStation->pResponse->Zeroes[i].dReal,
    01143               pStation->pResponse->Zeroes[i].dImag);
    01144     }
    01145
    01146     fprintf(fpPZ,"CONSTANT %e\n",pStation->pResponse->dGain);
    01147
    01148     fclose(fpPZ);
    01149   }  /* end if(bResponseIsValid) */
    01150
    01151   return(EW_SUCCESS);
    01152 }
    01153
    01154
    01155
    01156
    01157 int SACPABase_end_scn (void)
    01158 {
    01159   size_t towrite;           /* bytes to write to SAC file */
    01160   char   sacfile[2*MAXTXT]; /* the name of the sac file */
    01161   FILE  *fp;                /* sacfile file pointer */
    01162   long   i, npts;           /* number of SAC data points */
    01163   float *sac_p;
    01164
    01165   if(!bSACPABase_scn_open)
    01166   {
    01167     logit("e","SACPABase_end_scn(): ERROR! There is no open SCN record.\n");
    01168     return(SACPAB_SCN_NOT_OPEN);
    01169   }
    01170
    01171   npts = sacheadp->npts;
    01172   sac_p = (float *)(SacBuffer + SACHEADERSIZE);
    01173   if (strcmp (SAC_szOutputFormat, SAC_DIFFERENT_PLATFORM) == 0)
    01174   {
    01175     swapsac(sacheadp);
    01176     for (i = 0; i < npts; i++)
    01177       SwapFloat(&sac_p[i]);
    01178   }
    01179
    01180   /* copy the (potentially byte-swapped) SAC header
    01181      into the SAC buffer and write it out.
    01182   ******************************************************/
    01183   memcpy ((void *) SacBuffer, (void *) sacheadp, SACHEADERSIZE);
    01184
    01185   /* Update SAC file list with file name and arrival time */
    01186   sprintf (FileList[FileIndex].filename, "%s.%s.%s",  SAC_szSta, SAC_szChan,
    01187            SAC_szNet);
    01188   FileList[FileIndex].sort_param = SAC_starttime;
    01189
    01190   if ((FileIndex = FileIndex + 1) > DB_MAX_PHS_PER_EQ)
    01191   {
    01192     logit ("e", "SACPABase_end_scn: WARNING: Maximum number of phases per "
    01193            "event (%d) exceeded.\n", DB_MAX_PHS_PER_EQ);
    01194
    01195     FileIndex = FileIndex - 1;
    01196   }
    01197
    01198   /* create the full SAC file name for this SCN */
    01199   sprintf(sacfile, "%s/%s", SacDir, FileList[FileIndex-1].filename);
    01200
    01201
    01202   /* Open the sacfile */
    01203   if ((fp = fopen (sacfile, "wb")) == NULL)
    01204   {
    01205     logit("e", "SACPABase_next_scn: cannot open %s\n", sacfile);
    01206     return(EW_FAILURE);
    01207   }
    01208
    01209   /* Write the buffer to the sacfile */
    01210   towrite = SACHEADERSIZE + sizeof(float) * npts;
    01211   if (fwrite ((const void *) SacBuffer, towrite, 1, fp) != 1)
    01212   {
    01213     logit("e", "SACPABase_end_scn: cannot write %s\n", sacfile);
    01214     (void) unlink(sacfile);
    01215     return EW_FAILURE;
    01216   }
    01217   fclose (fp);
    01218
    01219   /* mark the SCN closed */
    01220   bSACPABase_scn_open=FALSE;
    01221   return(EW_SUCCESS);
    01222 }
    01223
    01224
    01225 int SACPABase_end_scn_gm (void)
    01226 {
    01227   size_t towrite;           /* bytes to write to SAC file */
    01228   char   sacfile[2*MAXTXT]; /* the name of the sac file */
    01229   FILE  *fp;                /* sacfile file pointer */
    01230   long   i, npts;           /* number of SAC data points */
    01231   float *sac_p;
    01232
    01233   if(!bSACPABase_scn_open)
    01234   {
    01235     logit("e","SACPABase_end_scn(): ERROR! There is no open SCN record.\n");
    01236     return(SACPAB_SCN_NOT_OPEN);
    01237   }
    01238
    01239   npts = sacheadp->npts;
    01240   sac_p = (float *)(SacBuffer + SACHEADERSIZE);
    01241   if (strcmp (SAC_szOutputFormat, SAC_DIFFERENT_PLATFORM) == 0)
    01242   {
    01243     swapsac(sacheadp);
    01244     for (i = 0; i < npts; i++)
    01245       SwapFloat(&sac_p[i]);
    01246   }
    01247
    01248   /* copy the (potentially byte-swapped) SAC header
    01249      into the SAC buffer and write it out.
    01250   ******************************************************/
    01251   memcpy ((void *) SacBuffer, (void *) sacheadp, SACHEADERSIZE);
    01252
    01253
    01254   /* create the full SAC file name for this SCN */
    01255   sprintf(sacfile, "%s/%s.gm", SacDir, FileList[FileIndex-1].filename);
    01256
    01257
    01258   /* Open the sacfile */
    01259   if ((fp = fopen (sacfile, "wb")) == NULL)
    01260   {
    01261     logit("e", "SACPABase_next_scn: cannot open %s\n", sacfile);
    01262     return(EW_FAILURE);
    01263   }
    01264
    01265   /* Write the buffer to the sacfile */
    01266   towrite = SACHEADERSIZE + sizeof(float) * npts;
    01267   if (fwrite ((const void *) SacBuffer, towrite, 1, fp) != 1)
    01268   {
    01269     logit("e", "SACPABase_end_scn: cannot write %s\n", sacfile);
    01270     (void) unlink(sacfile);
    01271     return EW_FAILURE;
    01272   }
    01273   fclose (fp);
    01274
    01275   /* mark the SCN closed */
    01276   bSACPABase_scn_open=FALSE;
    01277   return(EW_SUCCESS);
    01278 }
    01279
    01280
    01281 /************************************************************************
    01282 *       This is the Put Away end event routine. It's called after we've     *
    01283 *       finished processing one event.                                  *
    01284 *************************************************************************/
    01285 int SACPABase_end_ev (void)
    01286 {
    01287
    01288   if (SACPAB_Debug == 1)
    01289     logit ("", "In SACPA_end_ev\n");
    01290
    01291   qsort ((void *) FileList, (size_t) FileIndex,
    01292          sizeof (SACFileListStruct), SAC_Compare);
    01293
    01294   /* We haven't processed an event - something's fishy! */
    01295   if (!strcmp(szCurEventID,"-1"))
    01296   {
    01297     logit ("e", "SACPA_end_ev: CurEventId is invalid - don't know how to proceed\n");
    01298
    01299     return EW_FAILURE;
    01300   }
    01301
    01302
    01303   if (CreateSACSupportFiles (szCurEventID, FileList, FileIndex) != EW_SUCCESS)
    01304   {
    01305     logit ("e", "SACPABase_write_trace: Call to CreateSACSupportFiles failed\n");
    01306     return EW_FAILURE;
    01307   }
    01308
    01309   return(EW_SUCCESS);
    01310 }
    01311
    01312
    01313 /************************************************************************
    01314 *       This is the Put Away close routine. It's called after when      *
    01315 *       we're being shut down.                                          *
    01316 *************************************************************************/
    01317 int SACPABase_close (void)
    01318 {
    01319
    01320   free ((char *) SacBuffer);
    01321   if (!bSACPABase_init)
    01322   {
    01323     logit("","SACPABase_close():  Error, SACPABase is not initialized!\n");
    01324     return(SACPAB_NOT_INIT);
    01325   }
    01326   bSACPABase_init = FALSE;
    01327   return EW_SUCCESS;
    01328 }
    01329
    01330
    01331 void sacinit( struct SAChead *head)
    01332 {
    01333   int i;
    01334   struct SAChead2 *head2;   /* use a simple structure here - we don't care what
    01335                              * the variables are - set them to 'undefined' */
    01336
    01337   /* change to a simpler format */
    01338   head2 = (struct SAChead2 *) head;
    01339
    01340   /*    set all of the floats to 'undefined'    */
    01341   for (i = 0; i < NUM_FLOAT; ++i) head2->SACfloat[i] = SACUNDEF;
    01342   /*    set all of the ints to 'undefined'      */
    01343   for (i = 0; i < MAXINT-5; ++i) head2->SACint[i] = SACUNDEF;
    01344   /*    except for the logical integers - set them to 1 */
    01345   for ( ; i < MAXINT; ++i) head2->SACint[i] = 1;
    01346   /*    set all of the strings to 'undefined'   */
    01347   for (i = 0; i < MAXSTRING; ++i) (void) strncpy(head2->SACstring[i],
    01348                                                  SACSTRUNDEF,K_LEN);
    01349
    01350   /*    SAC I.D. number */
    01351   head2->SACfloat[9] = SAC_I_D;
    01352   /*    header version number */
    01353   head2->SACint[6] = SACVERSION;
    01354
    01355   return;       /* done */
    01356 }
    01357
    01358 /*
    01359  * swapsac: swap all the numeric fields in the SAC header.
    01360  */
    01361 void swapsac(struct SAChead *head)
    01362 {
    01363   int i;
    01364   struct SAChead2 *head2; /* use a simple structure here - we don't care what
    01365                            * the variables are - just swap their bytes! */
    01366
    01367   /* change to a simpler format */
    01368   head2 = (struct SAChead2 *) head;
    01369
    01370   /*    swap all of the floats  */
    01371   for (i = 0; i < NUM_FLOAT; ++i)
    01372     SwapFloat(&head2->SACfloat[i]);
    01373
    01374   /*    swap all of the ints   */
    01375   for ( i = 0; i < MAXINT; ++i)
    01376     SwapLong( &(head2->SACint[i]));
    01377
    01378   return;
    01379 }
    01380
    01381 /**************************************************
    01382  *  SAC_Compare()  compares 2 values              *
    01383  *  This function is passed to qsort()            *
    01384  **************************************************/
    01385 int SAC_Compare (const void *p1, const void *p2)
    01386 {
    01387   SACFileListStruct *srt1 = (SACFileListStruct *) p1;
    01388   SACFileListStruct *srt2 = (SACFileListStruct *) p2;
    01389
    01390   if (srt1->sort_param < srt2->sort_param)
    01391     return (-1);
    01392
    01393   if (srt1->sort_param > srt2->sort_param)
    01394     return (1);
    01395
    01396   return (0);
    01397 }
    01398
    01399
    01400
    01401
    01402 /* SACSupportFiles
    01403  *
    01404  * Write simple SAC macros to disk files in current working directory,
    01405  * given a list of filenames sorted in some order.
    01406  *
    01407  * Also write other files necessary for relocating the event
    01408  * with hypoinverse and for updating database.
    01409  * July 1998, LDD
    01410  */
    01411
    01412 /* how many traces do we want in the quicklook macro */
    01413 #define         NQUICKLOOK      10
    01414
    01415 /* Support file names */
    01416 #define         INIT_FNAME      "init"
    01417 #define         QUICKLOOK_FNAME "quicklook"
    01418 #define         REPICK_FNAME    "repick"
    01419 #define         SACLIST_FNAME   "saclist"
    01420
    01421 /*******************************************************
    01422  * CreateSACSupportFiles() writes all the desired SAC macros
    01423  *  and Hypoinv files to the current working directory
    01424  *******************************************************/
    01425 int CreateSACSupportFiles (char * szEventid, SACFileListStruct *pfl, int nfile)
    01426 {
    01427   int nlook;
    01428
    01429   if (SACmac_init() != EW_SUCCESS)
    01430   {
    01431     logit ("e", "Call to SACmac_init failed\n");
    01432     return EW_FAILURE;
    01433   }
    01434
    01435   nlook = (nfile < NQUICKLOOK) ? nfile : NQUICKLOOK;
    01436   if (SACmac_quicklook (pfl, nlook) != EW_SUCCESS)
    01437   {
    01438     logit ("e", "Call to SACmac_quicklook failed\n");
    01439     return EW_FAILURE;
    01440   }
    01441
    01442
    01443   if (SACmac_repick (pfl, nfile) != EW_SUCCESS)
    01444   {
    01445     logit ("e", "Call to SACmac_repick failed\n");
    01446     return EW_FAILURE;
    01447   }
    01448
    01449   if (SAC_filelist (pfl, nfile, szEventid) != EW_SUCCESS)
    01450   {
    01451     logit ("e", "Call to SAC_filelist failed\n");
    01452     return EW_FAILURE;
    01453   }
    01454
    01455   return (EW_SUCCESS);
    01456
    01457 }
    01458
    01459 /**************************************************
    01460  * SACmac_init() writes a simple initialization   *
    01461  *  macro to the current working directory in a   *
    01462  *  file named "init"                             *
    01463  **************************************************/
    01464 int SACmac_init (void)
    01465 {
    01466   FILE *fp;
    01467   char filename[256];
    01468
    01469   sprintf (filename, "%s/%s", SacDir, INIT_FNAME);
    01470
    01471   if ((fp = fopen (filename, "w+")) == NULL)
    01472   {
    01473     logit ("e", "SACmac_init: cannot open macro file %s; %s\n",
    01474            filename, strerror (errno));
    01475     return (EW_FAILURE);
    01476   }
    01477
    01478   fprintf (fp, "qdp 1000\n"
    01479            "window 1 x 0 1 y 0.35 0.97\n"
    01480            "bd X\n"
    01481            "bw 1\n" );
    01482   fclose (fp);
    01483
    01484   return (EW_SUCCESS);
    01485 }
    01486
    01487
    01488 /**************************************************
    01489  * SACmac_quicklook() writes a macro to bring up  *
    01490  *  the first nlook files in the list.  The list  *
    01491  *  should be sorted before invoking this funtion *
    01492  **************************************************/
    01493 int SACmac_quicklook (SACFileListStruct *pfl, int nlook)
    01494 {
    01495   FILE *fp;
    01496   int i;
    01497   char filename[256];
    01498
    01499   sprintf (filename, "%s/%s", SacDir, QUICKLOOK_FNAME);
    01500
    01501   if ((fp = fopen (filename, "w+")) == NULL)
    01502   {
    01503     logit("e", "SACmac_quicklook: cannot open macro file %s; %s\n",
    01504           filename, strerror (errno));
    01505     return (EW_FAILURE);
    01506   }
    01507
    01508   fprintf (fp, "qdp 500\n"
    01509            "fileid type list kevnm kstcmp\n"
    01510            "r ");
    01511
    01512   for (i = 0; i < nlook; i++ )
    01513     fprintf (fp, "%s ", pfl[i].filename);
    01514
    01515   fprintf (fp, "\n"
    01516            "p1\n");
    01517
    01518   fclose (fp);
    01519
    01520   return (EW_SUCCESS);
    01521 }
    01522
    01523
    01524 /**************************************************
    01525  * SACmac_repick() writes a macro to bring up     *
    01526  *  each trace for this event to repick it        *
    01527  **************************************************/
    01528 int SACmac_repick (SACFileListStruct *pfl, int nfile)
    01529 {
    01530   FILE *fp;
    01531   int i;
    01532   char filename[256];
    01533
    01534   sprintf (filename, "%s/%s", SacDir, REPICK_FNAME);
    01535
    01536   if ((fp = fopen (filename, "w+")) == NULL)
    01537   {
    01538     logit ("e", "SACmac_repick: cannot open macro file %s; %s\n",
    01539            filename, strerror (errno));
    01540     return (EW_FAILURE);
    01541   }
    01542
    01543   fprintf (fp, "qdp 500\n"
    01544            "fileid type list kevnm kstcmp\n");
    01545
    01546   fprintf (fp, "r %s\n"
    01547            "ppk p off b off\n"
    01548            "wh\n",
    01549            pfl[0].filename);  /* Turn off that darn bell! */
    01550
    01551   for (i = 1; i < nfile; i++)
    01552   {
    01553     fprintf (fp, "r %s\n"
    01554              "ppk p off\n"
    01555              "wh\n",
    01556              pfl[i].filename);
    01557   }
    01558   fclose (fp);
    01559
    01560   return (EW_SUCCESS);
    01561 }
    01562
    01563
    01564 /**************************************************
    01565  * SAC_filelist() writes a file containing the    *
    01566  *  names of all the SAC files in the directory   *
    01567  **************************************************/
    01568 int SAC_filelist (SACFileListStruct *pfl, int nfile, char * szEventid)
    01569 {
    01570   FILE *fp;
    01571   int i;
    01572   char filename[256];
    01573
    01574   sprintf (filename, "%s/%s", SacDir, SACLIST_FNAME);
    01575
    01576   if ((fp = fopen (filename, "w+")) == NULL)
    01577   {
    01578     logit ("e", "SACmac_filelist: cannot open file %s; %s\n",
    01579            filename, strerror (errno));
    01580     return (EW_FAILURE);
    01581   }
    01582
    01583   fprintf (fp, "EVENTID:%s\n", szEventid);
    01584
    01585   for (i = 0; i < nfile; i++)
    01586   {
    01587     fprintf (fp, "%s\n", pfl[i].filename);
    01588   }
    01589
    01590   fclose (fp);
    01591
    01592   return (EW_SUCCESS);
    01593 }
    01594
    01595 int SAC_SwapLong(long * pValue, char cDataType)
    01596 {
    01597 #if defined (_SPARC)
    01598   if( cDataType == 'i' || cDataType == 'f' )
    01599     SwapLong(pValue);
    01600   return(EW_SUCCESS);
    01601 #elif defined (_INTEL)
    01602   if( cDataType == 's' || cDataType == 't' )
    01603     SwapLong(pValue);
    01604   return(EW_SUCCESS);
    01605 #else
    01606   logit("e","SAC_SwapLong():Error! Unable to determine platform! "
    01607         "Please compile w/ _INTEL or _SPARC!\n");
    01608   return(SACPAB_UNKNOWN_PLATFORM);
    01609 #endif
    01610 }
    01611
    01612 int SAC_SwapShort(short * pValue, char cDataType)
    01613 {
    01614 #if defined (_SPARC)
    01615   if( cDataType == 'i' || cDataType == 'f' )
    01616     SwapShort(pValue);
    01617   return(EW_SUCCESS);
    01618 #elif defined (_INTEL)
    01619   if( cDataType == 's' || cDataType == 't' )
    01620     SwapShort(pValue);
    01621   return(EW_SUCCESS);
    01622 #else
    01623   logit("e","SAC_SwapShort():Error! Unable to determine platform! "
    01624         "Please compile w/ _INTEL or _SPARC!\n");
    01625   return(SACPAB_UNKNOWN_PLATFORM);
    01626 #endif
    01627 }
    01628
    01629 int SAC_SwapDouble(double * pValue, char cDataType)
    01630 {
    01631 #if defined (_SPARC)
    01632   if( cDataType == 'i' || cDataType == 'f' )
    01633     SwapDouble(pValue);
    01634   return(EW_SUCCESS);
    01635 #elif defined (_INTEL)
    01636   if( cDataType == 's' || cDataType == 't' )
    01637     SwapDouble(pValue);
    01638   return(EW_SUCCESS);
    01639 #else
    01640   logit("e","SAC_SwapDouble():Error! Unable to determine platform! "
    01641         "Please compile w/ _INTEL or _SPARC!\n");
    01642   return(SACPAB_UNKNOWN_PLATFORM);
    01643 #endif
    01644 }
    01645
    01646
    01647 /* Write urban hazards external info into the header */
    01648 int SACPABase_write_extinfo (SAC_ExtChanStruct *pExtChan)
    01649 {
    01650
    01651         if (pExtChan == NULL)
    01652         {
    01653                 logit ("", "SACPABase_write_extinfo: Invalid arguments passed in\n");
    01654                 return (EW_FAILURE);
    01655         }
    01656
    01657
    01658         sacheadp->user0 = (float) pExtChan->iGain;
    01659         sacheadp->user1 = (float) pExtChan->dFullscale;
    01660         sacheadp->user2 = (float) pExtChan->dSensitivity;
    01661         sacheadp->user3 = (float) pExtChan->dDamping;
    01662         sacheadp->user4 = (float) pExtChan->dNaturalFrequency;
    01663         sacheadp->user5 = (float) pExtChan->iSensorType;
    01664
    01665         sacheadp->cmpaz = (float) pExtChan->dAzm;
    01666         sacheadp->cmpinc = (float) pExtChan->dDip;
    01667
    01668         return(EW_SUCCESS);
    01669
    01670 }
    01671
    01672