📄 traceutils.c
字号:
*src++ = '_'; *src++ = mst->dataquality; } *src = '\0'; return srcname;} /* End of mst_srcname() *//*************************************************************************** * mst_printtracelist: * * Print trace list summary information for the specified MSTraceGroup. * * By default only print the srcname, starttime and endtime for each * trace. If details is greater than 0 include the sample rate, * number of samples and a total trace count. If gaps is greater than * 0 and the previous trace matches (srcname & samprate) include the * gap between the endtime of the last trace and the starttime of the * current trace. * * The timeformat flag can either be: * 0 : SEED time format (year, day-of-year, hour, min, sec) * 1 : ISO time format (year, month, day, hour, min, sec) * 2 : Epoch time, seconds since the epoch ***************************************************************************/voidmst_printtracelist ( MSTraceGroup *mstg, flag timeformat, flag details, flag gaps ){ MSTrace *mst = 0; char srcname[50]; char prevsrcname[50]; char stime[30]; char etime[30]; char gapstr[20]; flag nogap; double gap; double delta; double prevsamprate; hptime_t prevendtime; int tracecnt = 0; if ( ! mstg ) { return; } mst = mstg->traces; /* Print out the appropriate header */ if ( details > 0 && gaps > 0 ) ms_log (0, " Source Start sample End sample Gap Hz Samples\n"); else if ( details <= 0 && gaps > 0 ) ms_log (0, " Source Start sample End sample Gap\n"); else if ( details > 0 && gaps <= 0 ) ms_log (0, " Source Start sample End sample Hz Samples\n"); else ms_log (0, " Source Start sample End sample\n"); prevsrcname[0] = '\0'; prevsamprate = -1.0; prevendtime = 0; while ( mst ) { mst_srcname (mst, srcname, 1); /* Create formatted time strings */ if ( timeformat == 2 ) { snprintf (stime, sizeof(stime), "%.6f", (double) MS_HPTIME2EPOCH(mst->starttime) ); snprintf (etime, sizeof(etime), "%.6f", (double) MS_HPTIME2EPOCH(mst->endtime) ); } else if ( timeformat == 1 ) { if ( ms_hptime2isotimestr (mst->starttime, stime, 1) == NULL ) ms_log (2, "Cannot convert trace start time for %s\n", srcname); if ( ms_hptime2isotimestr (mst->endtime, etime, 1) == NULL ) ms_log (2, "Cannot convert trace end time for %s\n", srcname); } else { if ( ms_hptime2seedtimestr (mst->starttime, stime, 1) == NULL ) ms_log (2, "Cannot convert trace start time for %s\n", srcname); if ( ms_hptime2seedtimestr (mst->endtime, etime, 1) == NULL ) ms_log (2, "Cannot convert trace end time for %s\n", srcname); } /* Print trace info at varying levels */ if ( gaps > 0 ) { gap = 0.0; nogap = 0; if ( ! strcmp (prevsrcname, srcname) && prevsamprate != -1.0 && MS_ISRATETOLERABLE (prevsamprate, mst->samprate) ) gap = (double) (mst->starttime - prevendtime) / HPTMODULUS; else nogap = 1; /* Check that any overlap is not larger than the trace coverage */ if ( gap < 0.0 ) { delta = ( mst->samprate ) ? (1.0 / mst->samprate) : 0.0; if ( (gap * -1.0) > (((double)(mst->endtime - mst->starttime)/HPTMODULUS) + delta) ) gap = -(((double)(mst->endtime - mst->starttime)/HPTMODULUS) + delta); } /* Fix up gap display */ if ( nogap ) snprintf (gapstr, sizeof(gapstr), " == "); else if ( gap >= 86400.0 || gap <= -86400.0 ) snprintf (gapstr, sizeof(gapstr), "%-3.1fd", (gap / 86400)); else if ( gap >= 3600.0 || gap <= -3600.0 ) snprintf (gapstr, sizeof(gapstr), "%-3.1fh", (gap / 3600)); else if ( gap == 0.0 ) snprintf (gapstr, sizeof(gapstr), "-0 "); else snprintf (gapstr, sizeof(gapstr), "%-4.4g", gap); if ( details <= 0 ) ms_log (0, "%-17s %-24s %-24s %-4s\n", srcname, stime, etime, gapstr); else ms_log (0, "%-17s %-24s %-24s %-s %-3.3g %-d\n", srcname, stime, etime, gapstr, mst->samprate, mst->samplecnt); } else if ( details > 0 && gaps <= 0 ) ms_log (0, "%-17s %-24s %-24s %-3.3g %-d\n", srcname, stime, etime, mst->samprate, mst->samplecnt); else ms_log (0, "%-17s %-24s %-24s\n", srcname, stime, etime); if ( gaps > 0 ) { strcpy (prevsrcname, srcname); prevsamprate = mst->samprate; prevendtime = mst->endtime; } tracecnt++; mst = mst->next; } if ( tracecnt != mstg->numtraces ) ms_log (2, "mst_printtracelist(): number of traces in trace group is inconsistent\n"); if ( details > 0 ) ms_log (0, "Total: %d trace(s)\n", tracecnt); } /* End of mst_printtracelist() *//*************************************************************************** * mst_printgaplist: * * Print gap/overlap list summary information for the specified * MSTraceGroup. Overlaps are printed as negative gaps. The trace * summary information in the MSTraceGroup is logically inverted so gaps * for like channels are identified. * * If mingap and maxgap are not NULL their values will be enforced and * only gaps/overlaps matching their implied criteria will be printed. * * The timeformat flag can either be: * 0 : SEED time format (year, day-of-year, hour, min, sec) * 1 : ISO time format (year, month, day, hour, min, sec) * 2 : Epoch time, seconds since the epoch ***************************************************************************/voidmst_printgaplist (MSTraceGroup *mstg, flag timeformat, double *mingap, double *maxgap){ MSTrace *mst, *pmst; char src1[50], src2[50]; char time1[30], time2[30]; char gapstr[30]; double gap; double delta; double nsamples; flag printflag; int gapcnt = 0; if ( ! mstg ) return; if ( ! mstg->traces ) return; mst = mstg->traces; pmst = mst; ms_log (0, " Source Last Sample Next Sample Gap Samples\n"); while ( mst->next ) { mst_srcname (mst, src1, 1); mst_srcname (mst->next, src2, 1); if ( ! strcmp (src1, src2) ) { /* Skip MSTraces with 0 sample rate, usually from SOH records */ if ( mst->samprate == 0.0 ) { pmst = mst; mst = mst->next; continue; } /* Check that sample rates match using default tolerance */ if ( ! MS_ISRATETOLERABLE (mst->samprate, mst->next->samprate) ) { ms_log (2, "%s Sample rate changed! %.10g -> %.10g\n", src1, mst->samprate, mst->next->samprate ); } gap = (double) (mst->next->starttime - mst->endtime) / HPTMODULUS; /* Check that any overlap is not larger than the trace coverage */ if ( gap < 0.0 ) { delta = ( mst->next->samprate ) ? (1.0 / mst->next->samprate) : 0.0; if ( (gap * -1.0) > (((double)(mst->next->endtime - mst->next->starttime)/HPTMODULUS) + delta) ) gap = -(((double)(mst->next->endtime - mst->next->starttime)/HPTMODULUS) + delta); } printflag = 1; /* Check gap/overlap criteria */ if ( mingap ) if ( gap < *mingap ) printflag = 0; if ( maxgap ) if ( gap > *maxgap ) printflag = 0; if ( printflag ) { nsamples = ms_dabs(gap) * mst->samprate; if ( gap > 0.0 ) nsamples -= 1.0; else nsamples += 1.0; /* Fix up gap display */ if ( gap >= 86400.0 || gap <= -86400.0 ) snprintf (gapstr, sizeof(gapstr), "%-3.1fd", (gap / 86400)); else if ( gap >= 3600.0 || gap <= -3600.0 ) snprintf (gapstr, sizeof(gapstr), "%-3.1fh", (gap / 3600)); else if ( gap == 0.0 ) snprintf (gapstr, sizeof(gapstr), "-0 "); else snprintf (gapstr, sizeof(gapstr), "%-4.4g", gap); /* Create formatted time strings */ if ( timeformat == 2 ) { snprintf (time1, sizeof(time1), "%.6f", (double) MS_HPTIME2EPOCH(mst->endtime) ); snprintf (time2, sizeof(time2), "%.6f", (double) MS_HPTIME2EPOCH(mst->next->starttime) ); } else if ( timeformat == 1 ) { if ( ms_hptime2isotimestr (mst->endtime, time1, 1) == NULL ) ms_log (2, "Cannot convert trace end time for %s\n", src1); if ( ms_hptime2isotimestr (mst->next->starttime, time2, 1) == NULL ) ms_log (2, "Cannot convert next trace start time for %s\n", src1); } else { if ( ms_hptime2seedtimestr (mst->endtime, time1, 1) == NULL ) ms_log (2, "Cannot convert trace end time for %s\n", src1); if ( ms_hptime2seedtimestr (mst->next->starttime, time2, 1) == NULL ) ms_log (2, "Cannot convert next trace start time for %s\n", src1); } ms_log (0, "%-17s %-24s %-24s %-4s %-.8g\n", src1, time1, time2, gapstr, nsamples); gapcnt++; } } pmst = mst; mst = mst->next; } ms_log (0, "Total: %d gap(s)\n", gapcnt); } /* End of mst_printgaplist() *//*************************************************************************** * mst_pack: * * Pack MSTrace data into Mini-SEED records using the specified record * length, encoding format and byte order. The datasamples array and * numsamples field will be adjusted (reduced) based on how many * samples were packed. * * As each record is filled and finished they are passed to * record_handler which expects 1) a char * to the record, 2) the * length of the record and 3) a pointer supplied by the original * caller containing optional private data (handlerdata). It is the * responsibility of record_handler to process the record, the memory * will be re-used or freed when record_handler returns. * * If the flush flag is > 0 all of the data will be packed into data * records even though the last one will probably not be filled. * * If the mstemplate argument is not NULL it will be used as the * template for the packed Mini-SEED records. Otherwise a new * MSRecord will be initialized and populated from values in the * MSTrace. The reclen, encoding and byteorder arguments take * precedence over those in the template. The start time, sample * rate, datasamples, numsamples and sampletype values from the * template will be preserved. * * Returns the number of records created on success and -1 on error. ***************************************************************************/intmst_pack ( MSTrace *mst, void (*record_handler) (char *, int, void *), void *handlerdata, int reclen, flag encoding, flag byteorder, int *packedsamples, flag flush, flag verbose, MSRecord *mstemplate ){ MSRecord *msr; char srcname[50]; int packedrecords; int samplesize; int bufsize; hptime_t preservestarttime = 0; double preservesamprate = 0.0; void *preservedatasamples = 0; int32_t preservenumsamples = 0; char preservesampletype = 0; StreamState *preserveststate = 0; /* Allocate stream processing state space if needed */ if ( ! mst->ststate ) { mst->ststate = (StreamState *) malloc (sizeof(StreamState)); if ( ! mst->ststate ) { ms_log (2, "mst_pack(): Could not allocate memory for StreamState\n"); return -1; } memset (mst->ststate, 0, sizeof(StreamState)); } if ( mstemplate ) { msr = mstemplate; preservestarttime = msr->starttime; preservesamprate = msr->samprate; preservedatasamples = msr->datasamples; preservenumsamples = msr->numsamples; preservesampletype = msr->sampletype; preserveststate = msr->ststate; } else { msr = msr_init (NULL); if ( msr == NULL ) { ms_log (2, "mst_pack(): Error initializing msr\n"); return -1; } msr->dataquality = 'D'; strcpy (msr->network, mst->network); strcpy (msr->station, mst->station); strcpy (msr->location, mst->location); strcpy (msr->channel, mst->channel); } /* Setup MSRecord template for packing */ msr->reclen = reclen; msr->encoding = encoding; msr->byteorder = byteorder; msr->starttime = mst->starttime; msr->samprate = mst->samprate; msr->datasamples = mst->datasamples; msr->numsamples = mst->numsamples; msr->sampletype = mst->sampletype; msr->ststate = mst->ststate; /* Sample count sanity check */ if ( mst->samplecnt != mst->numsamples ) { ms_log (2, "mst_pack(): Sample counts do not match, abort\n"); return -1; } /* Pack data */ packedrecords = msr_pack (msr, record_handler, handlerdata, packedsamples, flush, verbose); if ( verbose > 1 ) { ms_log (1, "Packed %d records for %s trace\n", packedrecords, mst_srcname (mst, srcname, 1)); } /* Adjust MSTrace start time, data array and sample count */ if ( *packedsamples > 0 ) { /* The new start time was calculated my msr_pack */ mst->starttime = msr->starttime; samplesize = ms_samplesize (mst->sampletype); bufsize = (mst->numsamples - *packedsamples) * samplesize; if ( bufsize ) { memmove (mst->datasamples, (char *) mst->datasamples + (*packedsamples * samplesize), bufsize); mst->datasamples = realloc (mst->datasamples, bufsize); if ( mst->datasamples == NULL ) { ms_log (2, "mst_pack(): Cannot (re)allocate datasamples buffer\n"); return -1; } } else { if ( mst->datasamples ) free (mst->datasamples); mst->datasamples = 0; } mst->samplecnt -= *packedsamples; mst->numsamples -= *packedsamples; } /* Reinstate preserved values if a template was used */ if ( mstemplate ) { msr->starttime = preservestarttime; msr->samprate = preservesamprate; msr->datasamples = preservedatasamples; msr->numsamples = preservenumsamples; msr->sampletype = preservesampletype; msr->ststate = preserveststate; } else { msr->datasamples = 0; msr->ststate = 0; msr_free (&msr); } return packedrecords;} /* End of mst_pack() *//*************************************************************************** * mst_packgroup: * * Pack MSTraceGroup data into Mini-SEED records by calling mst_pack() * for each MSTrace in the group. * * Returns the number of records created on success and -1 on error. ***************************************************************************/intmst_packgroup ( MSTraceGroup *mstg, void (*record_handler) (char *, int, void *), void *handlerdata, int reclen, flag encoding, flag byteorder, int *packedsamples, flag flush, flag verbose, MSRecord *mstemplate ){ MSTrace *mst; int packedrecords = 0; int tracesamples = 0; char srcname[50]; if ( ! mstg ) { return -1; } *packedsamples = 0; mst = mstg->traces; while ( mst ) { if ( mst->numsamples <= 0 ) { if ( verbose > 1 ) { mst_srcname (mst, srcname, 1); ms_log (1, "No data samples for %s, skipping\n", srcname); } } else { packedrecords += mst_pack (mst, record_handler, handlerdata, reclen, encoding, byteorder, &tracesamples, flush, verbose, mstemplate); if ( packedrecords == -1 ) break; *packedsamples += tracesamples; } mst = mst->next; } return packedrecords;} /* End of mst_packgroup() */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -