source: trunk/src/libsrc/util/psn4putaway.c @ 2825

Revision 2825, 24.6 KB checked in by stefan, 12 years ago (diff)

linebreaks

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/* PSN4PutAway.c - Save data to PSN Type 4 Event Files
2   Created Dec 14 2005 by Larry Cochrane, Redwood City, PSN
3   Updated July 8 2006 - Replaced TRACE_HEADER with TRACE2_HEADER
4 */
5
6/************************************/
7/** #includes                      **/
8/************************************/
9#include <stdio.h>
10#include <stdlib.h>
11#include <string.h>
12#include <errno.h>
13#include <earthworm.h>
14#include <time.h>
15#include <trace_buf.h>
16#include <swap.h>
17#include <pa_subs.h>
18#include <time_ew.h>
19#include <psn4putaway.h>
20#include <math.h>
21
22static char *DataloggerString = "Earthworm 7.0";
23
24static PSNType4 PsnHeader;              /* header that get saves to disk */
25static long *BufferLong = 0;    /* buffer for storing output before writing */
26static short *BufferShort = 0;  /* write out data as short integers */
27static float *BufferFloat = 0;  /* write out data as float */
28static FILE *PsnFile = 0;               /* file pointer used to write out event file */
29static char FileName[256];              /* holds the file name we will be using */
30static char SaveDir[256];               /* holds the directory we wil be using */
31static int GoodData = 0;                /* used to check for deleting empty file */
32static char StaLocation[256];   /* station location string */
33static char SensorInfo[256];    /* sensor info string */
34static ChannelInfo ChanInfo;    /* holds additional info about the channel */
35
36static void MakeHdrTime( DateTime *, double );
37static void ReadStationFile( char *scnl, PSNType4 *hdr, int debug  );
38static void ParseLine( char *, char *, char * );
39static char *SkipSpace( char *string );
40static int Strib( char *string );
41static void SwapPsnHeader( PSNType4 * );
42static void SwapPsnVarHeader( VarHeader * );
43static void SwapChanInfo( ChannelInfo *);
44static WORD CalcFileCRC( FILE *fp, int length );
45static void CalcCRC16(WORD *crc, BYTE *cp, int cnt);
46
47/* Initialization function,
48*       This is the Put Away startup intializer. This is called when    *
49*       the system first comes up. Here is a chance to look around      *
50*       and see if it's possible to do business, and to complain        *
51*       if not ,BEFORE an event has to be processed.                    *
52*/
53int PSN4PA_init( long OutBufferLen, char *OutDir, char *OutputFormat, int debug )
54{
55        int len;
56
57        if( ( BufferLong = (long *)malloc( OutBufferLen * sizeof (char) ) ) == NULL )  {
58                logit ("et", "PSN4PA_init: couldn't malloc BufferLong\n");
59                return EW_FAILURE;
60        }
61        if( ( BufferFloat = (float *)malloc( OutBufferLen * sizeof (char) ) ) == NULL )  {
62                logit ("et", "PSN4PA_init: couldn't malloc BufferLong\n");
63                return EW_FAILURE;
64        }
65        if( ( BufferShort = (short *)malloc( OutBufferLen * sizeof (char) ) ) == NULL )  {
66                logit ("et", "PSN4PA_init: couldn't malloc BufferShort\n");
67                return EW_FAILURE;
68        }
69
70        strcpy( SaveDir, OutDir );
71
72        /* remove trailing '\' char in the directory string */
73        len = strlen( SaveDir );
74        if( len > 2 && ( SaveDir[len-1] == '\\' ||  SaveDir[len-1] == '/' ) )
75                SaveDir[len-1] = 0;
76
77        /* Make sure that the top level output directory exists */
78        CreateDir( SaveDir );
79
80        return EW_SUCCESS;
81}
82
83/****************************************************************************
84* This is the Put Away event initializer. It's called when a snippet        *
85* has been received, and is about to be processed.                                                      *
86* It gets to see the pointer to the TraceRequest array,                                         *
87* and the number of loaded trace structures.                                                            *
88*****************************************************************************/
89int PSN4PA_next_ev( TRACE_REQ *ptrReq, char *EventDate, char *EventTime, int debug )
90{
91        char toDir[256], fname[256];
92
93        sprintf( toDir, "%s\\%-4.4s", SaveDir, &EventDate[2] );
94        CreateDir( toDir );
95
96        sprintf( fname, "%s\\%-6.6s.%-6.6s.%s.%s.psn", toDir, &EventDate[2], EventTime,
97                ptrReq->sta, ptrReq->chan );
98
99        if( debug == 1 )
100                logit ("t", "Opening PSN Type 4 file %s\n", fname );
101
102        if( ! ( PsnFile = fopen( fname, "w+b" ) ) )  {
103                logit ("et", "PSN4PA_init: couldn't open output file %s\n", fname );
104                return EW_FAILURE;
105        }
106        strcpy( FileName, fname );
107        GoodData = 0;
108        return(EW_SUCCESS);
109}
110
111/*****************************************************************************
112 * This is the working entry point into the disposal system. This routine        *
113 * gets called for each trace snippet which has been recovered. It gets          *
114 * to see the corresponding SNIPPET structure, and the event id                          *
115 *****************************************************************************/
116/* Process one channel of data */
117int PSN4PA_next( TRACE_REQ *getThis, double GapThresh, long OutBufferLen, int debug)
118{
119        TRACE2_HEADER *wf;
120        PSNType4 *hdr = &PsnHeader;
121        short *s_data, s;
122        long *l_data, l;
123        float *f_data, f;
124        char *msg_p;                            /* pointer into tracebuf data */
125        char datatype;
126        int qual, j, data_size;
127        int gap_count = 0;
128        long nsamp, nfill;
129        long nfill_max = 0l;
130        long nsamp_this_scnl = 0l;
131        long this_size;
132        double begintime, starttime, endtime;
133        double samprate;
134        long fill = 0l;
135        char scnl[80];
136        double min, max, mean;
137        int len, varLen, crcLen;
138        VarHeader varHdr;
139        int swap = FALSE;
140        WORD crc;
141
142#if defined (_SPARC)
143        swap = TRUE;
144#endif
145
146        /* Check arguments */
147        if( getThis == NULL )  {
148                logit ("e", "PSN4PA_next: invalid argument passed in.\n");
149                return EW_FAILURE;
150        }
151
152        memset( hdr, 0, sizeof( PSNType4 ) );
153
154        if( (msg_p = getThis->pBuf) == NULL )  {         /* pointer to first message */
155                logit ("e", "PSN4PA_next: Message buffer is NULL.\n");
156                return EW_FAILURE;
157        }
158        wf = (TRACE2_HEADER *)msg_p;
159
160        /* Look at the first TRACE2_HEADER and get set up of action */
161        if (WaveMsg2MakeLocal(wf) < 0)  {
162                logit("e", "PSN4PA_next: unknown trace data type: %s\n", wf->datatype);
163                return( EW_FAILURE );
164        }
165        nsamp = wf->nsamp;
166        starttime = wf->starttime;
167        endtime = wf->endtime;
168        samprate = wf->samprate;
169        if (samprate < 0.01 ) {
170                logit("et", "unreasonable sample rate (%f) for <%s.%s.%s>\n", samprate,
171                        wf->sta, wf->chan, wf->net);
172                return( EW_FAILURE );
173        }
174        begintime = starttime;
175        datatype = 'n';
176        if( wf->datatype[0] == 's' || wf->datatype[0] == 'i' )  {
177                if(wf->datatype[1] == '2')
178                        datatype = 's';
179                else if(wf->datatype[1] == '4')
180                        datatype = 'l';
181        }
182        else if( wf->datatype[0] == 't' || wf->datatype[0] == 'f' && wf->datatype[1] == '4' )
183                datatype = 'f';
184
185        if (datatype == 'n')  {
186                logit("et", "PSN4PA_next: unsupported datatype: %s\n", datatype);
187                return( EW_FAILURE );
188        }
189
190        if (debug == 1)
191                logit("et", "PSN4PA_next: working on <%s/%s/%s> datatype: %c\n",
192                        wf->sta, wf->chan, wf->net, datatype );
193
194        min = 999999999.0;
195        max = -999999999.0;
196        mean = 0.0;
197
198        /* loop through all the messages for this s-c-n */
199        while (1) {
200                /* advance message pointer to the data */
201                msg_p += sizeof(TRACE2_HEADER);
202
203                /* check for sufficient memory in output buffer */
204                this_size = (nsamp_this_scnl + nsamp ) * sizeof(long);
205                if ( OutBufferLen < this_size )  {
206                        logit( "e", "out of space for <%s.%s.%s>; saving long trace.\n",
207                                 wf->sta, wf->chan, wf->net);
208                        break;
209                }
210
211                switch( datatype )
212                {
213                case 's':
214                        s_data = (short *)msg_p;
215                        for ( j = 0; j < nsamp ; j++, nsamp_this_scnl++ )  {
216                                s = s_data[j];
217                                if( s > max )
218                                        max = s;
219                                if( s < min )
220                                        min = s;
221                                mean += s;
222                                BufferLong[nsamp_this_scnl] = (long)s;
223                        }
224                        msg_p += sizeof(short) * nsamp;
225                        break;
226                case 'l':
227                        l_data = (long *)msg_p;
228                        for ( j = 0; j < nsamp; j++, nsamp_this_scnl++ )  {
229                                l = l_data[j];
230                                if( l > max )
231                                        max = l;
232                                if( l < min )
233                                        min = l;
234                                BufferLong[nsamp_this_scnl] = l;
235                        }
236                        msg_p += sizeof(long) * nsamp;
237                        break;
238                case 'f':
239                        f_data = (float *)msg_p;
240                        for ( j = 0; j < nsamp; j++, nsamp_this_scnl++ )  {
241                                f = f_data[j];
242                                if( f > max )
243                                        max = f;
244                                if( f < min )
245                                        min = f;
246                                BufferFloat[nsamp_this_scnl] = f;
247                        }
248                        msg_p += sizeof(float) * nsamp;
249                        break;
250                }
251
252                /* End-check based on length of snippet buffer */
253                if ((long) msg_p >= ((long) getThis->actLen + (long) getThis->pBuf) )  {
254                        if (debug == 1)
255                                logit ("", "Setting done for <%s.%s.%s>\n", wf->sta, wf->chan, wf->net);
256                        break; /* Break out of the while(1) loop 'cuz we're done */
257                }
258
259                /* msg_p has been advanced to the next TRACE_BUF; localize bytes *
260                 * and check for gaps.  */
261                wf = (TRACE2_HEADER *) msg_p;
262                if (WaveMsg2MakeLocal(wf) < 0)  {
263                        logit("e", "PSN4PA_next: unknown trace data type: %s\n",
264                                                wf->datatype);
265                        return( EW_FAILURE );
266                }
267                qual = wf->quality[0];          // Get time reference quality
268                nsamp = wf->nsamp;
269                starttime = wf->starttime;
270                /* starttime is set for new packet; endtime is still set for old packet */
271                if ( endtime + ( 1.0/samprate ) * GapThresh < starttime ) {
272                        /* there's a gap, so fill it */
273                        logit("e", "gap in %s.%s.%s: %lf: %lf\n", wf->sta, wf->chan, wf->net,
274                                                endtime, starttime - endtime);
275                        nfill = (long) (samprate * (starttime - endtime) - 1);
276                        if ( (nsamp_this_scnl + nfill) * (long)sizeof(long) > OutBufferLen ) {
277                                logit("e",
278                                                        "bogus gap (%d); skipping\n", nfill);
279                                return(EW_FAILURE);
280                        }
281                        /* do the filling */
282                        for ( j = 0; j < nfill; j++, nsamp_this_scnl ++ )
283                                BufferLong[nsamp_this_scnl] = fill;
284                        /* keep track of how many gaps and the largest one */
285                        gap_count++;
286                        if (nfill_max < nfill)
287                                nfill_max = nfill;
288                }
289                /* Advance endtime to the new packet;                           *
290                 * process this packet in the next iteration */
291                endtime = wf->endtime;
292        } /* while(1) */
293
294        if ( datatype == 's' )  {
295                for (j = 0; j < nsamp_this_scnl; j++)
296                        BufferShort[j] = (short)BufferLong[j];
297        }
298
299        /* now make the PSN header */
300        memcpy(hdr->headerID, "PSNTYPE4", 8);
301
302        /* Make the SCN test string and then try and find it in the station.lst file */
303        sprintf(scnl, "%s.%s.%s.%s", wf->sta, wf->chan, wf->net, wf->loc );
304        ReadStationFile( scnl, hdr, debug );
305
306        /* set the time of the first sample of data */
307        MakeHdrTime( &hdr->startTime, begintime );
308
309        /* calculate the size of the variable header section of the event file */
310        varLen = 0;
311        if( len = strlen( StaLocation) )
312                varLen += ( len + 1 + sizeof( VarHeader) );
313        if( len = strlen( SensorInfo) )
314                varLen += ( len + 1 + sizeof( VarHeader) );
315        if( ChanInfo.sensorOutVolt != 0.0 || ChanInfo.ampGain != 0.0 ||
316                        ChanInfo.adcInputVolt != 0.0 )
317                varLen += ( sizeof( ChannelInfo ) + sizeof( VarHeader ) );
318        if( len = strlen( DataloggerString ) )
319                varLen += ( len + 1 + sizeof( VarHeader) );
320        hdr->variableHdrLength = varLen;
321        hdr->sampleCount = nsamp_this_scnl;
322        hdr->spsRate = wf->samprate;
323        hdr->maximum = max;
324        hdr->minimum = min;
325        hdr->mean = mean / (double)nsamp_this_scnl;
326        if( ! (qual & TIME_TAG_QUESTIONABLE) )
327                hdr->timeRefStatus = 'L';
328        if( datatype == 's' )
329                hdr->sampleType = 0;
330        else if( datatype == 'l' )
331                hdr->sampleType = 1;
332        else
333                hdr->sampleType = 2;
334
335        if( strlen( wf->sta ) >= 6)
336                strncpy(hdr->name, wf->sta, 6 );
337        else
338                strcpy(hdr->name, wf->sta );
339
340        if( strlen( wf->chan ) >= 3 )
341                strncpy(hdr->compName, wf->chan, 3 );
342        else
343                strcpy(hdr->compName, wf->chan );
344
345        if( strlen( wf->net ) >= 6 )
346                strncpy(hdr->network, wf->net, 6);
347        else
348                strcpy( hdr->network, wf->net );
349
350        if( datatype == 's' )
351                data_size = nsamp_this_scnl * sizeof(short);
352        else if( datatype == 'l')
353                data_size = nsamp_this_scnl * sizeof(long);
354        else
355                data_size = nsamp_this_scnl * sizeof(float);
356
357        crcLen = sizeof( PSNType4 ) + hdr->variableHdrLength + data_size;
358
359        if( swap )
360                SwapPsnHeader( hdr );
361
362        /* now write the main header */
363        if( fwrite( (void *)hdr, 1, sizeof(PSNType4), PsnFile ) != sizeof(PSNType4) )  {
364                logit ("et", "PSN4PA_next: error writing PSN4 Header. \n");
365                return EW_FAILURE;
366        }
367
368        /* now save any variable header blocks */
369        if( len = strlen( StaLocation ) )  {
370                ++len;
371                varHdr.checkNumber = 0x55;
372                varHdr.id = 1;
373                varHdr.length = len;
374                if( swap )
375                        SwapPsnVarHeader( &varHdr );
376                if(fwrite(&varHdr, 1, sizeof(VarHeader), PsnFile ) != (UINT)sizeof(VarHeader) )  {
377                        logit ("et", "PSN4PA_next: error writing PSN4 Header. \n");
378                        return EW_FAILURE;
379                }
380                if(fwrite( StaLocation, 1, len, PsnFile ) != (UINT)len )  {
381                        logit ("et", "PSN4PA_next: error writing PSN4 Header. \n");
382                        return EW_FAILURE;
383                }
384        }
385
386        if( len = strlen( SensorInfo ) )  {
387                ++len;
388                varHdr.checkNumber = 0x55;
389                varHdr.id = 2;
390                varHdr.length = len;
391                if( swap )
392                        SwapPsnVarHeader( &varHdr );
393                if(fwrite(&varHdr, 1, sizeof(VarHeader), PsnFile ) != (UINT)sizeof(VarHeader) )  {
394                        logit ("et", "PSN4PA_next: error writing PSN4 Header. \n");
395                        return EW_FAILURE;
396                }
397                if( fwrite( SensorInfo, 1, len, PsnFile ) != (UINT)len )  {
398                        logit ("et", "PSN4PA_next: error writing PSN4 Header. \n");
399                        return EW_FAILURE;
400                }
401        }
402
403        if( len = strlen( DataloggerString ) )  {
404                ++len;
405                varHdr.checkNumber = 0x55;
406                varHdr.id = 7;
407                varHdr.length = len;
408                if( swap )
409                        SwapPsnVarHeader( &varHdr );
410                if(fwrite(&varHdr, 1, sizeof(VarHeader), PsnFile ) != (UINT)sizeof(VarHeader) )  {
411                        logit ("et", "PSN4PA_next: error writing PSN4 Header. \n");
412                        return EW_FAILURE;
413                }
414                if( fwrite( DataloggerString, 1, len, PsnFile ) != (UINT)len )  {
415                        logit ("et", "PSN4PA_next: error writing PSN4 Header. \n");
416                        return EW_FAILURE;
417                }
418        }
419
420        if( ChanInfo.sensorOutVolt != 0.0 || ChanInfo.ampGain != 0.0 ||
421                                ChanInfo.adcInputVolt != 0.0 )  {
422                varHdr.checkNumber = 0x55;
423                varHdr.id = 11;
424                varHdr.length = sizeof( ChannelInfo );
425                if( swap )
426                        SwapPsnVarHeader( &varHdr );
427                if(fwrite(&varHdr, 1, sizeof(VarHeader), PsnFile ) != sizeof( VarHeader ) )  {
428                        logit ("et", "PSN4PA_next: error writing PSN4 Header. \n");
429                        return EW_FAILURE;
430                }
431                if( swap )
432                        SwapChanInfo( &ChanInfo );
433
434                if( fwrite( &ChanInfo, 1, sizeof( ChannelInfo ), PsnFile ) != sizeof( ChannelInfo ) )  {
435                        logit ("et", "PSN4PA_next: error writing PSN4 Header. \n");
436                        return EW_FAILURE;
437                }
438        }
439
440        /* Convert to the appropriate output format */
441        if( swap )  {
442                /* we are on sparc, data will be read on intel */
443                for (j = 0; j < nsamp_this_scnl; j++)  {
444                        if(datatype == 's' )
445                                SwapShort( &BufferShort[j] );
446                        else if( datatype == 'l' )
447                                SwapLong( &BufferLong[j] );
448                        else if( datatype == 'f' )
449                                SwapFloat( &BufferFloat[j] );
450                }
451        }
452
453        if (debug == 1 )
454            logit ("", "Writing %d bytes of trace data\n", data_size );
455
456        if( datatype == 's' )  {
457                if ((long)fwrite ((void *) BufferShort, sizeof (char), data_size, PsnFile ) !=
458                                data_size )  {
459                        logit ("et", "PSN4PA_next: error writing short TRACE data. \n");
460                        return EW_FAILURE;
461                }
462        }
463        else if( datatype == 'l' ) {
464                if( (long)fwrite ((void *) BufferLong, sizeof (char), data_size, PsnFile ) !=
465                                data_size )  {
466                        logit ("et", "PSN4PA_next: error writing long TRACE data. \n");
467                        return EW_FAILURE;
468                }
469        }
470        else  {         // write out float data
471                if( (long)fwrite ((void *) BufferFloat, sizeof (char), data_size, PsnFile ) !=
472                                data_size )  {
473                        logit ("et", "PSN4PA_next: error writing long TRACE data. \n");
474                        return EW_FAILURE;
475                }
476        }
477
478        crc = CalcFileCRC( PsnFile, crcLen );
479        if( swap )
480                SwapShort( &crc );
481        if( fwrite(&crc, 1, sizeof(short), PsnFile ) != sizeof(short))
482                logit ("et", "PSN4PA_next: error writing crc. \n");
483        GoodData = TRUE;
484        return EW_SUCCESS;
485}
486
487/************************************************************************
488* This is the Put Away end event routine. It's called after we've               *
489* finished processing one event.                                                                                *
490*************************************************************************/
491int PSN4PA_end_ev(int debug)
492{
493        if( debug == 1 )
494                        logit("t", "Closing PSN Type 4 file \n");
495        if( PsnFile )
496                fclose( PsnFile );
497        PsnFile = 0;
498        if( !GoodData )
499                unlink( FileName );
500        return(EW_SUCCESS);
501}
502
503
504/************************************************************************
505* This is the Put Away close routine. It's called after when            *
506* we're being shut down.                                                                                    *
507*************************************************************************/
508int PSN4PA_close(int debug)
509{
510        if( BufferLong )
511                free( (char *)BufferLong );
512        if( BufferShort )
513                free( (char *)BufferShort );
514        if( BufferFloat )
515                free( (char *)BufferFloat );
516
517        return(EW_SUCCESS);
518}
519
520/* Make a PSN Type 4 header time based on the start time  */
521static void MakeHdrTime( DateTime *ti, double startTime )
522{
523        struct tm *tme;
524        time_t ltime = (time_t)startTime;
525        double frac, secs;
526
527        /* gmt time makes months from 0 - 11 */
528        tme = gmtime( &ltime );
529        ti->year = (WORD)tme->tm_year + 1900;
530        ti->month = (char)(tme->tm_mon + 1);
531        ti->day = (char)tme->tm_mday;
532        ti->hour = (char)tme->tm_hour;
533        ti->minute = (char)tme->tm_min;
534        ti->second = (char)tme->tm_sec;
535        frac = modf( startTime, &secs );
536        ti->nanoseconds = (int)( frac * 1000000000 );
537}
538
539/* Read the station.lst file. This file is currently located
540   in the directory defined by the system variable "EW_PARAMS" */
541static void ReadStationFile( char *scnl, PSNType4 *hdr, int debug  )
542{
543        char *dir = getenv( "EW_PARAMS" ), buff[256], fname[256];
544        char scnlSearch[64], key[256], data[256], *ptr;
545        int found = 0;
546        FILE *fp;
547
548        StaLocation[0] = SensorInfo[0] = 0;
549        ChanInfo.sensorOutVolt = ChanInfo.ampGain = ChanInfo.adcInputVolt;
550
551        if( debug )
552                logit("", "Start ReadStationFile - Looking for %s\n", scnl );
553
554        if( !dir )  {
555                if( debug == 1 )
556                        logit("e", "Environment variable EW_PARAMS not found\n");
557                return;
558        }
559
560        /* Make the file name and try and open the file */
561        sprintf(fname, "%s\\station.lst", dir );
562        if( ! (fp = fopen( fname, "r" ) ) )  {
563                if( debug == 1 )
564                        logit("e", "Station information file %s not found\n", fname );
565                return;
566        }
567
568        /* Make the search string and then look for the SCNL in the file */
569        sprintf( scnlSearch, "[%s]", scnl );
570        while( fgets( buff, 256, fp ) )   {
571                if( buff[0] == '#' || buff[0] == ';' || buff[0] == '!' )
572                        continue;
573                Strib( buff );
574                ptr = SkipSpace( buff );
575                if( strcmp( scnlSearch, ptr ) )
576                        continue;
577                found = TRUE;
578                break;
579        }
580        if( !found )  {
581                fclose( fp );
582                if( debug )
583                        logit("e", "Station information not found\n" );
584                return;
585        }
586
587        if( debug )
588                logit("e", "Station information found\n" );
589
590        /* We found the SCNL so now get the key=data pairs from the file */
591        while( fgets( buff, 256, fp ) )  {
592                if( buff[0] == '#' || buff[0] == ';' || buff[0] == '!' )        // comment
593                        continue;
594                Strib( buff );
595                ptr = SkipSpace( buff );
596                if( ptr[0] == '[' )                             // if next SCNL we are done.
597                        break;
598
599                ParseLine( key, data, ptr );    // get key and data
600
601                if( !strcmp( key, "latitude" ) )  {
602                        hdr->latitude = atof( data );
603                        continue;
604                }
605                if( !strcmp( key, "longitude" ) )  {
606                        hdr->longitude = atof( data );
607                        continue;
608                }
609                if( !strcmp( key, "elevation" ) )  {
610                        hdr->elevation = atof( data );
611                        continue;
612                }
613                if( !strcmp( key, "orientation" ) )  {
614                        hdr->compOrientation = data[0];
615                        continue;
616                }
617                if( !strcmp( key, "incident" ) )  {
618                        hdr->compIncident = atof( data );
619                        continue;
620                }
621                if( !strcmp( key, "azimuth" ) )  {
622                        hdr->compAzimuth = atof( data );
623                        continue;
624                }
625                if( !strcmp( key, "sensortype" ) )  {
626                        if( data[0] == 'A' )
627                                hdr->sensorType = 1;
628                        else if( data[0] == 'V' )
629                                hdr->sensorType = 2;
630                        else if( data[0] == 'D' )
631                                hdr->sensorType = 3;
632                        continue;
633                }
634                if( !strcmp( key, "sensitivity" ) )  {
635                        hdr->sensitivity = atof( data );
636                        continue;
637                }
638                if( !strcmp( key, "referencetype" ) )  {
639                        hdr->timeRefType[0] = data[0];
640                        hdr->timeRefType[1] = data[1];
641                        hdr->timeRefType[2] = data[2];
642                        continue;
643                }
644                if( !strcmp( key, "adbits" ) )  {
645                        hdr->atodBits = (short)atoi( data );
646                        continue;
647                }
648                if( !strcmp( key, "magcorrection" ) )  {
649                        hdr->magCorr = atof( data );
650                        continue;
651                }
652                if( !strcmp( key, "stationlocation" ) )  {
653                        strcpy( StaLocation, data );
654                        continue;
655                }
656                if( !strcmp( key, "sensorInformation" ) )  {
657                        strcpy( SensorInfo, data );
658                        continue;
659                }
660                if( !strcmp( key, "sensoroutputvoltage" ) )  {
661                        ChanInfo.sensorOutVolt = atof( data );
662                        continue;
663                }
664                if( !strcmp( key, "amplifiergain" ) )  {
665                        ChanInfo.ampGain = atof( data );
666                        continue;
667                }
668                if( !strcmp( key, "adcinputvoltage" ) )  {
669                        ChanInfo.adcInputVolt = atof( data );
670                        continue;
671                }
672                if( debug )
673                        logit("", "Unknown Key in station.lst file = %s\n", key );
674        }
675        fclose( fp );
676}
677
678/* Parse the line from the ReadStationFile above. Returns the key and data
679   parts of the string */
680void ParseLine( char *key, char *data, char *string )
681{
682        char *ptr;
683
684        *key = 0;
685        *data = 0;
686        ptr = strchr( string, '=' );    // find the = between key and data
687        if( ptr == NULL )
688                return;
689        *ptr = 0;
690        strcpy( key, string );                  // get the key
691        Strib( key );
692        strlwr( key );
693        ++ptr;
694        ptr = SkipSpace( ptr );
695        strcpy( data, ptr );                    // get the data
696}
697
698/* Skip any white spaces in a string */
699static char *SkipSpace( char *string )
700{
701        while( *string )  {
702                if( *string != ' ' && *string != '\t' )
703                        return string;
704                ++string;
705        }
706        return string;
707}
708
709/* Strip trailing blanks and newlines from string. */
710static int Strib( char *string )
711{
712        int i, length;
713
714        length = strlen( string );
715        if ( length )  {
716    for ( i = length-1; i >= 0; i-- )  {
717                if ( string[i] == ' ' || string[i] == '\n' || string[i] == '\r' )
718                        string[i] = '\0';
719        else
720                        return ( i+1 );
721        }
722        }
723        else
724        return length;
725        return i+1;
726}
727
728/* Swap the main PSN Type 4 header information structure */
729static void SwapPsnHeader( PSNType4 *hdr )
730{
731        SwapLong( &hdr->variableHdrLength );
732        SwapShort( &hdr->startTime.year );
733        SwapLong( &hdr->startTime.nanoseconds );
734        SwapDouble( &hdr->startTimeOffset );
735        SwapDouble( &hdr->spsRate );
736        SwapLong( &hdr->sampleCount );
737        SwapLong( &hdr->flags );
738        SwapDouble( &hdr->compIncident );
739        SwapDouble( &hdr->compAzimuth );
740        SwapDouble( &hdr->latitude );
741        SwapDouble( &hdr->longitude );
742        SwapDouble( &hdr->elevation );
743        SwapDouble( &hdr->sensitivity );
744        SwapDouble( &hdr->magCorr );
745        SwapShort( &hdr->atodBits );
746        SwapDouble( &hdr->minimum );
747        SwapDouble( &hdr->maximum );
748        SwapDouble( &hdr->mean );
749}
750
751/* Swap the variable header information structure */
752static void SwapPsnVarHeader( VarHeader *var )
753{
754        SwapLong( &var->length );
755}
756
757/* Swap the channel information structure */
758static void SwapChanInfo( ChannelInfo *chan )
759{
760        SwapDouble( &chan->sensorOutVolt );
761        SwapDouble( &chan->ampGain );
762        SwapDouble( &chan->adcInputVolt );
763}
764
765/* The following are used to calculate the CRC of the event file */
766
767static WORD CalcFileCRC( FILE *fp, int length )
768{
769        BYTE buff[512];
770        WORD crc = 0;
771        int cnt, len;
772        long pos = ftell(fp);
773
774        fseek(fp, 0, SEEK_SET);
775        while( length )  {
776                if( length > 512 )
777                        len = 512;
778                else
779                        len = length;
780                cnt = fread( buff, 1, len, fp );
781                if( !cnt )
782                        logit("e", "Error calculating PSN file CRC. Read error\n");
783                CalcCRC16( &crc, buff, cnt );
784                length -= len;
785        }
786        fseek(fp, pos, SEEK_SET);
787        return crc ;
788}
789
790#define P       0x1021
791#define W       16
792#define B       8
793
794static WORD crctab[1 << B] = {
795    0x0000,  0x1021,  0x2042,  0x3063,  0x4084,  0x50a5,  0x60c6,  0x70e7,
796    0x8108,  0x9129,  0xa14a,  0xb16b,  0xc18c,  0xd1ad,  0xe1ce,  0xf1ef,
797    0x1231,  0x0210,  0x3273,  0x2252,  0x52b5,  0x4294,  0x72f7,  0x62d6,
798    0x9339,  0x8318,  0xb37b,  0xa35a,  0xd3bd,  0xc39c,  0xf3ff,  0xe3de,
799    0x2462,  0x3443,  0x0420,  0x1401,  0x64e6,  0x74c7,  0x44a4,  0x5485,
800    0xa56a,  0xb54b,  0x8528,  0x9509,  0xe5ee,  0xf5cf,  0xc5ac,  0xd58d,
801    0x3653,  0x2672,  0x1611,  0x0630,  0x76d7,  0x66f6,  0x5695,  0x46b4,
802    0xb75b,  0xa77a,  0x9719,  0x8738,  0xf7df,  0xe7fe,  0xd79d,  0xc7bc,
803    0x48c4,  0x58e5,  0x6886,  0x78a7,  0x0840,  0x1861,  0x2802,  0x3823,
804    0xc9cc,  0xd9ed,  0xe98e,  0xf9af,  0x8948,  0x9969,  0xa90a,  0xb92b,
805    0x5af5,  0x4ad4,  0x7ab7,  0x6a96,  0x1a71,  0x0a50,  0x3a33,  0x2a12,
806    0xdbfd,  0xcbdc,  0xfbbf,  0xeb9e,  0x9b79,  0x8b58,  0xbb3b,  0xab1a,
807    0x6ca6,  0x7c87,  0x4ce4,  0x5cc5,  0x2c22,  0x3c03,  0x0c60,  0x1c41,
808    0xedae,  0xfd8f,  0xcdec,  0xddcd,  0xad2a,  0xbd0b,  0x8d68,  0x9d49,
809    0x7e97,  0x6eb6,  0x5ed5,  0x4ef4,  0x3e13,  0x2e32,  0x1e51,  0x0e70,
810    0xff9f,  0xefbe,  0xdfdd,  0xcffc,  0xbf1b,  0xaf3a,  0x9f59,  0x8f78,
811    0x9188,  0x81a9,  0xb1ca,  0xa1eb,  0xd10c,  0xc12d,  0xf14e,  0xe16f,
812    0x1080,  0x00a1,  0x30c2,  0x20e3,  0x5004,  0x4025,  0x7046,  0x6067,
813    0x83b9,  0x9398,  0xa3fb,  0xb3da,  0xc33d,  0xd31c,  0xe37f,  0xf35e,
814    0x02b1,  0x1290,  0x22f3,  0x32d2,  0x4235,  0x5214,  0x6277,  0x7256,
815    0xb5ea,  0xa5cb,  0x95a8,  0x8589,  0xf56e,  0xe54f,  0xd52c,  0xc50d,
816    0x34e2,  0x24c3,  0x14a0,  0x0481,  0x7466,  0x6447,  0x5424,  0x4405,
817    0xa7db,  0xb7fa,  0x8799,  0x97b8,  0xe75f,  0xf77e,  0xc71d,  0xd73c,
818    0x26d3,  0x36f2,  0x0691,  0x16b0,  0x6657,  0x7676,  0x4615,  0x5634,
819    0xd94c,  0xc96d,  0xf90e,  0xe92f,  0x99c8,  0x89e9,  0xb98a,  0xa9ab,
820    0x5844,  0x4865,  0x7806,  0x6827,  0x18c0,  0x08e1,  0x3882,  0x28a3,
821    0xcb7d,  0xdb5c,  0xeb3f,  0xfb1e,  0x8bf9,  0x9bd8,  0xabbb,  0xbb9a,
822    0x4a75,  0x5a54,  0x6a37,  0x7a16,  0x0af1,  0x1ad0,  0x2ab3,  0x3a92,
823    0xfd2e,  0xed0f,  0xdd6c,  0xcd4d,  0xbdaa,  0xad8b,  0x9de8,  0x8dc9,
824    0x7c26,  0x6c07,  0x5c64,  0x4c45,  0x3ca2,  0x2c83,  0x1ce0,  0x0cc1,
825    0xef1f,  0xff3e,  0xcf5d,  0xdf7c,  0xaf9b,  0xbfba,  0x8fd9,  0x9ff8,
826    0x6e17,  0x7e36,  0x4e55,  0x5e74,  0x2e93,  0x3eb2,  0x0ed1,  0x1ef0
827};
828
829static void CalcCRC16(WORD *crc, BYTE *cp, int cnt)
830{
831        while(cnt--)
832                *crc = (*crc << B) ^ crctab[(*crc>>(W - B)) ^ *cp++];
833}
Note: See TracBrowser for help on using the repository browser.