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

seiputaway.c

Go to the documentation of this file.
00001 /******************************************************************
00002  * seiputaway.c - routines to enable Seisan data to be stored from
00003  *                Earthworm
00004  *
00005  * S. Flower, Feb 2001
00006  *
00007  * Modified 11 Oct 2001 - instead of writing direct to the output
00008  * file we write to a temporary file and rename it when it is
00009  * complete - this ensures that the file can be read OK as soon
00010  * as it is available
00011  *
00012  * Modified 26 Oct 2001 - fixed bug that puts gaps at wrong end
00013  * of output traces
00014  *
00015  * Modified 26 Oct 2001 - seisan file writing routines moved to a
00016  * sparate file because of complexity of doing seisan writes
00017  * with the Earthworm putaway structure
00018  *
00019  * Modified 31st Jan 2002 - new routines to make dealing with
00020  * earthworm data structures easier to follow (pa_find_data())
00021  ******************************************************************/
00022 
00023 #include <stdio.h>
00024 #include <time.h>
00025 #include <stdlib.h>
00026 #include <string.h>
00027 #include <errno.h>
00028 #include <math.h>
00029 #include <float.h>
00030 #if defined (_WINNT)
00031 #include <io.h>
00032 #endif
00033 
00034 #include <sys/types.h>
00035 #include <sys/stat.h>
00036 
00037 #include "earthworm.h"
00038 #include "trace_buf.h"
00039 #include "swap.h"
00040 #include "ws_clientII.h"
00041 #include "site.h"
00042 #include "time_ew.h"
00043 
00044 #include "seihead.h"
00045 
00046 
00047 /* private global variables */
00048 static int output_native_numbers;
00049 
00050 
00051 /**********************************************************************
00052  * SEIPA_init
00053  *
00054  * Description: initialise SEIsan put away routines
00055  *
00056  * Input parameters: output_dir - the directory to be used for Seisan
00057  *                                output files
00058  *                   output_format - "intel" or "sparc" for byte ordering
00059  *                   debug - flag for debugging output
00060  * Output parameters: none
00061  * Returns: EW_SUCCESS or EW_FAILURE
00062  *
00063  * Comments:
00064  *
00065  ***********************************************************************/
00066 int SEIPA_init (char *output_dir, char *output_format, int debug)
00067 
00068 {
00069     
00070   /* make sure that the output directory exists */
00071   if (CreateDir (output_dir) != EW_SUCCESS)
00072   {
00073     logit ("e", "SEIPA_init: Call to CreateDir failed\n");
00074     return EW_FAILURE;
00075   }
00076 
00077 #if defined (_INTEL)
00078   if (! strcmp (output_format, "intel"))
00079     output_native_numbers = TRUE;
00080   else if (! strcmp (output_format, "sparc"))
00081     output_native_numbers = FALSE;
00082   else
00083   {
00084     logit ("e", "SEIPA_init: can't recognise OutputFormat (%s)\n", output_format);
00085     return EW_FAILURE;
00086   }
00087 #elif defined (_SPARC)
00088   if (! strcmp (output_format, "sparc"))
00089     output_native_numbers = TRUE;
00090   else if (! strcmp (output_format, "intel"))
00091     output_native_numbers = FALSE;
00092   else
00093   {
00094     logit ("e", "SEIPA_init: can't recognise OutputFormat (%s)\n", output_format);
00095     return EW_FAILURE;
00096   }
00097 #else
00098 #error "_INTEL or _SPARC must be set before compiling"
00099 #endif
00100 
00101   return EW_SUCCESS;
00102 
00103 }
00104 
00105 /****************************************************************************
00106  * SEIPA_next_ev
00107  *
00108  * Description: called when a snippet has been received,
00109  *              before it is processed
00110  *
00111  * Input parameters: trace_req - array of trace request structures
00112  *                   n_reqs - size of array
00113  *                   output_dir - output directory
00114  *                   e_date, e_time - event time in the form
00115  *                                    'ccyymmdd' and 'hhmmss.ff'
00116  *                   debug - flag for debugging output
00117  * Output parameters: none
00118  * Returns: EW_SUCCESS or EW_FAILURE
00119  *
00120  * Comments:
00121  *
00122  ***********************************************************************/
00123 int SEIPA_next_ev (TRACE_REQ *trace_req, int n_reqs, char *output_dir,
00124                    char *e_date, char *e_time, char *subnet, int debug)
00125 {
00126 
00127   int count;
00128   double min_start_time, max_end_time;
00129   TRACE_REQ *trace_req_ptr;
00130 
00131 
00132   if (debug)
00133   {
00134     logit ("e", "Entering SEIPA_next_ev, date/time: %s %s\n", e_date, e_time);
00135   }
00136 
00137   /* calculate overall duration of all traces */
00138   min_start_time = DBL_MAX;
00139   max_end_time = 0.0;
00140   for (count=0; count<n_reqs; count++)
00141   {
00142     trace_req_ptr = trace_req + count;
00143     if (trace_req_ptr->reqStarttime < min_start_time)
00144       min_start_time = trace_req_ptr->reqStarttime;
00145     if (trace_req_ptr->reqEndtime > max_end_time)
00146       max_end_time = trace_req_ptr->reqEndtime;
00147   }
00148   if (debug)
00149   {
00150     logit ("e", "Request details: %lf-%lf %s\n", min_start_time, max_end_time, trace_req->net);
00151   }
00152   
00153   /* open the SEIsan file */
00154   /* changed by CJB 3/20/2002 to use subnet name if one exists */
00155   if (subnet[0] != '\0')
00156   {
00157         if (! open_seisan_file (output_dir, subnet, min_start_time,
00158                                       max_end_time - min_start_time, output_native_numbers))
00159         {
00160                 logit ("e", "SEIPA_init: unable to open Seisan output file\n");
00161                 return EW_FAILURE;
00162         }
00163   }
00164   else
00165   {
00166         if (! open_seisan_file (output_dir, trace_req->net, min_start_time,
00167                                       max_end_time - min_start_time, output_native_numbers))
00168         {
00169                 logit ("e", "SEIPA_init: unable to open Seisan output file\n");
00170                 return EW_FAILURE;
00171         }
00172   }
00173 
00174   /* write the seisan event file headers */
00175   for (count=0; count<n_reqs; count++)
00176   {
00177     trace_req_ptr = trace_req + count;
00178     if (! add_seisan_channel (trace_req_ptr->sta, trace_req_ptr->chan))
00179     {
00180       logit ("e", "SEIPA_init: error writing to Seisan output file\n");
00181       return EW_FAILURE;
00182     }
00183     if (debug)
00184     {
00185       logit ("e", "Channel %d/%d, %s %s %lf %lf\n",
00186              count, n_reqs, trace_req->sta,
00187              trace_req_ptr->chan, min_start_time,
00188              trace_req_ptr->reqStarttime);
00189     }
00190   }
00191 
00192   return EW_SUCCESS;
00193 
00194 }
00195 
00196 /*****************************************************************************
00197  * SEIPA_next
00198  *
00199  * Description: called once for each trace to be put away
00200  *
00201  * Input parameters: trace_req - the data to be stored
00202  *                   gap_thresh - size of any gap in seconds
00203  *                   debug - flag for debugging output
00204  * Output parameters: none
00205  * Returns: EW_SUCCESS or EW_FAILURE
00206  *
00207  * Comments: see pa_find_data()
00208  *
00209  *****************************************************************************/
00210 int SEIPA_next (TRACE_REQ *trace_req, double gap_thresh, int debug)
00211 
00212 {
00213 
00214   int status, loop_count;
00215   short short_val;
00216   long value, count;
00217   float float_val;
00218   double sample_time, double_val, data_end_time;
00219   char *data_ptr;
00220   struct Found_data data;
00221 
00222 
00223   if (debug) logit ("e", "Entering SEIPA_next\n");
00224 
00225   /* loop over the requested times for the data - the test for n_samples==0
00226    * is an emergency condition that could happen with very bad floating point
00227    * rounding errors (very unlikely though) */
00228   data.n_samples = 1;
00229   for (sample_time = trace_req->reqStarttime, loop_count = 0;
00230        (sample_time < trace_req->reqEndtime) && (data.n_samples > 0);
00231            sample_time += ((double) data.n_samples / data.sample_rate), loop_count ++)
00232   {
00233     /* get the data for this time */
00234     status = pa_find_data (trace_req, sample_time, &data);
00235     switch (status)
00236         {
00237     case FD_FOUND_REQUESTED:
00238     case FD_FOUND_GAP:
00239           break;
00240     case FD_NO_MORE_DATA:
00241       /* if no data has been found on previous calls, then exit
00242            * so that no data will be recorded for this channel */
00243           if (sample_time == trace_req->reqStarttime) return EW_SUCCESS;
00244 
00245           /* otherwise calculate the size of the gap to the end of requested data */
00246           data.n_samples = (long) (data.sample_rate * (trace_req->reqEndtime - sample_time));
00247           break;
00248 
00249     case FD_BAD_DATATYPE:
00250       logit("e", "SEIPA_next: unrecognised data type code, skipping this scn: %s.%s.%s\n",
00251             trace_req->sta, trace_req->chan, trace_req->net);
00252       return EW_FAILURE;
00253 
00254     case FD_CHANGED_SRATE:
00255       logit("e", "SEIPA_next: bad sample rate, skipping this scn: %s.%s.%s\n",
00256             trace_req->sta, trace_req->chan, trace_req->net);
00257       return EW_FAILURE;
00258         }
00259 
00260     /* adjust the number of samples to ensure it doesn't go beyond the end time */
00261         data_end_time = sample_time + ((double) data.n_samples / data.sample_rate);
00262         if (data_end_time > trace_req->reqEndtime)
00263           data.n_samples = (long) (data.sample_rate * (trace_req->reqEndtime - sample_time));
00264     if (debug) logit ("e", "Loop %d: %s %ld @ %.1lfHz, time %.3lf\n",
00265                       loop_count, status == FD_FOUND_REQUESTED ? "samples" : "gap",
00266                                           data.n_samples, data.sample_rate, sample_time);
00267 
00268     /* on the first time write the seisan channel header */
00269     if (sample_time == trace_req->reqStarttime)
00270         {
00271       if (! start_seisan_channel (trace_req->sta, trace_req->chan,
00272                                   sample_time, data.sample_rate,
00273                                   (long) (data.sample_rate * (trace_req->reqEndtime - trace_req->reqStarttime))))
00274           {
00275         logit ("e", "SEIPA_next: error starting new Seisan channel\n");
00276         return EW_FAILURE;
00277           }
00278         }
00279 
00280         /* write the data */
00281         value = SEISAN_MISSING_DATA_FLAG;
00282         data_ptr = data.data;
00283         for (count=0; count<data.n_samples; count++)
00284         {
00285           if (status == FD_FOUND_REQUESTED)
00286           {
00287                 switch (data.data_type_code)
00288                 {
00289                 /* write all values into longs regardless of input type */
00290                 case FD_SHORT_INT:
00291                   short_val = *((short *) data_ptr);
00292           value = (long) short_val;
00293                   data_ptr += sizeof (short);
00294                   break;
00295                 case FD_LONG_INT:
00296                   value = *((long *) data_ptr);
00297                   data_ptr += sizeof (long);
00298                   break;
00299                 case FD_FLOAT:
00300                   float_val = *((float *) data_ptr);
00301           value = (long) float_val;
00302                   data_ptr += sizeof (float);
00303                   break;
00304                 case FD_DOUBLE:
00305                   double_val = *((double *) data_ptr);
00306           value = (long) double_val;
00307                   data_ptr += sizeof (double);
00308                   break;
00309                 }
00310           }
00311       add_seisan_channel_data (1, &value);
00312         }
00313   }
00314 
00315   /* stop writing on this channel and fill in any gap at the end of the data */
00316   end_seisan_channel ();
00317 
00318   if (debug)
00319   {
00320     logit ("e", "Successful completion of SEIPA_next\n");
00321   }
00322   return EW_SUCCESS;
00323 
00324 }
00325 
00326 
00327 /************************************************************************
00328  * SEIPA_end_ev
00329  *
00330  * Description: called when an event has been completely processed
00331  *
00332  * Input parameters: debug - flag for debugging output
00333  * Output parameters: none
00334  * Returns: EW_SUCCESS or EW_FAILURE
00335  *
00336  * Comments:
00337  *
00338  *****************************************************************************/
00339 int SEIPA_end_ev (int debug)
00340 
00341 {
00342 
00343   int ret_val;
00344 
00345 
00346   if (debug)
00347   {
00348     logit ("e", "Entering SEIPA_end_ev\n");
00349   }
00350   ret_val = EW_SUCCESS;
00351 
00352   /* check and close the Seisan file */
00353   if (! close_seisan_file ())
00354   {
00355     logit ("e", "SEIPA_end_ev: error writing to Seisan file\n");
00356     ret_val = EW_FAILURE;
00357   }
00358 
00359   return ret_val;
00360 
00361 }
00362 
00363 /************************************************************************
00364  * SEIPA_close
00365  *
00366  * Description: called at program shutdown
00367  *
00368  * Input parameters: debug - flag for debugging output
00369  * Output parameters: none
00370  * Returns: EW_SUCCESS or EW_FAILURE
00371  *
00372  * Comments:
00373  *
00374  *****************************************************************************/
00375 int SEIPA_close (int debug)
00376 {
00377 
00378   if (debug)
00379   {
00380     logit ("e", "Entering SEIPA_close\n");
00381   }
00382 
00383   return EW_SUCCESS;
00384 
00385 }
00386 
00387 
00388 
00389 

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