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

sudsputaway.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: sudsputaway_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:02  paulf
00008  *     first inclusion
00008  *
00009  *     Revision 1.9  2002/01/08 17:02:29  cjbryan
00010  *     In order to accommodate 24-bit broadband data, traces of data of longer than long are now clipped to +/-2147483648
00011  *
00012  *     Revision 1.8  2001/04/12 03:47:36  lombard
00013  *     Major reorganization of SUDSPA_next to improve efficiency
00014  *     Reformatted code; cleaned up lots of comments and logit calls
00015  *     Removed mapping of NC component codes (only needed at UW)
00016  *     Now traces of data larger than short in are clipped to +/- 32767
00017  *     counts; before they were byte-truncated.
00018  *     Initializes SUDS structures to zero before filling them.
00019  *
00020  *     Revision 1.7  2001/03/27 22:22:51  cjbryan
00021  *     ensured that time portion of suds format is hhmmss and not hhmmss.ss as carried by EventTime variable
00022  *
00023  *     Revision 1.6  2001/03/22 20:55:12  cjbryan
00024  *     deleted now obsolete EventInst variable
00025  *
00026  *     Revision 1.5  2001/03/21 23:15:23  cjbryan
00027  *     integrated CVO subnet into output filename
00028  *
00029  *     Revision 1.4  2001/03/21 16:41:07  alex
00030  *     added EventSubnet variable to carry subnet name through to
00031  *     filename; deleted now extraneous EventMod variable
00032  *
00033  *     Revision 1.3  2001/03/21 02:23:03  alex
00034  *     *** empty log message ***
00035  *
00036  *     Revision 1.2  2000/03/10 23:23:43  davidk
00037  *     changed the sudsputaway routines to match the new PA_XXX
00038  *     routines in putaway.c.
00039  *     Moved the SUDSPA_XXX function prototypes to pa_other_head.h
00040  *
00041  *     Revision 1.1  2000/02/14 18:51:48  lucky
00042  *     Initial revision
00043  *
00044  *
00045  */
00046 
00047 /* sudsputaway.c 
00048    
00049         Routines for writing trace data in PC-SUDS format 
00050 
00051 
00052   Thu Jul 22 14:56:37 MDT 1999 Lucky Vidmar
00053     Major structural changes to accomodate making all putaway routines
00054     into library calls so that they can be shared between trig2disk
00055     and wave2disk. Eliminated global variables set and allocated outside
00056     of this file. We should only have static globals from now on, with
00057     everything else being passed in via the putaway.c calls.
00058 */
00059 
00060 #include <limits.h>
00061 #include <stdio.h>
00062 #include <stdlib.h>
00063 #include <string.h>
00064 #include <errno.h>
00065 #include <earthworm.h>
00066 #include <time.h>
00067 #include <trace_buf.h>
00068 #include <swap.h>
00069 #include <ws_clientII.h>
00070 #include <sudshead.h>
00071 #include <pa_subs.h>
00072 
00073 #define TAG_FILE        '.tag'        /* file containing the last known file tag */
00074 #define MAXTXT           150
00075 
00076 
00077 FILE    *SUDSfp;                      /* file pointer for the SUDS file */
00078 
00079 static  long   *SudsBuffer;           /* write out SUDS data as long integers */
00080 static  short  *SudsBufferShort;      /* write out SUDS data as short integers */
00081 static  char SudsOutputFormat[MAXTXT];
00082 
00083 /* Internal Function Prototypes */
00084 static int StructMakeLocal (void *, int, char, int);
00085 static int SwapDo (void *, int);
00086 
00087 /************************************************************************
00088 * Initialization function,                                              *
00089 *       This is the Put Away startup intializer. This is called when    *
00090 *       the system first comes up. Here is a chance to look around      *
00091 *       and see if it's possible to do business, and to complain        *
00092 *       if not ,BEFORE an event has to be processed.                    *
00093 *                                                                       *
00094 *       For PCSUDS, all we want to do is to make sure that the          *
00095 *       directory where files should be written exists.                 *
00096 *************************************************************************/
00097 int SUDSPA_init (int OutBufferLen, char *OutDir, char *OutputFormat, 
00098                  int debug)
00099 {
00107   if ((SudsBuffer = (long *) malloc (OutBufferLen * sizeof (char))) == NULL)
00108   {
00109     logit ("et", "SUDSPA_init: couldn't malloc SudsBuffer\n");
00110     return EW_FAILURE;
00111   }
00112   if ((SudsBufferShort = (short *) malloc (OutBufferLen * sizeof (char))) == NULL)
00113   {
00114     logit ("et", "SUDSPA_init: couldn't malloc SudsBufferShort\n");
00115     return EW_FAILURE;
00116   }
00117 
00118   /* Make sure that the top level output directory exists */
00119   if (CreateDir (OutDir) != EW_SUCCESS)
00120   {
00121     logit ("e", "SUDSPA_init: Call to CreateDir failed\n");
00122     return EW_FAILURE;
00123   }
00124 
00125   if(strlen(OutputFormat) >= sizeof(SudsOutputFormat))
00126   {
00127     logit("","SUDSPA_init: Error: OutputFormat(%s) is too long! Quitting!\n",
00128           OutputFormat);
00129     return(EW_FAILURE);
00130   }
00131   else
00132   {
00133     strcpy(SudsOutputFormat,OutputFormat);
00134   }
00135   return EW_SUCCESS; 
00136 }
00137 
00138 /************************************************************************
00139 *   This is the Put Away event initializer. It's called when a snippet  *
00140 *   has been received, and is about to be processed.                    *
00141 *   It gets to see the pointer to the TraceRequest array,               *
00142 *   and the number of loaded trace structures.                          *
00143 *                                                                       *
00144 *   For PCSUDS, we need to make sure that the target directory          *
00145 *   exists, create it if it does not, then open the SUDS file           *
00146 *   for writing.                                                        *
00147 *************************************************************************/
00148 int SUDSPA_next_ev (char *EventID, TRACE_REQ *ptrReq, int nReq, 
00149                     char *OutDir, char *EventDate, char *EventTime,
00150                     char *EventSubnet, int debug)
00151 
00152 {
00153   char    SUDSFile[4*MAXTXT];
00154   char    hhmmss[7];
00155 
00156   /* Changed by Eugene Lublinsky, 3/31/Y2K */
00157   /* There are 2 modes of behavior now: the default one when insmod */
00158   /* is numeric or the second one when insmod is alphanumeric */
00159   char  tmpEventID[EVENTID_SIZE + 3];
00160 
00161   /* We treat suds file slightly differently - by request
00162    * from Tom Murray. The files are placed directly into the
00163    * top level suds directory, with names as follows:
00164    *
00165    *    yyyymmdd_hhmmss_insmod_evid.dmx
00166    */
00167 
00168   /* Changed by Eugene Lublinsky, 3/31/Y2K */
00169   /* choose which way to go */
00170 
00171   /* Build the file name */
00172   /* added by murray (and it shows) to set the eventid at 3 characters */
00173   if (strlen(EventID) < 3)
00174     sprintf (tmpEventID,"000%s",EventID) ;
00175   else
00176     sprintf (tmpEventID,"%s",EventID) ;
00177 
00178   /* ensure that time string is of the form hhmmss (revised EventTime 
00179      allows a string of the form hhmmss.ss, so truncate it if necessary) */
00180   if (strlen(EventTime) > 6)
00181   {
00182     strncpy(hhmmss, EventTime, 6);
00183     hhmmss[6] = '\0';
00184   }
00185   else
00186     strcpy(hhmmss, EventTime);
00187 
00188   /* changed by Carol 3/21/01: if no subnet, use network name
00189      in filename */
00190   if (EventSubnet[0] != '\0')
00191     sprintf (SUDSFile, "%s/%s_%s_%s_%s.dmx", OutDir,
00192              EventDate, hhmmss, EventSubnet, 
00193              &tmpEventID[strlen(tmpEventID)-3]);
00194   else
00195     sprintf (SUDSFile, "%s/%s_%s_%s_%s.dmx", OutDir,
00196              EventDate, hhmmss, ptrReq->net, 
00197              &tmpEventID[strlen(tmpEventID)-3]);
00198         
00199   /* end of changes */
00200 
00201   if (debug == 1)
00202     logit ("t", "Opening SUDS file %s\n", SUDSFile);
00203 
00204   /* open file */
00205   if ((SUDSfp = fopen (SUDSFile, "wb")) == NULL)
00206   {
00207     logit ("e", "SUDSPA_next_ev: unable to open file %s: %s\n", 
00208            SUDSFile, strerror(errno));
00209     return EW_FAILURE;
00210   }
00211 
00212   return (EW_SUCCESS);
00213 }
00214 
00215 /************************************************************************
00216 * This is the working entry point into the disposal system. This        *
00217 * routine gets called for each trace snippet which has been recovered.  *
00218 * It gets to see the corresponding SNIPPET structure, and the event id  *
00219 *                                                                       *
00220 * For PCSUDS, this routine writes to the SUDS file, pointed to by the   *
00221 * SUDSfp pointer, all of the received trace data in SUDS format:        *
00222 *                                                                       *
00223 *      1. SUDS tag - indicating what follows                            *
00224 *      2. SUDS_STATIONCOMP struct - describe the station                *
00225 *      3. SUDS tag - indicating what follows                            *
00226 *      4. SUDS_DESCRIPTRACE struct - describe the trace data            *
00227 *      5. trace data                                                    *
00228 *                                                                       *
00229 *  One bit of complexity is that we need to write the files in the      *
00230 *  correct byte-order. Based on the OutputFormat parameter, determine   *
00231 *  whether or not to swap bytes before writing the suds file.           *
00232 *                                                                       *
00233 * WARNING: we clip trace data to -2147483648 - +2147483647 so it will   *
00234 *  fit in a long int. Any incoming data that is longer than 32 bits     *
00235 *  will be CLIPPED. cjb 5/18/2001                                       *
00236 *************************************************************************/
00237 /* Process one channel of data */
00238 int SUDSPA_next (TRACE_REQ *getThis, double GapThresh,
00239                  long OutBufferLen, int debug)
00240 {
00241   TRACE_HEADER *wf;
00242   short  *s_data;
00243   long   *l_data;
00244   float  *f_data;
00245   char   *msg_p;        /* pointer into tracebuf data */
00246   char    datatype;
00247   int     data_size;
00248   int     j;
00249   int     gap_count = 0;
00250   long    nsamp, nfill;
00251   long    nfill_max = 0l;
00252   long    nsamp_this_scn = 0l;
00253   long    this_size;
00254   double  begintime, starttime, endtime;
00255   double  samprate;
00256   long    fill = 0l;
00257   long    min, max;
00258   int     total;
00259   SUDS_STRUCTTAG          tag;
00260   SUDS_DESCRIPTRACE       dt;
00261   SUDS_STATIONCOMP        sc;
00262   
00263   /* Check arguments */
00264   if (getThis == NULL)
00265   {
00266     logit ("e", "SUDSPA_next: invalid argument passed in.\n");
00267     return EW_FAILURE;
00268   }
00269 
00270   /* Start with a clean slate */
00271   memset(&tag, 0, sizeof(tag));
00272   memset(&dt, 0, sizeof(dt));
00273   memset(&sc, 0, sizeof(sc));
00274   
00275   /* Used for computing trace statistics */
00276   max = 4096;
00277   min = 0;
00278   total = 0;
00279 
00280   if ( (msg_p = getThis->pBuf) == NULL)   /* pointer to first message */
00281   {
00282     logit ("e", "SUDSPA_next: Message buffer is NULL.\n");
00283     return EW_FAILURE;
00284   }
00285   wf = (TRACE_HEADER *) msg_p;
00286   
00287   /* Look at the first TRACE_HEADER and get set up of action */
00288   if (WaveMsgMakeLocal(wf) < 0)
00289   {
00290     logit("e", "SUDSPA_next: unknown trace data type: %s\n",
00291           wf->datatype);
00292     return( EW_FAILURE );
00293   }
00294 
00295   nsamp = wf->nsamp;
00296   starttime = wf->starttime;
00297   endtime = wf->endtime;
00298   samprate = wf->samprate;
00299   if (samprate < 0.01)
00300   {
00301     logit("et", "unreasonable samplerate (%f) for <%s.%s.%s>\n",
00302           samprate, wf->sta, wf->chan, wf->net);
00303     return( EW_FAILURE );
00304   }
00305   begintime = starttime;
00306   datatype = 'n';
00307   if (wf->datatype[0] == 's' || wf->datatype[0] == 'i')
00308   {
00309     if (wf->datatype[1] == '2') datatype = 's';
00310     else if (wf->datatype[1] == '4') datatype = 'l';
00311   }
00312   else if (wf->datatype[0] == 't' || wf->datatype[0] == 'f')
00313   {
00314     if (wf->datatype[1] == '4') datatype = 'f';
00315   }
00316   if (datatype == 'n')
00317   {
00318     logit("et", "SUDSPA_next: unsupported datatype: %s\n", datatype);
00319     return( EW_FAILURE );
00320   }
00321 
00322   if (debug == 1)
00323     logit("et", "SUDSPA_next: working on <%s/%s/%s> datatype: %c \n",
00324                         wf->sta, wf->chan, wf->net, datatype);
00325 
00326   /* loop through all the messages for this s-c-n */
00327   while (1) 
00328   {
00329     /* advance message pointer to the data */
00330     msg_p += sizeof(TRACE_HEADER);
00331         
00332     /* check for sufficient memory in output buffer */
00333     this_size = (nsamp_this_scn + nsamp ) * sizeof(long);
00334     if ( OutBufferLen < this_size )
00335     {
00336       logit( "e", "out of space for <%s.%s.%s>; saving long trace.\n",
00337              wf->sta, wf->chan, wf->net);
00338       break;
00339     }
00340   
00341         /* if data are floats, clip to longs cjb 5/18/2001 */
00342     switch( datatype )
00343     {
00344     case 's':
00345       s_data = (short *)msg_p;
00346       for ( j = 0; j < nsamp ; j++, nsamp_this_scn++ )
00347         SudsBuffer[nsamp_this_scn] = (long) s_data[j];
00348       msg_p += sizeof(short) * nsamp;
00349       break;
00350     case 'l':
00351       l_data = (long *)msg_p;
00352       for ( j = 0; j < nsamp; j++, nsamp_this_scn++ )
00353           SudsBuffer[nsamp_this_scn] = l_data[j];
00354       msg_p += sizeof(long) * nsamp;
00355       break;
00356     case 'f':
00357       f_data = (float *)msg_p;
00358       /* CLIP the data to long int */
00359       for ( j = 0; j < nsamp; j++, nsamp_this_scn++ )
00360       {
00361         if (l_data[j] < (float)LONG_MIN)
00362           SudsBuffer[nsamp_this_scn] = LONG_MIN;
00363         else if (l_data[j] > (float) LONG_MAX)
00364           SudsBuffer[nsamp_this_scn] = LONG_MAX;
00365         else
00366           SudsBuffer[nsamp_this_scn] = (long) l_data[j];
00367       }
00368       msg_p += sizeof(float) * nsamp;
00369       break;
00370     }
00371   
00372     /* End-check based on length of snippet buffer */
00373     if ((long) msg_p >= ((long) getThis->actLen + (long) getThis->pBuf)) 
00374     {
00375       if (debug == 1)
00376         logit ("", "Setting done for <%s.%s.%s>\n", wf->sta, wf->chan, 
00377                wf->net);
00378       break; /* Break out of the while(1) loop 'cuz we're done */
00379     }
00380   
00381     /* msg_p has been advanced to the next TRACE_BUF; localize bytes *
00382      * and check for gaps.                                           */
00383     wf = (TRACE_HEADER *) msg_p;
00384     if (WaveMsgMakeLocal(wf) < 0)
00385     {
00386       logit("e", "SUDSPA_next: unknown trace data type: %s\n",
00387             wf->datatype);
00388       return( EW_FAILURE );
00389     }
00390     nsamp = wf->nsamp;
00391     starttime = wf->starttime; 
00392     /* starttime is set for new packet; endtime is still set for old packet */
00393     if ( endtime + ( 1.0/samprate ) * GapThresh < starttime ) 
00394     {
00395       /* there's a gap, so fill it */
00396       logit("e", "gap in %s.%s.%s: %lf: %lf\n", wf->sta, wf->chan, wf->net,
00397             endtime, starttime - endtime);
00398       nfill = (long) (samprate * (starttime - endtime) - 1);
00399       if ( (nsamp_this_scn + nfill) * (long)sizeof(long) > OutBufferLen ) 
00400       {
00401         logit("e", 
00402               "bogus gap (%d); skipping\n", nfill);
00403         return(EW_FAILURE);
00404       }
00405       /* do the filling */
00406       for ( j = 0; j < nfill; j++, nsamp_this_scn ++ ) 
00407         SudsBuffer[nsamp_this_scn] = fill;
00408       /* keep track of how many gaps and the largest one */
00409       gap_count++;
00410       if (nfill_max < nfill) 
00411         nfill_max = nfill;
00412     }
00413     /* Advance endtime to the new packet;        *
00414      * process this packet in the next iteration */
00415     endtime = wf->endtime;
00416   } /* while(1) */
00417       
00418   /* figure out min, max, and "noise" */
00419   for (j = 0; j < 200 && j < nsamp_this_scn; j++)
00420   {
00421     if (SudsBuffer[j] > max)
00422       max = SudsBuffer[j];
00423     if (SudsBuffer[j] < min)
00424       min = SudsBuffer[j];
00425     total += SudsBuffer[j];
00426   }
00427   dt.avenoise = ((float)total)/ (float)j;  /* Mean of the first 200 samples */
00428   for (; j < nsamp_this_scn; j++)
00429   {
00430     if (SudsBuffer[j] > max)
00431       max = SudsBuffer[j];
00432     if (SudsBuffer[j] < min)
00433       min = SudsBuffer[j];
00434   }
00435 
00436   /* If the incoming data were originally short integers, copy the values
00437      back to an array of shorts; disk space saving feature requested
00438          by Gabriel Reyes cjb 6/11/01 */
00439   if (datatype == 's') 
00440   {
00441     for (j = 0; j < nsamp_this_scn; j++)
00442                 SudsBufferShort[j] = (short)SudsBuffer[j];
00443   }
00444 
00445   /* Convert to the appropriate output format */
00446 #if defined (_INTEL)
00447   /* we are on intel, data will be read on sparc */
00448   if (strcmp (SudsOutputFormat, "sparc") == 0)
00449     for (j = 0; j < nsamp_this_scn; j++)
00450     {
00451                 if (datatype == 's')
00452                         SwapShort(&SudsBufferShort[j]);
00453                 else
00454                         SwapLong(&SudsBuffer[j]);
00455         }
00456 #elif defined (_SPARC)
00457   /* we are on sparc, data will be read on intel */
00458   if (strcmp (SudsOutputFormat, "intel") == 0)
00459     for (j = 0; j < nsamp_this_scn; j++)
00460     {
00461                 if (datatype == 's')
00462                         SwapShort(&SudsBufferShort[j]);
00463                 else
00464                         SwapLong(&SudsBuffer[j]);
00465         }
00466 #else
00467   logit ("e", "SUDSPA_next: Can't determine my platform - please compile with either _INTEL or _SPARC set\n");
00468       return EW_FAILURE;
00469 #endif
00470                
00471   /* Write out to the SUDS file */
00472   /* Fill and write TAG for the STATIONCOMP struct */
00473 
00474   tag.id_struct = STATIONCOMP; /* what follows is STATIONCOMP */
00475   tag.len_struct = sizeof (SUDS_STATIONCOMP); 
00476   tag.len_data = 0;
00477   tag.sync = 'S';
00478 
00479   if (debug == 1)
00480     logit ("", "Writing tag for %d (%d)\n", tag.id_struct, tag.len_struct);
00481 
00482   if (strcmp (SudsOutputFormat, "sparc") == 0)
00483     tag.machine = '1';
00484   else if (strcmp (SudsOutputFormat, "intel") == 0)
00485     tag.machine = '6';
00486 
00487   if (StructMakeLocal ((void *) &tag, STRUCTTAG, tag.machine, debug) 
00488       != EW_SUCCESS)
00489   {
00490     logit ("et", "SUDSPA_next: Call to StructMakeLocal failed. \n");
00491     return EW_FAILURE;
00492   }
00493 
00494   if (fwrite ((void *) &tag, sizeof (SUDS_STRUCTTAG), 1, SUDSfp) != 1)
00495   {
00496     logit ("et", "SUDSPA_next: error writing SUDS tag. \n");
00497     return EW_FAILURE;
00498   }
00499 
00500   /* Fill and write STATIONCOMP struct */
00501   /* in SUDS_STATIDENT structure, char st_name[5],
00502         char network[4], char component where component = v,n,e
00503         cjb 5/18/2001 */
00504   if (strlen(wf->sta) > 5) {
00505         strncpy(sc.sc_name.st_name, wf->sta, 4);
00506         sc.sc_name.st_name[4] = '\0';
00507   }
00508   else
00509         strcpy (sc.sc_name.st_name, wf->sta); 
00510 
00511  if (strlen(wf->net) > 4) {
00512         strncpy(sc.sc_name.network, wf->net, 3);
00513         sc.sc_name.network[3] = '\0';
00514   }
00515   else
00516         strcpy (sc.sc_name.network, wf->net); 
00517 
00518   if (strlen(wf->chan) >= 3)
00519         sc.sc_name.component = wf->chan[2];
00520   else 
00521         sc.sc_name.component = wf->chan[0];
00522 
00523   if ((sc.sc_name.component == 'Z') || (sc.sc_name.component == 'z'))
00524           sc.sc_name.component = 'V';
00525 
00526   if ((sc.sc_name.component != 'N') && (sc.sc_name.component != 'n')
00527           && (sc.sc_name.component != 'E') && (sc.sc_name.component != 'e')
00528           && (sc.sc_name.component != 'V') && (sc.sc_name.component != 'v')
00529           && (sc.sc_name.component != 'T') && (sc.sc_name.component != 't'))
00530           logit("et", "SUDSPA_next: unknown station component %c \n",
00531                 sc.sc_name.component);
00532 
00533   if (datatype == 's')
00534         sc.data_type = 's';
00535   else
00536           sc.data_type = 'l';
00537   sc.data_units = 'd';
00538 
00539   if (debug == 1)
00540     logit ("", "Writing STATIONCOMP struct for %s.%s.%c\n", 
00541            sc.sc_name.st_name,
00542            sc.sc_name.network,     
00543            sc.sc_name.component);
00544 
00545   if (StructMakeLocal ((void *) &sc, STATIONCOMP, tag.machine, debug) 
00546       != EW_SUCCESS)
00547   {
00548     logit ("et", "SUDSPA_next: Call to StructMakeLocal failed. \n");
00549     return EW_FAILURE;
00550   }
00551 
00552   if (fwrite ((void *) &sc, sizeof (SUDS_STATIONCOMP), 1, SUDSfp) != 1)
00553   {
00554     logit ("et", "SUDSPA_next: error writing SUDS_STATIONCOMP struct. \n");
00555     return EW_FAILURE;
00556   }
00557 
00558   /* Fill and write TAG for the DESCRIPTRACE struct */
00559   if (datatype == 's')
00560         data_size = nsamp_this_scn * sizeof (short);
00561   else
00562         data_size = nsamp_this_scn * sizeof (long);
00563   tag.id_struct = DESCRIPTRACE; /* what follows is DESCRIPTRACE */
00564   tag.len_struct = sizeof (SUDS_DESCRIPTRACE); 
00565   tag.len_data = (long) data_size;
00566 
00567   if (debug == 1)
00568     logit ("", "Writing tag for %d (%d)\n", tag.id_struct, tag.len_struct);
00569 
00570   if (StructMakeLocal ((void *) &tag, STRUCTTAG, tag.machine, debug) != EW_SUCCESS)
00571   {
00572     logit ("et", "SUDSPA_next: Call to StructMakeLocal failed. \n");
00573     return EW_FAILURE;
00574   }
00575 
00576   if (fwrite ((void *) &tag, sizeof (SUDS_STRUCTTAG), 1, SUDSfp) != 1)
00577   {
00578     logit ("et", "SUDSPA_next: error writing SUDS tag. \n");
00579     return EW_FAILURE;
00580   }
00581 
00582   /* Fill and write DESCRIPTRACE struct */
00583   /*strcpy (dt.dt_name.st_name, wf->sta); 
00584   strcpy (dt.dt_name.network, wf->net); 
00585   dt.dt_name.component = wf->chan[0];
00586   */
00587   /* in SUDS_STATIDENT structure, char st_name[5],
00588         char network[4], char component where component = v,n,e
00589         cjb 5/18/2001 */
00590   if (strlen(wf->sta) > 5) {
00591         strncpy(dt.dt_name.st_name, wf->sta, 4);
00592         dt.dt_name.st_name[4] = '\0';
00593   }
00594   else
00595         strcpy (dt.dt_name.st_name, wf->sta); 
00596 
00597  if (strlen(wf->net) > 4) {
00598         strncpy(dt.dt_name.network, wf->net, 3);
00599         dt.dt_name.network[3] = '\0';
00600   }
00601   else
00602         strcpy (dt.dt_name.network, wf->net); 
00603 
00604   if (strlen(wf->chan) >= 3)
00605     dt.dt_name.component = wf->chan[2];
00606   else 
00607     dt.dt_name.component = wf->chan[0];
00608 
00609   if ((dt.dt_name.component == 'Z') || (dt.dt_name.component == 'z'))
00610           dt.dt_name.component = 'V';
00611 
00612   if ((dt.dt_name.component != 'N') && (dt.dt_name.component != 'n')
00613           && (dt.dt_name.component != 'E') && (dt.dt_name.component != 'e')
00614           && (dt.dt_name.component != 'V') && (dt.dt_name.component != 'v')
00615           && (dt.dt_name.component != 'T') && (dt.dt_name.component != 't'))
00616           logit("et", "SUDSPA_next: error with station component %c \n",
00617                 dt.dt_name.component);
00618 
00619 
00620   if (datatype == 's')
00621           dt.datatype = 's';
00622   else
00623           dt.datatype = 'l';
00624   dt.begintime = begintime;
00625   dt.length = nsamp_this_scn;
00626   dt.rate = (float) wf->samprate;
00627   dt.mindata = (float) min;
00628   dt.maxdata = (float) max;
00629 
00630   /* Ignore the rest for now - see how it works */
00631 
00632   if (debug == 1)
00633     logit ("", "Writing DESCRIPTRACE - %d samples (%d,%d) \n", 
00634            nsamp_this_scn, min, max);
00635 
00636   if (StructMakeLocal ((void *) &dt, DESCRIPTRACE, tag.machine, debug) != EW_SUCCESS)
00637   {
00638     logit ("et", "SUDSPA_next: Call to StructMakeLocal failed. \n");
00639     return EW_FAILURE;
00640   }
00641 
00642   if (fwrite ((void *) &dt, sizeof (SUDS_DESCRIPTRACE), 1, SUDSfp) != 1)
00643   {
00644     logit ("et", "SUDSPA_next: error writing DESCRIPTRACE struct. \n");
00645     return EW_FAILURE;
00646   }
00647 
00648   /* write TRACE data - SudsBuffer holds long data;
00649           SudsBufferShort holds short data */
00650   if (debug == 1)
00651     logit ("", "Writing %d bytes of DESCRIPTRACE data\n", data_size);
00652   if (datatype == 's')
00653   {
00654         if ((long)fwrite ((void *) SudsBufferShort, sizeof (char), data_size, SUDSfp)
00655                 != data_size)
00656         {
00657                 logit ("et", "SUDSPA_next: error writing short TRACE data. \n");
00658                 return EW_FAILURE;
00659         }
00660   }
00661   else
00662   {
00663         if ((long)fwrite ((void *) SudsBuffer, sizeof (char), data_size, SUDSfp)
00664                 != data_size)
00665         {
00666                 logit ("et", "SUDSPA_next: error writing long TRACE data. \n");
00667                 return EW_FAILURE;
00668         }
00669   }
00670   return EW_SUCCESS;
00671 }
00672 
00673 
00674 /************************************************************************
00675 * This is the Put Away end event routine. It's called after we've       *
00676 * finished processing one event                                         *
00677 *                                                                       *
00678 * For PC-SUDS - close the SUDS file, pointed to by SUDSfp               *
00679 *               free SudsBuffer memory to be nice to everyone else      *
00680 *************************************************************************/
00681 int SUDSPA_end_ev(int debug)
00682 {
00683   fclose (SUDSfp);
00684         
00685   if (debug == 1)
00686     logit("t", "Closing SUDS file \n");
00687 
00688   return( EW_SUCCESS );
00689 }
00690 
00691 
00692 /************************************************************************
00693 *       This is the Put Away close routine. It's called after when      *
00694 *       we're being shut down.                                          *
00695 *************************************************************************/
00696 int SUDSPA_close(int debug)
00697 {
00698 
00699   free ((char *) SudsBufferShort);
00700   free ((char *) SudsBuffer);
00701   return( EW_SUCCESS );
00702 }
00703 
00704 
00705 /*
00706  *
00707  *  Byte swapping functions
00708  */
00709 
00710 /* swap bytes if necessary, depending on what machine */
00711 /* we have been compiled, and what machine the data   */
00712 /* is being read from/being written to                */
00713 
00714 static int StructMakeLocal(void *ptr, int struct_type, char data_type, 
00715                            int debug)
00716 {
00717   if (ptr == NULL)
00718   {
00719     logit ("e", "StructMakeLocal: NULL pointer passed in\n");
00720     return EW_FAILURE;
00721   }
00722 
00723 #if defined (_INTEL)
00724   if (data_type != '6')
00725   {
00726     if (debug == 1)
00727       logit ("", "Swapping from Intel to Sun \n");
00728 
00729     /* if we are on intel, and target data is not intel */
00730     if (SwapDo (ptr, struct_type) != EW_SUCCESS)
00731     {
00732       logit ("e", "StructMakeLocal: Call to SwapDo failed \n");
00733       return EW_FAILURE;
00734     }
00735   }
00736 
00737 #elif defined (_SPARC)
00738   if (data_type == '6')
00739   {
00740     if (debug == 1)
00741       logit ("", "Swapping from Sun to Intel \n");
00742 
00743     /* if we are on solaris, and target data is not solaris */
00744     if (SwapDo (ptr, struct_type) != EW_SUCCESS)
00745     {
00746       logit ("e", "StructMakeLocal: Call to SwapDo failed \n");
00747       return EW_FAILURE;
00748     }
00749   }
00750 
00751 #endif
00752   return EW_SUCCESS;
00753 }
00754 
00755 
00756 /* Do the dirty work by swapping the innards of SUDS */
00757 /* structures that are of interest to us             */
00758 static int SwapDo( void *ptr, int struct_type)
00759 {
00760   SUDS_STRUCTTAG *tag;
00761   SUDS_STATIONCOMP *sc;
00762   SUDS_DESCRIPTRACE *dt;
00763   SUDS_TRIGGERS *tr;
00764   SUDS_DETECTOR *de;
00765   SUDS_TIMECORRECTION *tc;
00766 
00767   if (ptr == NULL)
00768   {
00769     logit ("e", "SwapDo: NULL pointer passed in.\n");
00770     return EW_FAILURE;
00771   }
00772 
00773   switch( struct_type ) 
00774   {
00775   case STRUCTTAG:
00776     tag = (SUDS_STRUCTTAG *) ptr;
00777     SwapShort (&tag->id_struct);
00778     SwapLong (&tag->len_struct);
00779     SwapLong (&tag->len_data);
00780     break;
00781   case STATIONCOMP:
00782     sc = (SUDS_STATIONCOMP *) ptr;
00783     SwapShort (&sc->sc_name.inst_type);
00784     SwapShort (&sc->azim);
00785     SwapShort (&sc->incid);
00786     SwapDouble (&sc->st_lat);
00787     SwapDouble (&sc->st_long);
00788     SwapFloat (&sc->elev);
00789     SwapShort (&sc->rocktype);
00790     SwapFloat (&sc->max_gain);
00791     SwapFloat (&sc->clip_value);
00792     SwapFloat (&sc->con_mvolts);
00793     SwapShort (&sc->channel);
00794     SwapShort (&sc->atod_gain);
00795     SwapLong (&sc->effective);
00796     SwapFloat (&sc->clock_correct);
00797     SwapFloat (&sc->station_delay);
00798     break;
00799   case DESCRIPTRACE:
00800     dt = (SUDS_DESCRIPTRACE *) ptr;
00801     SwapShort (&dt->dt_name.inst_type);
00802     SwapDouble (&dt->begintime);
00803     SwapShort (&dt->localtime);
00804     SwapShort (&dt->digi_by);
00805     SwapShort (&dt->processed);
00806     SwapLong (&dt->length);
00807     SwapFloat (&dt->rate);
00808     SwapFloat (&dt->mindata);
00809     SwapFloat (&dt->maxdata);
00810     SwapFloat (&dt->avenoise);
00811     SwapLong (&dt->numclip);
00812     SwapDouble (&dt->time_correct);
00813     SwapFloat (&dt->rate_correct);
00814     break;
00815   case TRIGGERS:
00816     tr = (SUDS_TRIGGERS *) ptr;
00817     SwapShort (&tr->tr_name.inst_type);
00818     SwapShort (&tr->sta);
00819     SwapShort (&tr->lta);
00820     SwapShort (&tr->abs_sta);
00821     SwapShort (&tr->abs_lta);
00822     SwapShort (&tr->trig_value);
00823     SwapShort (&tr->num_triggers);
00824     SwapDouble (&tr->trig_time);
00825     break;
00826   case DETECTOR:
00827     de = (SUDS_DETECTOR *) ptr;
00828     SwapFloat (&de->versionnum);
00829     SwapLong (&de->event_number);
00830     SwapLong (&de->spareL);
00831     break;
00832   case TIMECORRECTION:
00833     tc = (SUDS_TIMECORRECTION *) ptr;
00834     SwapShort (&tc->tm_name.inst_type);
00835     SwapDouble (&tc->time_correct);
00836     SwapFloat (&tc->rate_correct);
00837     SwapLong (&tc->effective_time);
00838     SwapShort (&tc->spareM);
00839     break;
00840   default:
00841     logit ("e", "SwapDo: Don't know about type %d\n", struct_type);
00842     return EW_FAILURE;
00843   }
00844 
00845   return EW_SUCCESS;
00846 }
00847 

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