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

# arc_2_ewevent.c

Go to the documentation of this file.

    00001 /*
    00002  *   THIS FILE IS UNDER RCS - DO NOT MODIFY UNLESS YOU HAVE
    00003  *   CHECKED IT OUT USING THE COMMAND CHECKOUT.
    00004  *
    00005  *    $Id: arc__2__ewevent_8c-source.html,v 1.1 2006/05/19 16:55:01 paulf Exp $
    00006  *
    00007  *    Revision history:
    00008  *     $Log: arc__2__ewevent_8c-source.html,v $
    00008  *     Revision 1.1  2006/05/19 16:55:01  paulf
    00008  *     first inclusion
    00008  *
    00009  *     Revision 1.7  2001/07/20 17:40:05  lucky
    00010  *     State of the code after much of v6.0 testing and debugging
    00011  *
    00012  *     Revision 1.6  2001/07/01 21:55:20  davidk
    00013  *     Cleanup of the Earthworm Database API and the applications that utilize it.
    00014  *     The "ewdb_api" was cleanup in preparation for Earthworm v6.0, which is
    00015  *     supposed to contain an API that will be backwards compatible in the
    00016  *     future.  Functions were removed, parameters were changed, syntax was
    00017  *     rewritten, and other stuff was done to try to get the code to follow a
    00018  *     general format, so that it would be easier to read.
    00019  *
    00020  *     Applications were modified to handle changed API calls and structures.
    00021  *     They were also modified to be compiler warning free on WinNT.
    00022  *
    00023  *     Revision 1.5  2001/06/26 19:55:31  lucky
    00024  *     Fixed a bug where the number of stamags was not correctly incremented
    00025  *     in the conversion from Arc msg to Event struct.
    00026  *
    00027  *     Revision 1.4  2001/06/21 21:25:00  lucky
    00028  *     State of the code after LocalMag review was implemented and partially tested.
    00029  *
    00030  *     Revision 1.3  2001/06/06 20:54:46  lucky
    00031  *     Changes made to support multitude magnitudes, as well as amplitude picks. This is w
    00032  *     in progress - checkin in for the sake of safety.
    00033  *
    00034  *     Revision 1.2  2001/05/21 22:33:42  davidk
    00035  *     removed internal definition of MAGTYPE_DURATION.  Using the one from rw_mag.h
    00036  *     instead.
    00037  *
    00038  *     Revision 1.1  2001/05/15 02:15:27  davidk
    00039  *     Initial revision
    00040  *
    00041  *     Revision 1.4  2001/04/17 17:22:36  davidk
    00042  *     Removed some unneeded local variables to get rid of compiler warnings
    00043  *     on NT.
    00044  *
    00045  *     Revision 1.2  2001/01/18 21:26:58  lucky
    00046  *     Cleaned up debug messages
    00047  *
    00048  *     Revision 1.1  2000/12/18 18:55:12  lucky
    00049  *     Initial revision
    00050  *
    00051  *     Revision 1.12  2000/12/06 17:50:47  lucky
    00052  *     We now correctly keep track of the pick onset
    00053  *
    00054  *     Revision 1.11  2000/09/20 19:50:09  lucky
    00055  *     Do not over-write coda length when filling in S-pick information -- it gets
    00056  *     the wrong duration in the Arc file.
    00057  *
    00058  *     Revision 1.10  2000/09/13 15:36:51  lucky
    00059  *     Fixed FirstMotion character handling;
    00060  *     Fixed handling of the coda length
    00061  *
    00062  *     Revision 1.7  2000/09/07 21:17:45  lucky
    00063  *     Final version after the Review pages have been demonstrated.
    00064  *
    00065  *     Revision 1.4  2000/08/30 17:41:57  lucky
    00066  *     InitEWEvent has been changed to include optional allocation of
    00067  *     pChanInfo space. This must be optional because GetEWEventInfo mallocs
    00068  *     space on the fly.
    00069  *
    00070  *     Revision 1.3  2000/08/28 15:41:10  lucky
    00071  *     get_EW_event_info.h -> EW_event_info.h
    00072  *
    00073  *     Revision 1.2  2000/08/25 18:23:42  lucky
    00074  *     Made to work with P and S waves, as well as the new pChanInfo struct.
    00075  *
    00076  *     Revision 1.1  2000/08/16 17:18:11  lucky
    00077  *     Initial revision
    00078  *
    00079  *     Revision 1.13  2000/06/29 17:24:42  lucky
    00080  *     Added to Sac2EWEvent the translation of the coda duration from the sac header.
    00081  *     The coda duration is written to EW structs.
    00082  *
    00083  *     Revision 1.12  2000/06/28 22:53:07  lucky
    00084  *     Increased the maximum number of Phases per event to 1000 to accomodate
    00085  *     extremely large Dewey-type events.
    00086  *     If BuildPhs fails, we record the failure, but do not exit. This way,
    00087  *     even if one arrival writing fails we still get the remaining ones
    00088  *     in the arc message.
    00089  *
    00090  *     Revision 1.11  2000/06/28 22:22:34  lucky
    00091  *     Added a check in EWEvent2ArcMsg so that only the arrival-type channels
    00092  *     are written to Arc message. Recall:channels may be arrivals, station
    00093  *     magnitudes, or even just waveform data.
    00094  *
    00095  *     Revision 1.10  2000/06/26 18:14:42  lucky
    00096  *     Fixed creation of hypoinverse arc files with NSN locations.
    00097  *
    00098  *     Revision 1.9  2000/06/22 23:29:11  lucky
    00099  *     Fixed BuildPhs to work with USNSN messages'
    00100  *
    00101  *     Revision 1.8  2000/06/20 21:42:51  lucky
    00102  *     *** empty log message ***
    00103  *
    00104  *     Revision 1.7  2000/06/16 17:23:36  lucky
    00105  *     Set tObsPhase to be same as tCalcPhase when read from sac headers.
    00106  *
    00107  *     Revision 1.6  2000/06/13 19:05:58  lucky
    00108  *     Fixed to work with the new hypo2ora, as well as the review stuff.
    00109  *
    00110  *     Revision 1.5  2000/06/07 22:09:52  lucky
    00111  *     Added ArcMsg2EWEvent calls
    00112  *
    00113  *
    00114  *     Revision 1.1  2000/02/14 18:51:48  lucky
    00115  *     Initial revision
    00116  *
    00117  *
    00118  */
    00119
    00120
    00121 #include <stdio.h>
    00122 #include <stdlib.h>
    00123 #include <string.h>
    00124 #include <errno.h>
    00125 #include <sys/types.h>
    00126 #include <earthworm.h>
    00127 #include <ws_clientII.h>
    00128 #include <chron3.h>
    00129 #include <ewdb_ora_api.h>
    00130 #include <ew_event_info.h>
    00131 #include <read_arc.h>
    00132
    00133
    00134 /* Define max lengths of various lines in the Hypoinverse archive format
    00135    (includes space for a newline & null-terminator on each line )
    00136  ************************************************************************/
    00137 #define ARC_HYP_LEN   500
    00138 #define ARC_SHYP_LEN  500
    00139 #define ARC_PHS_LEN   500
    00140 #define ARC_SPHS_LEN  500
    00141 #define ARC_TRM_LEN    74
    00142 #define ARC_STRM_LEN   74
    00143
    00144
    00145 /* Define some simple "functions"
    00146  ********************************/
    00147 #ifndef MIN
    00148 #define MIN(a,b) (((a)<(b)) ? (a) : (b))        /* Smaller value  */
    00149 #endif
    00150 #ifndef ABS
    00151 #define ABS(a) ((a) > 0 ? (a) : -(a))           /* Absolute value */
    00152 #endif
    00153
    00154
    00155 extern          time_t timegm_ew (struct tm *);
    00156
    00157 int     EWEvent2ArcMsg (EWEventInfoStruct *, char *, int);
    00158 int             BuildHyp (EWEventInfoStruct *, char *, int);
    00159 int             BuildPhs (EWEventInfoStruct *, int, char *, int);
    00160 int             BuildTerm (int, char *, int);
    00161
    00162
    00163
    00164
    00165
    00166
    00167 /********************************************************
    00168 *
    00169 *  EWEvent2ArcMsg:
    00170 *     Creates a Hypoinverse Archive message, stored in
    00171 *     string pArc, from the data passed in the
    00172 *     pEWEvent structure and its substructures.
    00173 *
    00174 *
    00175 *      Returns EW_SUCCESS if everything went OK,
    00176 *       EW_FAILURE otherwise.
    00177 *
    00178 *
    00179 *   Author: Lucky Vidmar    04/2000
    00180 *
    00181 ********************************************************/
    00182 int     EWEvent2ArcMsg (EWEventInfoStruct *pEWEvent, char *pArc, int ArcLen)
    00183 {
    00184
    00185         int             i;
    00186
    00187         if ((pEWEvent == NULL) || (pArc == NULL) || (ArcLen < 0))
    00188         {
    00189                 logit ("", "Invalid arguments passed in.\n");
    00190                 return EW_FAILURE;
    00191         }
    00192
    00193         if (BuildHyp (pEWEvent, pArc, ArcLen) != EW_SUCCESS)
    00194         {
    00195                 logit ("", "Call to BuildHyp failed.\n");
    00196                 return EW_FAILURE;
    00197         }
    00198
    00199         for (i = 0; i < pEWEvent->iNumChans; i++)
    00200         {
    00201                 if (pEWEvent->pChanInfo[i].iNumArrivals > 0)
    00202                 {
    00203                         if (BuildPhs (pEWEvent, i, pArc, ArcLen) != EW_SUCCESS)
    00204                         {
    00205                                 logit ("", "Call to BuildPhs failed for channel %d.\n", i);
    00206                         }
    00207                 }
    00208         }
    00209
    00210         if (BuildTerm (pEWEvent->PrefOrigin.idEvent, pArc, ArcLen) != EW_SUCCESS)
    00211         {
    00212                 logit ("", "Call to BuildTerm failed.\n");
    00213                 return EW_FAILURE;
    00214         }
    00215
    00216         return EW_SUCCESS;
    00217
    00218 }
    00219
    00220
    00221 /********************************************************
    00222 *
    00223 *  ArcMsg2EWEvent:
    00224 *     Given a Hypoinverse Archive message stored in
    00225 *     string pArc, fill the pEWEvent structure
    00226 *     and its substructures.
    00227 *
    00228 *
    00229 *      Returns EW_SUCCESS if everything went OK,
    00230 *       EW_FAILURE otherwise.
    00231 *
    00232 *
    00233 *   Author: Lucky Vidmar    06/2000
    00234 *
    00235 ********************************************************/
    00236 int     ArcMsg2EWEvent (EWEventInfoStruct *pEWEvent, char *pArc, int ArcLen)
    00237 {
    00238
    00239         int                                     j, rc, index;
    00240         int                                     nline, tmp, toalloc;
    00241         char                            *in;
    00242         char                            line[ARC_HYP_LEN];
    00243         char                            shdw[ARC_SHYP_LEN];
    00244         EWDB_EventStruct        *pEvent;
    00245         EWDB_OriginStruct       *pOrigin;
    00246         EWDB_MagStruct          *pMagnitude;
    00247         EWDB_ArrivalStruct      *pArrival;
    00248         EWDB_StationMagStruct   *pStaMag;
    00249         EWDB_StationStruct      *pStation;
    00250   EWChannelDataStruct   *pOldChan;
    00251         struct Hsum             HSum;
    00252         struct Hpck             HPck;
    00253         /* EWDB_CodaAmplitudeStruct     *pCodaAmp; */
    00254
    00255
    00256         if ((pEWEvent == NULL) || (pArc == NULL) || (ArcLen <= 0))
    00257         {
    00258                 logit ("", "ArcMsg2EWEvent: Invalid arguments passed in.\n");
    00259                 return EW_FAILURE;
    00260         }
    00261
    00262
    00263         /* Initialize the Event structure */
    00264         if (InitEWEvent (pEWEvent) != EW_SUCCESS)
    00265         {
    00266                 logit ("", "Call to InitEWEvent failed.\n");
    00267                 return EW_FAILURE;
    00268         }
    00269
    00270
    00271         /* Initialize other stuff
    00272          ***********************/
    00273         nline  = 0;
    00274         in     = pArc;
    00275
    00276         memset (&HSum, 0, sizeof (struct Hsum));
    00277
    00278         pEvent = &pEWEvent->Event;
    00279         memset (pEvent, 0, sizeof (EWDB_EventStruct));
    00280         pEWEvent->iNumChans = 0;
    00281
    00282
    00283         pOrigin = &pEWEvent->PrefOrigin;
    00284         memset (pOrigin, 0, sizeof (EWDB_OriginStruct));
    00285
    00286         pMagnitude = &pEWEvent->Mags[0];
    00287         memset (pMagnitude, 0, sizeof (EWDB_MagStruct));
    00288
    00289
    00290         /* Read one data line and its shadow at a time from arcmsg; process them
    00291          ***********************************************************************/
    00292         index = 0;
    00293         while (index < ArcLen)
    00294         {
    00295                 j = 0;
    00296         while (in[index] != '\n')
    00297         {
    00298             line[j] = in[index];
    00299             index = index + 1;
    00300             j = j + 1;
    00301         }
    00302         if (in[index] == '\n')
    00303         {
    00304             line[j] = '\0';
    00305         }
    00306                 else
    00307                 {
    00308                         logit ("", "Max hyp length reached without newline\n");
    00309                         return EW_FAILURE;
    00310                 }
    00311
    00312                 j = 0;
    00313                 index = index + 1;
    00314         while ((in[index] != '\n') && (j <  ARC_SPHS_LEN))
    00315         {
    00316             shdw[j] = in[index];
    00317             index = index + 1;
    00318             j = j + 1;
    00319         }
    00320         if (in[index] == '\n')
    00321         {
    00322             shdw[j] = '\0';
    00323         }
    00324                 else
    00325                 {
    00326                         logit ("", "Max hyp length reached without newline\n");
    00327                         break;
    00328                 }
    00329
    00330                 index = index + 1;
    00331
    00332                 nline++;
    00333
    00334                 /* Process the hypocenter card (1st line of msg) & its shadow
    00335                 ************************************************************/
    00336                 if (nline == 1)
    00337                 {                  /* hypocenter */
    00338                         rc = read_hyp (line, NULL, &HSum);
    00339
    00340                         pEvent->idEvent=HSum.qid;
    00341
    00342                         /* Fill in the Origin Struct */
    00343                         pOrigin->BindToEvent = TRUE;
    00344                         pOrigin->idEvent = pEvent->idEvent;
    00345                         pOrigin->SetPreferred = TRUE;
    00346                         pOrigin->tOrigin = HSum.ot - GSEC1970;
    00347
    00348                         pOrigin->dLat = HSum.lat;
    00349                         pOrigin->dLon = HSum.lon;
    00350                         pOrigin->dDepth = HSum.z;
    00351                         pOrigin->dErrLat = HSum.erh;
    00352                         pOrigin->dErrLon = HSum.erh;
    00353                         pOrigin->dErZ = HSum.erz;
    00354                         pOrigin->iGap = HSum.gap;
    00355                         pOrigin->dDmin = (float)(HSum.dmin);
    00356                         pOrigin->dRms = HSum.rms;
    00357                         pOrigin->iUsedPh = HSum.nph;
    00358                         pOrigin->iE1Azm = HSum.e1az;
    00359                         pOrigin->iE1Dip = HSum.e1dp;
    00360                         pOrigin->iE2Azm = HSum.e0az;
    00361                         pOrigin->iE2Dip = HSum.e0dp;
    00362                         pOrigin->dE0 = HSum.e0;
    00363                         pOrigin->dE1 = HSum.e1;
    00364                         pOrigin->dE2 = HSum.e2;
    00365                         pOrigin->iFixedDepth = FALSE;
    00366
    00367
    00368                         /* Since the Event/Origin insert succeeded,
    00369                            insert the associated Magnitude
    00370                            *******************************************/
    00371
    00372                         /* Fill in the Magnitude Struct */
    00373                         pMagnitude->iMagType = MAGTYPE_DURATION;
    00374                         pMagnitude->dMagAvg  = HSum.Md;
    00375                         pMagnitude->iNumMags = (int)(HSum.mdwt + 0.9);
    00376                         pMagnitude->dMagErr  = HSum.mdmad;
    00377                         pMagnitude->idEvent  = pEvent->idEvent;
    00378                         pMagnitude->bBindToEvent = TRUE;
    00379                         pMagnitude->bSetPreferred = TRUE;
    00380
    00381                         pEWEvent->iNumMags = 1;
    00382                         pEWEvent->iPrefMag = 0;
    00383                         pEWEvent->iMd = 0;
    00384
    00385                 }
    00386                 else
    00387                 {
    00388                         /* Process all the phase cards & their shadows
    00389                            *********************************************/
    00390                         if (strlen (line) < (size_t) 75)  /* found the terminator line      */
    00391                                 break;
    00392
    00393                         /* re-blank the pick struct */
    00394                         memset (&HPck, 0, sizeof (struct Hpck));
    00395
    00396                         if (pEWEvent->iNumChans >= pEWEvent->iNumAllocChans)
    00397                         {
    00398
    00399                                 toalloc = (int) (pEWEvent->iNumAllocChans + CHAN_ALLOC_INCR);
    00400
    00401                                 logit ("", "Max Channels (%d) reached. Alloc to %d\n",
    00402                                                                                                 pEWEvent->iNumAllocChans, toalloc);
    00403
    00404                                 pOldChan = pEWEvent->pChanInfo;
    00405                                 if ((pEWEvent->pChanInfo = (EWChannelDataStruct *) malloc
    00406                                                                 (toalloc * sizeof (EWChannelDataStruct))) == NULL)
    00407                                 {
    00408                                         logit ("",  "Could not malloc %d pChanInfo entries.\n", toalloc);
    00409                                         return  (EW_FAILURE);
    00410                                 }
    00411
    00412                                 memcpy (pEWEvent->pChanInfo, pOldChan,
    00413                                                 (pEWEvent->iNumAllocChans * sizeof (EWChannelDataStruct)));
    00414
    00415                                 for (tmp = pEWEvent->iNumChans; tmp < toalloc; tmp++)
    00416                                         InitEWChan(&pEWEvent->pChanInfo[tmp]);
    00417
    00418                                 pEWEvent->iNumAllocChans = toalloc;
    00419
    00420                                 free (pOldChan);
    00421                         }
    00422
    00423
    00424
    00425                         /* load info into Pck structure   */
    00426                         rc = read_phs (line, shdw, &HPck);
    00427
    00428                         pEWEvent->pChanInfo[pEWEvent->iNumChans].iNumArrivals = 0;
    00429                         pEWEvent->pChanInfo[pEWEvent->iNumChans].iNumStaMags = 0;
    00430
    00431                         pStation = &pEWEvent->pChanInfo[pEWEvent->iNumChans].Station;
    00432                         memset(pStation, 0, sizeof(EWDB_StationStruct));
    00433
    00434
    00435                         /* Fill in the common information */
    00436                         strncpy (pStation->Sta, HPck.site, sizeof (pStation->Sta)-1);
    00437                         strncpy (pStation->Comp, HPck.comp, sizeof (pStation->Comp)-1);
    00438                         strncpy (pStation->Net, HPck.net, sizeof (pStation->Net)-1);
    00439
    00440                         /* Do we have a P-pick?? */
    00441                         if ((HPck.Plabel == 'P') || (HPck.Plabel == 'p'))
    00442                         {
    00443                                 /* Fill in the P-pick information */
    00444
    00445                                 rc = pEWEvent->pChanInfo[pEWEvent->iNumChans].iNumArrivals;
    00446
    00447                                 pArrival = &pEWEvent->pChanInfo[pEWEvent->iNumChans].Arrivals[rc];
    00448                                 memset(pArrival, 0, sizeof(EWDB_ArrivalStruct));
    00449
    00450                                 pStaMag = &pEWEvent->pChanInfo[pEWEvent->iNumChans].Stamags[rc];
    00451                                 memset(pStaMag, 0, sizeof(EWDB_StationMagStruct));
    00452
    00453
    00454                                 /* Fill in the Arrival record */
    00455                                 pArrival->idOrigin = pOrigin->idOrigin;
    00456
    00457                                 pArrival->tObsPhase = HPck.Pat -  GSEC1970;
    00458                                 pArrival->tCalcPhase = pArrival->tObsPhase - HPck.Pres;
    00459
    00460                                 if (pArrival->dWeight > 1000.0)
    00461                                         pArrival->dWeight = 0.0;
    00462
    00463                                 pArrival->dAzm = (float) HPck.azm;
    00464                                 pArrival->dTakeoff = (float) HPck.takeoff;
    00465                                 pArrival->tResPick = HPck.Pres;
    00466                                 pArrival->szObsPhase[0] = 'P';
    00467                                 pArrival->cMotion = HPck.Pfm;
    00468                                 pArrival->cOnset = HPck.Ponset;
    00469                                 pArrival->dDist = HPck.dist;
    00470                                 pArrival->dWeight = HPck.Pwt;
    00471
    00472                                 if (HPck.Pqual == 3)
    00473                                         pArrival->dSigma = 0.08;
    00474                                 else if (HPck.Pqual == 2)
    00475                                         pArrival->dSigma = 0.05;
    00476                                 else if (HPck.Pqual == 1)
    00477                                         pArrival->dSigma = 0.03;
    00478                                 else if (HPck.Pqual == 0)
    00479                                         pArrival->dSigma = 0.02;
    00480                                 else
    00481                                         pArrival->dSigma = 99.99;
    00482
    00483                                 /* create phase label */
    00484                                 sprintf (pArrival->szCalcPhase, "P");
    00485
    00486                                 pStaMag->idChan = pArrival->idChan;
    00487                                 pStaMag->StaMagUnion.CodaDur.idPick = pArrival->idPick;
    00488                                 pStaMag->idMagnitude = pMagnitude->idMag;
    00489                                 pStaMag->iMagType = MAGTYPE_DURATION;
    00490                                 pStaMag->dMag = HPck.Md;
    00491                                 pStaMag->dWeight = (float) HPck.codawt;
    00492                                 pStaMag->StaMagUnion.CodaDur.tCodaTermObs = pArrival->tObsPhase + HPck.codalenObs;
    00493                                 pStaMag->StaMagUnion.CodaDur.tCodaTermXtp = pArrival->tObsPhase + HPck.codalen;
    00494
    00495                                 pEWEvent->pChanInfo[pEWEvent->iNumChans].iNumArrivals =
    00496                                         pEWEvent->pChanInfo[pEWEvent->iNumChans].iNumArrivals + 1;
    00497
    00498                                 pEWEvent->pChanInfo[pEWEvent->iNumChans].iNumStaMags =
    00499                                         pEWEvent->pChanInfo[pEWEvent->iNumChans].iNumStaMags + 1;
    00500
    00501                         }
    00502
    00503                         /* Do we have an S-pick */
    00504                         if ((HPck.Slabel == 'S') || (HPck.Slabel == 's'))
    00505                         {
    00506
    00507                                 /* Fill in the S-pick information */
    00508
    00509                                 rc = pEWEvent->pChanInfo[pEWEvent->iNumChans].iNumArrivals;
    00510
    00511                                 pArrival = &pEWEvent->pChanInfo[pEWEvent->iNumChans].Arrivals[rc];
    00512                                 memset(pArrival, 0, sizeof(EWDB_ArrivalStruct));
    00513
    00514                                 pStaMag = &pEWEvent->pChanInfo[pEWEvent->iNumChans].Stamags[rc];
    00515                                 memset(pStaMag, 0, sizeof(EWDB_StationMagStruct));
    00516
    00517                                 /* pPhaseAmp = &pEWEvent->pChanInfo[pEWEvent->iNumChans].PhaseAmps[rc];
    00518                                  * memset(pPhaseAmp, 0, sizeof(EWDB_PhaseAmpStruct)); */
    00519
    00520                                 /* Fill in the Arrival record */
    00521                                 pArrival->idOrigin = pOrigin->idOrigin;
    00522
    00523                                 pArrival->tObsPhase = HPck.Sat -  GSEC1970;
    00524                                 pArrival->tCalcPhase = pArrival->tObsPhase - HPck.Sres;
    00525
    00526                                 if (pArrival->dWeight > 1000.0)
    00527                                         pArrival->dWeight = 0.0;
    00528
    00529                                 pArrival->dAzm = (float) HPck.azm;
    00530                                 pArrival->dTakeoff = (float) HPck.takeoff;
    00531                                 pArrival->tResPick = HPck.Sres;
    00532                                 pArrival->szObsPhase[0] = 'S';
    00533                                 pArrival->cMotion = HPck.Sfm;
    00534                                 pArrival->cOnset = HPck.Sonset;
    00535                                 pArrival->dDist = HPck.dist;
    00536                                 pArrival->dWeight = HPck.Swt;
    00537
    00538                                 if (HPck.Squal == 3)
    00539                                         pArrival->dSigma = 0.08;
    00540                                 else if (HPck.Squal == 2)
    00541                                         pArrival->dSigma = 0.05;
    00542                                 else if (HPck.Squal == 1)
    00543                                         pArrival->dSigma = 0.03;
    00544                                 else if (HPck.Squal == 0)
    00545                                         pArrival->dSigma = 0.02;
    00546                                 else
    00547                                         pArrival->dSigma = 99.99;
    00548
    00549                                 /* create phase label */
    00550                                 sprintf (pArrival->szCalcPhase, "S");
    00551
    00552         /* This is horse pucky, you can't have a duration magnitude calc'd off
    00553            an S wave!  CLEANUP! DavidK */
    00554                                 pStaMag->idChan = pArrival->idChan;
    00555                                 pStaMag->StaMagUnion.CodaDur.idPick = pArrival->idPick;
    00556                                 pStaMag->idMagnitude = pMagnitude->idMag;
    00557                                 pStaMag->iMagType = MAGTYPE_DURATION;
    00558                                 pStaMag->dMag = HPck.Md;
    00559                                 pStaMag->dWeight = (float) HPck.codawt;
    00560                                 pStaMag->StaMagUnion.CodaDur.tCodaTermObs = pArrival->tObsPhase + HPck.codalenObs;
    00561                                 pStaMag->StaMagUnion.CodaDur.tCodaTermXtp = pArrival->tObsPhase + HPck.codalen;
    00562
    00563                                 pEWEvent->pChanInfo[pEWEvent->iNumChans].iNumArrivals =
    00564                                         pEWEvent->pChanInfo[pEWEvent->iNumChans].iNumArrivals + 1;
    00565
    00566                                 pEWEvent->pChanInfo[pEWEvent->iNumChans].iNumStaMags =
    00567                                         pEWEvent->pChanInfo[pEWEvent->iNumChans].iNumStaMags + 1;
    00568
    00569                         }
    00570
    00571
    00572                         pEWEvent->iNumChans = pEWEvent->iNumChans + 1;
    00573
    00574                 }   /* else(line==1) */
    00575
    00576         } /*end while over reading message*/
    00577
    00578         return EW_SUCCESS;
    00579
    00580 }
    00581
    00582
    00583 /***************************************************************
    00584  * BuildHyp () builds a hypoinverse summary card & its shadow  *
    00585  ***************************************************************/
    00586 int             BuildHyp (EWEventInfoStruct *pEvent, char *arcmsg, int maxlen)
    00587 {
    00588
    00589         char            line[ARC_HYP_LEN];   /* temporary working place */
    00590         char            shdw[ARC_SHYP_LEN];  /* temporary shadow card   */
    00591         struct tm       *otm;
    00592         time_t          ott;
    00593         int             tmp;
    00594         int             i;
    00595         EWDB_OriginStruct       *pOrig;
    00596         EWDB_MagStruct          *pMag;
    00597
    00598
    00599         if ((pEvent == NULL) || (arcmsg == NULL))
    00600         {
    00601                 fprintf (stderr, "Invalid arguments passed in.\n");
    00602                 return EW_FAILURE;
    00603         }
    00604
    00605
    00606         if ((pOrig = &(pEvent->PrefOrigin)) == NULL)
    00607         {
    00608                 fprintf (stderr, "Invalid pEvent -- can't get PrefOrigin.\n");
    00609                 return EW_FAILURE;
    00610         }
    00611
    00612         if ((pMag = &(pEvent->Mags[pEvent->iPrefMag])) == NULL)
    00613         {
    00614                 fprintf (stderr, "Invalid pEvent -- can't get Pref Magnitude.\n");
    00615                 return EW_FAILURE;
    00616         }
    00617
    00618 /* Put all blanks into line and shadow card
    00619  ******************************************/
    00620    for (i = 0; i < ARC_HYP_LEN; i++)
    00621                 line[i] = ' ';
    00622
    00623    for (i = 0; i < ARC_SHYP_LEN; i++)
    00624                 shdw[i] = ' ';
    00625
    00626 /*----------------------------------------------------------------------------------
    00627 Sample HYPOINVERSE 2000 hypocenter and shadow card.  Event id from binder is stored in
    00628   cols 129-138.  Many fields are blank due to lack of information from binder.
    00629   (summary is 165 chars, including newline; shadow is 95 chars, including newline):
    00630 199912312359492936 2810120 2596  851    27 78 19  15                                                                                         10154                1 \n
    00631 $1                                                                              \n
    00632 0123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123
    00633 -----------------------------------------------------------------------------------*/
    00634
    00635         /* Origin time
    00636          *************/
    00637         ott = (time_t) pOrig->tOrigin;
    00638         otm = gmtime( &ott );
    00639
    00640         sprintf( line, "%04d%02d%02d%02d%02d%02d%02d",
    00641               (otm->tm_year + 1900),
    00642               otm->tm_mon+1,
    00643               otm->tm_mday,
    00644               otm->tm_hour,
    00645               otm->tm_min,
    00646               otm->tm_sec,
    00647               (int)((pOrig->tOrigin-(double)ott+.005)*100.) );
    00648         line[16]=' ';
    00649
    00650         /* Latitude, convert from decimal degrees to degrees/minutes*100 */
    00651         if (pOrig->dLat >= 0)
    00652                 sprintf (line+16, "%2d ",  (int)pOrig->dLat);
    00653         else
    00654                 sprintf (line+16, "%2d%c", -(int)pOrig->dLat, 'S');
    00655
    00656         tmp = (int) ((pOrig->dLat - (int)pOrig->dLat) * 6000.);
    00657         sprintf( line+19,  "%4d",     (int) MIN( ABS(tmp), 9999 ));
    00658         line[23]=' ';
    00659
    00660         /* Longitude, convert from decimal degrees to degrees/minutes*100 */
    00661         if (pOrig->dLon >= 0)
    00662                 sprintf( line+23, "%2d%c",  (int)pOrig->dLon, 'E' );
    00663         else
    00664                 sprintf( line+23, "%2d ", (int) (-1.0 * pOrig->dLon));
    00665     line[26] = ' ';
    00666
    00667         tmp = (int)( (pOrig->dLon - (int)pOrig->dLon) * 6000.);
    00668         sprintf( line+27, "%4d", (int) MIN( ABS(tmp), 9999 ) );
    00669         line[31]=' ';
    00670
    00671         /* Depth */
    00672         if (pOrig->dDepth != 0.0)
    00673         {
    00674                 tmp = (int) (pOrig->dDepth * 100.0);
    00675                 sprintf( line+31,  "%5d", (int) MIN( ABS(tmp), 99999 ) );
    00676                 line[36]=' ';
    00677         }
    00678
    00679
    00680         /* All the other stuff */
    00681
    00682         if (pOrig->iUsedPh != 0)
    00683         {
    00684                 sprintf( line+39, "%3d", (int) MIN( pOrig->iUsedPh, 999 ) );
    00685                 line[42] = ' ';
    00686         }
    00687
    00688         if (pOrig->iGap != 0)
    00689         {
    00690                 sprintf( line+42, "%3d", (int) MIN( pOrig->iGap, 999 ) );
    00691                 line[45] = ' ';
    00692         }
    00693
    00694         if (pOrig->dDmin != 0.0)
    00695         {
    00696                 sprintf( line+45, "%3d", (int) MIN( pOrig->dDmin, 999 ) );
    00697                 line[48] = ' ';
    00698         }
    00699
    00700         if (pOrig->dRms != 0.0)
    00701         {
    00702                 tmp = (int) (pOrig->dRms*100.);
    00703                 sprintf( line+48,  "%4d", (int) MIN( tmp, 9999 ) );
    00704                 line[52]  = ' ';
    00705         }
    00706
    00707         /* azimuth of largest principal error */
    00708         if (pOrig->iE2Azm != 0.0)
    00709         {
    00710                 sprintf( line+52,  "%3d", (int) MIN( pOrig->iE2Azm, 999 ) );
    00711                 line[55]  = ' ';
    00712         }
    00713
    00714         /* dip of largest principal error  */
    00715         if (pOrig->iE2Dip != 0.0)
    00716         {
    00717                 sprintf( line+55,  "%2d", (int) MIN( pOrig->iE2Dip, 99 ) );
    00718                 line[57]  = ' ';
    00719         }
    00720
    00721         /* magnitude (km) of largest principal error */
    00722         if (pOrig->dE0 != 0.0)
    00723         {
    00724                 tmp = (int) (pOrig->dE0 * 100.);
    00725                 sprintf( line+57,  "%4d", (int) MIN( tmp, 9999 ) );
    00726                 line[61]  = ' ';
    00727         }
    00728
    00729         /* azimuth of intermediate principal error */
    00730         if (pOrig->iE1Azm != 0.0)
    00731         {
    00732                 sprintf( line+61,  "%3d", (int) MIN( pOrig->iE1Azm, 999 ) );
    00733                 line[64]  = ' ';
    00734         }
    00735
    00736         /* dip of intermediate principal error  */
    00737         if (pOrig->iE1Dip != 0.0)
    00738         {
    00739                 sprintf( line+64,  "%2d", (int) MIN( pOrig->iE1Dip, 99 ) );
    00740                 line[66]  = ' ';
    00741         }
    00742
    00743         /* magnitude (km) of intermed principal error */
    00744         if (pOrig->dE1 != 0.0)
    00745         {
    00746                 tmp = (int) (pOrig->dE1 * 100.);
    00747                 sprintf( line+66,  "%4d", (int) MIN( tmp, 9999 ) );
    00748                 line[70]  = ' ';
    00749         }
    00750
    00751
    00752         if (pMag->dMagAvg != 0.0)
    00753         {
    00754                 tmp = (int) (pMag->dMagAvg*100.);
    00755                 sprintf( line+70,  "%3d", (int) MIN (tmp, 999));
    00756                 line[73]  = ' ';
    00757         }
    00758
    00759
    00761         sprintf (line+73, "   ");
    00762         line[76] = ' ';
    00763
    00764
    00765         /* magnitude (km) of smallest principal error */
    00766         if (pOrig->dE2 != 0.0)
    00767         {
    00768                 tmp = (int) (pOrig->dE2 * 100.);
    00769                 sprintf( line+76,  "%4d", (int) MIN( tmp, 9999 ) );
    00770                 line[80]  = ' ';
    00771         }
    00772
    00773         if (pOrig->dErrLon != 0.0)
    00774         {
    00775                 tmp = (int) (pOrig->dErrLon*100.);
    00776                 sprintf( line+85,  "%4d", (int) MIN( tmp, 9999 ) );
    00777                 line[89]  = ' ';
    00778         }
    00779
    00780         if (pOrig->dErZ != 0.0)
    00781         {
    00782                 tmp = (int) (pOrig->dErZ*100.);
    00783                 sprintf( line+89,  "%4d", (int) MIN( tmp, 9999 ) );
    00784                 line[93]  = ' ';
    00785         }
    00786
    00787         if (pMag->iNumMags != 0)
    00788         {
    00789                 sprintf( line+100, "%4d", (int) MIN (pMag->iNumMags, 9999));
    00790                 line[104] = ' ';
    00791         }
    00792
    00793         if (pMag->dMagErr != 0)
    00794         {
    00795                 sprintf( line+107, "%3d", (int) MIN (pMag->dMagErr, 999));
    00796                 line[110] = ' ';
    00797         }
    00798
    00799
    00800         if (pEvent->Event.idEvent != 0)
    00801         {
    00802                 sprintf( line+136, "%10ld",   pEvent->Event.idEvent);
    00803                 line[146] = ' ';
    00804         }
    00805
    00806
    00807         sprintf (line+164, "\n\0");
    00808
    00809 /* Write out summary shadow card
    00810  *******************************/
    00811         sprintf( shdw,     "$1");
    00812         shdw[2]= ' ';
    00813         sprintf (shdw+94,  "\n\0");
    00814
    00815 /* Copy both to the target address if there's room
    00816  *************************************************/
    00817         if ((strlen (arcmsg) + strlen (line) + strlen (shdw) + 1) > (size_t)maxlen )
    00818         {
    00819                 fprintf (stderr, "Max arcmsg length exceeded\n");
    00820                 return EW_FAILURE;
    00821         }
    00822
    00823         strcpy (arcmsg, line);
    00824         strcat (arcmsg, shdw);
    00825
    00826         return EW_SUCCESS;
    00827
    00828 }
    00829
    00830
    00831
    00832
    00833 /***********************************************************************
    00834  * BuildPhs() builds a hypoinverse archive phase card & its shadow     *
    00835  ***********************************************************************/
    00836 int             BuildPhs (EWEventInfoStruct *pEvent, int NumPhs, char *arcmsg, int maxlen)
    00837 {
    00838
    00839         char            line[ARC_PHS_LEN];     /* temporary phase card    */
    00840         char            shdw[ARC_SPHS_LEN];    /* temporary shadow card   */
    00841         char            otime[50];
    00842         int             i, j;
    00843         struct tm       *otm;
    00844         time_t          ott;
    00845         int             tmpint, slen, clen, nlen, plen;
    00846         double          Cat;
    00847         EWDB_ArrivalStruct      *pArr;
    00848         EWDB_StationStruct      *pStation;
    00849         EWDB_StationMagStruct   *pStaMag;
    00850
    00851
    00852
    00853         if ((pEvent == NULL) || (NumPhs < 0) || (arcmsg == NULL))
    00854         {
    00855                 logit ("", "Invalid arguments passed in.\n");
    00856                 return EW_FAILURE;
    00857         }
    00858
    00859         if ((pStation = &pEvent->pChanInfo[NumPhs].Station) == NULL)
    00860         {
    00861                 logit ("", "Invalid EWEvent passed in -- can't get Station.\n");
    00862                 return EW_FAILURE;
    00863         }
    00864
    00865         /* Compute the common arrival time - yyyymmddhhmm */
    00866         ott = (time_t) pEvent->PrefOrigin.tOrigin;
    00867         otm = gmtime( &ott );
    00868
    00869         sprintf (otime, "%04d%02d%02d%02d%02d00.00",
    00870                             (otm->tm_year + 1900),
    00871                             otm->tm_mon+1,
    00872                             otm->tm_mday,
    00873                             otm->tm_hour,
    00874                             otm->tm_min);
    00875
    00876         epochsec17 (&Cat, otime);
    00877
    00878
    00879
    00880         /* Put all blanks into line and shadow card
    00881          ******************************************/
    00882         for( i=0; i<ARC_PHS_LEN; i++ )
    00883                 line[i] = ' ';
    00884
    00885         for (i = 0; i < pEvent->pChanInfo[NumPhs].iNumArrivals; i++)
    00886         {
    00887                 if ((pArr = &pEvent->pChanInfo[NumPhs].Arrivals[i]) == NULL)
    00888                 {
    00889                         logit ("", "Invalid EWEvent passed in -- can't get Arrivals.\n");
    00890                         return EW_FAILURE;
    00891                 }
    00892
    00893
    00894                 if ((pStaMag = &pEvent->pChanInfo[NumPhs].Stamags[i]) == NULL)
    00895                 {
    00896                         logit ("", "Invalid EWEvent passed in -- can't get StaMags.\n");
    00897                         return EW_FAILURE;
    00898                 }
    00899
    00900
    00901
    00902 /*----------------------------------------------------------------------------------------------------
    00903 Sample HYPOINVERSE station archive card and its shadow card.
    00904   Many fields are blank due to lack of information from binder.
    00905   (phase is 101 chars, including newline; shadow is 93 chars, including newline):
    00906 PWM  NC  VHZ  PD0199912312359 5341                                                0      77                 W  \n
    00907 0123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 1
    00908 $   6 5.49 1.80 7.91 3.30 0.10 PSN0   77 PHP3 1853 39 340 47 245 55 230 63  86 71  70 77  48           \n
    00909 -----------------------------------------------------------------------------------------------------*/
    00910
    00911
    00912
    00913                 plen = strlen (pArr->szObsPhase);
    00914                 slen = strlen (pStation->Sta);
    00915                 clen = strlen (pStation->Comp);
    00916                 nlen = strlen (pStation->Net);
    00917
    00918                 /* Fill in the common parts */
    00919
    00920                 /* Station site code */
    00921                 if (slen >= 5)
    00922                         strncpy (line, pStation->Sta, 5);
    00923                 else
    00924                         strncpy (line, pStation->Sta, slen );
    00925
    00926                 /* Network code */
    00927                 if (nlen >= 2)
    00928                         strncpy (line+5, pStation->Net, 2);
    00929                 else
    00930                         strncpy (line+5, pStation->Net, nlen);
    00931
    00932                 line[7] = ' ';
    00933
    00934                 /* Component Code */
    00935                 if (clen == 1)
    00936                         strncpy(line+8, pStation->Comp, clen);
    00937                 else
    00938                         line[8] = ' ';
    00939
    00940                 if (clen >= 3)
    00941                         strncpy (line+9, pStation->Comp, 3);
    00942                 else
    00943                         strncpy (line+9, pStation->Comp, clen);
    00944
    00945                 line[12] = ' ';
    00946
    00947                 /* Common time  - yyyymmddhhmm */
    00948                 sprintf (line+17, "%04d%02d%02d%02d%02d",
    00949                                                         (otm->tm_year + 1900),
    00950                                                         otm->tm_mon+1,
    00951                                                         otm->tm_mday,
    00952                                                         otm->tm_hour,
    00953                                                         otm->tm_min);
    00954                 line[29] = ' ';
    00955
    00956
    00957                 if ((pArr->szObsPhase[0] == 'P') || (pArr->szObsPhase[0] == 'p'))
    00958                 {
    00959                         /* Fill in the P-wave information */
    00960
    00961                         /* Make sure there's a pick
    00962                          **************************/
    00963                         if (pArr->tObsPhase == 0.0)
    00964                         {
    00965                                 logit ("", "No pick time found\n");
    00966                                 return EW_FAILURE;
    00967                         }
    00968
    00969                         /* P onset (if any) */
    00970                         if (pArr->cOnset != '\0' )
    00971                                 line[13] = pArr->cOnset;
    00972
    00973                         /* P label */
    00974                         line[14] = 'P';
    00975
    00976                         /* P first motion */
    00977                         if (pArr->cMotion != '\0' )
    00978                                 line[15] = pArr->cMotion;
    00979
    00980                         /* Assigned P weight code */
    00981                         if (pArr->dSigma >= 0)
    00982                         {
    00983                                 if (pArr->dSigma <= 0.02)
    00984                                         tmpint = 0;
    00985                                 else if (pArr->dSigma <= 0.03)
    00986                                         tmpint = 1;
    00987                                 else if (pArr->dSigma <= 0.05)
    00988                                         tmpint = 2;
    00989                                 else if (pArr->dSigma <= 0.08)
    00990                                         tmpint = 3;
    00991                                 else
    00992                                         tmpint = 4;
    00993
    00994                                 line[16] = tmpint + '0';
    00995                         }
    00996
    00997                         /* Seconds of P arrival */
    00998                         sprintf (line+29, "%5d", (int) (100.0 * (pArr->tObsPhase - Cat)));
    00999                         line[34] = ' ';
    01000
    01001                         /* P travel time residual */
    01002                         sprintf (line+34, "%4d", (int) MIN((100.0* pArr->tResPick), 9999));
    01003                         line[38] = ' ';
    01004
    01005                         /* P weight actually used */
    01006                         sprintf (line+38, "%3d", (int) MIN((100.0 * pArr->dWeight), 999));
    01007                         line[41] = ' ';
    01008
    01009                         /* epicentral distance */
    01010                         if (pArr->dDist != 0.0)
    01011                         {
    01012                                 sprintf (line+74, "%4d", (int) MIN((10.0 * pArr->dDist), 9999));
    01013                                 line[78] = ' ';
    01014                         }
    01015
    01016                         /* emergence angle at source */
    01017                         if (pArr->dTakeoff != 0.0)
    01018                         {
    01019                                 sprintf (line+78, "%3d", (int) MIN(pArr->dTakeoff, 999));
    01020                                 line[81] = ' ';
    01021                         }
    01022
    01023                         /* duration magnitude weight code */
    01024                         sprintf (line+82, "%1d", (int) MIN(pStaMag->dWeight, 9));
    01025                         line[83] = ' ';
    01026
    01027
    01028                         /* coda duration in seconds */
    01029                         if (pStaMag->StaMagUnion.CodaDur.tCodaDurXtp != 0.0)
    01030                         {
    01031                                 sprintf( line+87,  "%4d", (int) MIN(pStaMag->StaMagUnion.CodaDur.tCodaDurXtp, 9999 ) );
    01032                                 line[91] = ' ';
    01033                         }
    01034
    01035                         /* azimuth to station */
    01036                         if (pArr->dAzm != 0.0)
    01037                         {
    01038                                 sprintf (line+91, "%3d", (int) MIN(pArr->dAzm, 999));
    01039                                 line[94] = ' ';
    01040                         }
    01041
    01042                         /* duration magnitude for this station */
    01043                         if (pStaMag->dMag != 0.0)
    01044                         {
    01045                                 sprintf (line+94, "%3d", (int) MIN((100.0* pStaMag->dMag), 999));
    01046                                 line[97] = ' ';
    01047                         }
    01048
    01049                         /* data source code */
    01050                         sprintf( line+108,  "%c",   ' ');
    01051                         line[109] = ' ';
    01052
    01053                         sprintf( line+111, "\n\0" );
    01054
    01055
    01056
    01057                         /* Build the shadow card
    01058                          ***********************/
    01059                         for( j=0; j<ARC_SPHS_LEN; j++ )
    01060                                 shdw[j] = ' ';
    01061
    01062                         strncpy (shdw, "$", 1);
    01063
    01064                         if (pStaMag->StaMagUnion.CodaDur.tCodaDurXtp != 0.0)
    01065                         {
    01066                                 sprintf (shdw+35, "%5d",  (int) MIN( pStaMag->StaMagUnion.CodaDur.tCodaDurXtp, 99999 ) );
    01067                                 shdw[40] = ' ';
    01068                         }
    01069
    01070                         sprintf (shdw+92, "\n\0");
    01071
    01072                 }
    01073                 else if ((pArr->szObsPhase[0] == 'S') || (pArr->szObsPhase[0] == 's'))
    01074                 {
    01075
    01076                         /* Fill in the S-wave information */
    01077
    01078                         /* Make sure there's a pick
    01079                          **************************/
    01080                         if (pArr->tObsPhase == 0.0)
    01081                         {
    01082                                 logit ("", "No pick time found\n");
    01083                                 return EW_FAILURE;
    01084                         }
    01085
    01086                         /* Seconds of S arrival */
    01087                         sprintf (line+41, "%5d", (int) (100.0 * (pArr->tObsPhase - Cat)));
    01088                         line[41+5] = ' ';
    01089
    01090                         /* S onset (if any) */
    01091                         if (pArr->cOnset != '\0' )
    01092                                 line[46] = pArr->cOnset;
    01093
    01094                         /* S label */
    01095                         line[47] = 'S';
    01096
    01097                         /* blank  (first motion???) */
    01098                         line[48] = ' ';
    01099
    01100                         /* Assigned S weight code */
    01101                         if (pArr->dSigma >= 0)
    01102                         {
    01103                                 if (pArr->dSigma <= 0.02)
    01104                                         tmpint = 0;
    01105                                 else if (pArr->dSigma <= 0.03)
    01106                                         tmpint = 1;
    01107                                 else if (pArr->dSigma <= 0.05)
    01108                                         tmpint = 2;
    01109                                 else if (pArr->dSigma <= 0.08)
    01110                                         tmpint = 3;
    01111                                 else
    01112                                         tmpint = 4;
    01113
    01114                                 line[49] = tmpint + '0';
    01115                         }
    01116
    01117
    01118                         /* S travel time residual */
    01119                         sprintf (line+50, "%4d", (int) MIN((100.0* pArr->tResPick), 9999));
    01120                         line[50+4] = ' ';
    01121
    01122                         /* S weight actually used */
    01123                         sprintf (line+63, "%3d", (int) MIN((100.0 * pArr->dWeight), 999));
    01124                         line[63+3] = ' ';
    01125
    01126                         /* epicentral distance */
    01127                         if (pArr->dDist != 0.0)
    01128                         {
    01129                                 sprintf (line+74, "%4d", (int) MIN((10.0 * pArr->dDist), 9999));
    01130                                 line[78] = ' ';
    01131                         }
    01132
    01133                         /* emergence angle at source */
    01134                         if (pArr->dTakeoff != 0.0)
    01135                         {
    01136                                 sprintf (line+78, "%3d", (int) MIN(pArr->dTakeoff, 999));
    01137                                 line[81] = ' ';
    01138                         }
    01139
    01140                         /* duration magnitude weight code */
    01141                         sprintf (line+82, "%1d", (int) MIN(pStaMag->dWeight, 9));
    01142                         line[83] = ' ';
    01143
    01144
    01145                         /* azimuth to station */
    01146                         if (pArr->dAzm != 0.0)
    01147                         {
    01148                                 sprintf (line+91, "%3d", (int) MIN(pArr->dAzm, 999));
    01149                                 line[94] = ' ';
    01150                         }
    01151
    01152                         /* data source code */
    01153                         sprintf( line+108,  "%c",   ' ');
    01154                         line[109] = ' ';
    01155
    01156                         sprintf( line+111, "\n\0" );
    01157
    01158                 } /* S-wave portion */
    01159                 else
    01160                 {
    01161
    01162                         /* Fill in the UNKNOWN wave portion */
    01163                         /* THIS IS A HACK: to accomodate weird NSN
    01164                          * picks. In real life, we will not be using
    01165                          * the hypoinverse file format to do this
    01166                          */
    01167
    01168                         /* Make sure there's a pick
    01169                          **************************/
    01170                         if (pArr->tObsPhase == 0.0)
    01171                         {
    01172                                 logit ("", "No pick time found\n");
    01173                                 return EW_FAILURE;
    01174                         }
    01175
    01176
    01177                         /* P remark such as "IP" */
    01178                         if (plen >= 2 )
    01179                                 strncpy( line+13, pArr->szObsPhase, 2 );
    01180                         else if (plen == 1)
    01181                                 strncpy( line+14, pArr->szObsPhase, plen );
    01182
    01183
    01184                         /* P first motion */
    01185                         if (pArr->cMotion != '\0' )
    01186                                 line[15] = pArr->cMotion;
    01187
    01188                         /* Assigned P weight code */
    01189                         if (pArr->dSigma >= 0)
    01190                         {
    01191                                 if (pArr->dSigma <= 0.02)
    01192                                         tmpint = 0;
    01193                                 else if (pArr->dSigma <= 0.03)
    01194                                         tmpint = 1;
    01195                                 else if (pArr->dSigma <= 0.05)
    01196                                         tmpint = 2;
    01197                                 else if (pArr->dSigma <= 0.08)
    01198                                         tmpint = 3;
    01199                                 else
    01200                                         tmpint = 4;
    01201
    01202                                 line[16] = tmpint + '0';
    01203                         }
    01204
    01205                         /* Seconds of P arrival */
    01206                         sprintf (line+29, "%5d", (int) (100.0 * (pArr->tObsPhase - Cat)));
    01207                         line[34] = ' ';
    01208
    01209                         /* P travel time residual */
    01210                         sprintf (line+34, "%4d", (int) MIN((100.0* pArr->tResPick), 9999));
    01211                         line[38] = ' ';
    01212
    01213                         /* P weight actually used */
    01214                         sprintf (line+38, "%3d", (int) MIN((100.0 * pArr->dWeight), 999));
    01215                         line[41] = ' ';
    01216
    01217                         /* epicentral distance */
    01218                         if (pArr->dDist != 0.0)
    01219                         {
    01220                                 sprintf (line+74, "%4d", (int) MIN((10.0 * pArr->dDist), 9999));
    01221                                 line[78] = ' ';
    01222                         }
    01223
    01224                         /* emergence angle at source */
    01225                         if (pArr->dTakeoff != 0.0)
    01226                         {
    01227                                 sprintf (line+78, "%3d", (int) MIN(pArr->dTakeoff, 999));
    01228                                 line[81] = ' ';
    01229                         }
    01230
    01231                         /* duration magnitude weight code */
    01232                         sprintf (line+82, "%1d", (int) MIN(pStaMag->dWeight, 9));
    01233                         line[83] = ' ';
    01234
    01235
    01236                         /* coda duration in seconds */
    01237                         if (pStaMag->StaMagUnion.CodaDur.tCodaDurXtp != 0.0)
    01238                         {
    01239                                 sprintf( line+87,  "%4d", (int) MIN(pStaMag->StaMagUnion.CodaDur.tCodaDurXtp, 9999 ) );
    01240                                 line[91] = ' ';
    01241                         }
    01242
    01243                         /* azimuth to station */
    01244                         if (pArr->dAzm != 0.0)
    01245                         {
    01246                                 sprintf (line+91, "%3d", (int) MIN(pArr->dAzm, 999));
    01247                                 line[94] = ' ';
    01248                         }
    01249
    01250                         /* duration magnitude for this station */
    01251                         if (pStaMag->dMag != 0.0)
    01252                         {
    01253                                 sprintf (line+94, "%3d", (int) MIN((100.0* pStaMag->dMag), 999));
    01254                                 line[97] = ' ';
    01255                         }
    01256
    01257                         /* data source code */
    01258                         sprintf( line+108,  "%c",   ' ');
    01259                         line[109] = ' ';
    01260
    01261                         sprintf( line+111, "\n\0" );
    01262
    01263
    01264                         /* Build the shadow card
    01265                          ***********************/
    01266                         for( j=0; j<ARC_SPHS_LEN; j++ )
    01267                                 shdw[j] = ' ';
    01268
    01269                         strncpy (shdw, "$", 1);
    01270
    01271                         if (pStaMag->StaMagUnion.CodaDur.tCodaDurXtp != 0.0)
    01272                         {
    01273                                 sprintf (shdw+35, "%5d",  (int) MIN( pStaMag->StaMagUnion.CodaDur.tCodaDurXtp, 99999 ) );
    01274                                 shdw[40] = ' ';
    01275                         }
    01276
    01277                         sprintf (shdw+92, "\n\0");
    01278                 }
    01279
    01280         } /* loop over arrivals */
    01281
    01282
    01283
    01284
    01285         /* Copy both to the target address if there's room
    01286          *************************************************/
    01287         if ((strlen (arcmsg) + strlen (line) + strlen (shdw) + 1) > (size_t)maxlen)
    01288         {
    01289                 logit ("", "Max arcmsg length exceeded.\n");
    01290                 return EW_FAILURE;
    01291         }
    01292
    01293         strcat (arcmsg, line);
    01294         strcat (arcmsg, shdw);
    01295
    01296         return EW_SUCCESS;
    01297
    01298 }
    01299
    01300
    01301
    01302
    01303
    01304 /***************************************************************************/
    01305 /* BuildTerm() builds a hypoinverse event terminator card & its shadow     */
    01306 /***************************************************************************/
    01307 int             BuildTerm (int eventid, char *arcmsg, int maxlen)
    01308 {
    01309    char line[ARC_TRM_LEN];   /* temporary working place */
    01310    char shdw[ARC_STRM_LEN];   /* temporary shadow card   */
    01311    int  i;
    01312
    01313 /* Put all blanks into line and shadow card
    01314  ******************************************/
    01315         for (i = 0; i < ARC_TRM_LEN; i++)
    01316                 line[i] = ' ';
    01317         for (i = 0; i < ARC_STRM_LEN; i++)
    01318                 shdw[i] = ' ';
    01319
    01320 /* Build terminator
    01321  ******************/
    01322         if (eventid != 0)
    01323                 sprintf (line+62, "%10ld\n\0",  eventid );
    01324         else
    01325                 sprintf (line+72, "\n\0");
    01326
    01327 /* Build shadow card
    01328  *******************/
    01329         sprintf (shdw, "$");
    01330         shdw[1] = ' ';
    01331         if (eventid != 0)
    01332                 sprintf (shdw+62, "%10ld\n\0",  eventid);
    01333         else
    01334                 sprintf (shdw+72, "\n\0");
    01335
    01336 /* Copy both to the target address if there's room
    01337  *************************************************/
    01338         if ((strlen (arcmsg) + strlen (line) + strlen (shdw) + 1) > (size_t)maxlen)
    01339         {
    01340                 logit ("", "Max length (%d) of ARC message exceeded.\n", maxlen);
    01341                 return EW_FAILURE;
    01342         }
    01343
    01344         strcat (arcmsg, line);
    01345         strcat (arcmsg, shdw);
    01346         return EW_SUCCESS;
    01347
    01348 }
    01349
    01350
    01351