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 2161 2006-05-19 16:55:03Z paulf $ 00006 * 00007 * Revision history: 00008 * $Log$ 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