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 

Generated on Tue May 6 09:16:09 2003 for Earthworm Libs by doxygen1.3-rc3