📄 msrutils.c
字号:
{ /* Allocate memory for new FSDH structure */ if ( (dupmsr->fsdh = (struct fsdh_s *) malloc (sizeof(struct fsdh_s))) == NULL ) { ms_log (2, "msr_duplicate(): Error allocating memory\n"); free (dupmsr); return NULL; } /* Copy the contents */ memcpy (dupmsr->fsdh, msr->fsdh, sizeof(struct fsdh_s)); } /* Copy the blockette chain */ if ( msr->blkts ) { BlktLink *blkt = msr->blkts; BlktLink *next = NULL; dupmsr->blkts = 0; while ( blkt ) { next = blkt->next; /* Add blockette to chain of new MSRecord */ if ( msr_addblockette (dupmsr, blkt->blktdata, blkt->blktdatalen, blkt->blkt_type, 0) == NULL ) { ms_log (2, "msr_duplicate(): Error adding blockettes\n"); msr_free (&dupmsr); return NULL; } blkt = next; } } /* Copy data samples if requested and available */ if ( datadup && msr->datasamples ) { /* Determine size of samples in bytes */ samplesize = ms_samplesize (msr->sampletype); if ( samplesize == 0 ) { ms_log (2, "msr_duplicate(): unrecognized sample type: '%c'\n", msr->sampletype); free (dupmsr); return NULL; } /* Allocate memory for new data array */ if ( (dupmsr->datasamples = (void *) malloc (msr->numsamples * samplesize)) == NULL ) { ms_log (2, "msr_duplicate(): Error allocating memory\n"); free (dupmsr); return NULL; } /* Copy the data array */ memcpy (dupmsr->datasamples, msr->datasamples, (msr->numsamples * samplesize)); } /* Otherwise make sure the sample array and count are zero */ else { dupmsr->datasamples = 0; dupmsr->numsamples = 0; } return dupmsr;} /* End of msr_duplicate() *//*************************************************************************** * msr_samprate: * * Calculate and return a double precision sample rate for the * specified MSRecord. If a Blockette 100 was included and parsed, * the "Actual sample rate" (field 3) will be returned, otherwise a * nominal sample rate will be calculated from the sample rate factor * and multiplier in the fixed section data header. * * Returns the positive sample rate on success and -1.0 on error. ***************************************************************************/doublemsr_samprate (MSRecord *msr){ if ( ! msr ) return -1.0; if ( msr->Blkt100 ) return (double) msr->Blkt100->samprate; else return msr_nomsamprate (msr); } /* End of msr_samprate() *//*************************************************************************** * msr_nomsamprate: * * Calculate a double precision nominal sample rate from the sample * rate factor and multiplier in the FSDH struct of the specified * MSRecord. * * Returns the positive sample rate on success and -1.0 on error. ***************************************************************************/doublemsr_nomsamprate (MSRecord *msr){ double samprate = 0.0; int factor; int multiplier; if ( ! msr ) return -1.0; /* Calculate the nominal sample rate */ factor = msr->fsdh->samprate_fact; multiplier = msr->fsdh->samprate_mult; if ( factor > 0 ) samprate = (double) factor; else if ( factor < 0 ) samprate = -1.0 / (double) factor; if ( multiplier > 0 ) samprate = samprate * (double) multiplier; else if ( multiplier < 0 ) samprate = -1.0 * (samprate / (double) multiplier); return samprate;} /* End of msr_nomsamprate() *//*************************************************************************** * msr_starttime: * * Convert a btime struct of a FSDH struct of a MSRecord (the record * start time) into a high precision epoch time and apply time * corrections if any are specified in the header and bit 1 of the * activity flags indicates that it has not already been applied. If * a Blockette 1001 is included and has been parsed the microseconds * of field 4 are also applied. * * Returns a high precision epoch time on success and HPTERROR on * error. ***************************************************************************/hptime_tmsr_starttime (MSRecord *msr){ hptime_t starttime = msr_starttime_uc (msr); if ( ! msr || starttime == HPTERROR ) return HPTERROR; /* Check if a correction is included and if it has been applied, bit 1 of activity flags indicates if it has been appiled */ if ( msr->fsdh->time_correct != 0 && ! (msr->fsdh->act_flags & 0x02) ) { starttime += (hptime_t) msr->fsdh->time_correct * (HPTMODULUS / 10000); } /* Apply microsecond precision in a parsed Blockette 1001 */ if ( msr->Blkt1001 ) { starttime += (hptime_t) msr->Blkt1001->usec * (HPTMODULUS / 1000000); } return starttime;} /* End of msr_starttime() *//*************************************************************************** * msr_starttime_uc: * * Convert a btime struct of a FSDH struct of a MSRecord (the record * start time) into a high precision epoch time. This time has no * correction(s) applied to it. * * Returns a high precision epoch time on success and HPTERROR on * error. ***************************************************************************/hptime_tmsr_starttime_uc (MSRecord *msr){ if ( ! msr ) return HPTERROR; if ( ! msr->fsdh ) return HPTERROR; return ms_btime2hptime (&msr->fsdh->start_time);} /* End of msr_starttime_uc() *//*************************************************************************** * msr_endtime: * * Calculate the time of the last sample in the record; this is the * actual last sample time and *not* the time "covered" by the last * sample. * * Returns the time of the last sample as a high precision epoch time * on success and HPTERROR on error. ***************************************************************************/hptime_tmsr_endtime (MSRecord *msr){ hptime_t span = 0; if ( ! msr ) return HPTERROR; if ( msr->samprate > 0.0 && msr->samplecnt > 0 ) span = ((double) (msr->samplecnt - 1) / msr->samprate * HPTMODULUS) + 0.5; return (msr->starttime + span);} /* End of msr_endtime() *//*************************************************************************** * msr_srcname: * * Generate a source name string for a specified MSRecord in the * format: 'NET_STA_LOC_CHAN' or, if the quality flag is true: * 'NET_STA_LOC_CHAN_QUAL'. The passed srcname must have enough room * for the resulting string. * * Returns a pointer to the resulting string or NULL on error. ***************************************************************************/char *msr_srcname (MSRecord *msr, char *srcname, flag quality){ char *src = srcname; char *cp = srcname; if ( ! msr || ! srcname ) return NULL; /* Build the source name string */ cp = msr->network; while ( *cp ) { *src++ = *cp++; } *src++ = '_'; cp = msr->station; while ( *cp ) { *src++ = *cp++; } *src++ = '_'; cp = msr->location; while ( *cp ) { *src++ = *cp++; } *src++ = '_'; cp = msr->channel; while ( *cp ) { *src++ = *cp++; } if ( quality ) { *src++ = '_'; *src++ = msr->dataquality; } *src = '\0'; return srcname;} /* End of msr_srcname() *//*************************************************************************** * msr_print: * * Prints header values in an MSRecord struct, if 'details' is greater * than 0 then detailed information about each blockette is printed. * If 'details' is greater than 1 very detailed information is * printed. If no FSDH (msr->fsdh) is present only a single line with * basic information is printed. ***************************************************************************/voidmsr_print (MSRecord *msr, flag details){ double nomsamprate; char srcname[50]; char time[25]; char b; int idx; if ( ! msr ) return; /* Generate a source name string */ srcname[0] = '\0'; msr_srcname (msr, srcname, 0); /* Generate a start time string */ ms_hptime2seedtimestr (msr->starttime, time, 1); /* Report information in the fixed header */ if ( details > 0 && msr->fsdh ) { nomsamprate = msr_nomsamprate (msr); ms_log (0, "%s, %06d, %c\n", srcname, msr->sequence_number, msr->dataquality); ms_log (0, " start time: %s\n", time); ms_log (0, " number of samples: %d\n", msr->fsdh->numsamples); ms_log (0, " sample rate factor: %d (%.10g samples per second)\n", msr->fsdh->samprate_fact, nomsamprate); ms_log (0, " sample rate multiplier: %d\n", msr->fsdh->samprate_mult); if ( details > 1 ) { /* Activity flags */ b = msr->fsdh->act_flags; ms_log (0, " activity flags: [%u%u%u%u%u%u%u%u] 8 bits\n", bit(b,0x01), bit(b,0x02), bit(b,0x04), bit(b,0x08), bit(b,0x10), bit(b,0x20), bit(b,0x40), bit(b,0x80)); if ( b & 0x01 ) ms_log (0, " [Bit 0] Calibration signals present\n"); if ( b & 0x02 ) ms_log (0, " [Bit 1] Time correction applied\n"); if ( b & 0x04 ) ms_log (0, " [Bit 2] Beginning of an event, station trigger\n"); if ( b & 0x08 ) ms_log (0, " [Bit 3] End of an event, station detrigger\n"); if ( b & 0x10 ) ms_log (0, " [Bit 4] A positive leap second happened in this record\n"); if ( b & 0x20 ) ms_log (0, " [Bit 5] A negative leap second happened in this record\n"); if ( b & 0x40 ) ms_log (0, " [Bit 6] Event in progress\n"); if ( b & 0x80 ) ms_log (0, " [Bit 7] Undefined bit set\n"); /* I/O and clock flags */ b = msr->fsdh->io_flags; ms_log (0, " I/O and clock flags: [%u%u%u%u%u%u%u%u] 8 bits\n", bit(b,0x01), bit(b,0x02), bit(b,0x04), bit(b,0x08), bit(b,0x10), bit(b,0x20), bit(b,0x40), bit(b,0x80)); if ( b & 0x01 ) ms_log (0, " [Bit 0] Station volume parity error possibly present\n"); if ( b & 0x02 ) ms_log (0, " [Bit 1] Long record read (possibly no problem)\n"); if ( b & 0x04 ) ms_log (0, " [Bit 2] Short record read (record padded)\n"); if ( b & 0x08 ) ms_log (0, " [Bit 3] Start of time series\n"); if ( b & 0x10 ) ms_log (0, " [Bit 4] End of time series\n"); if ( b & 0x20 ) ms_log (0, " [Bit 5] Clock locked\n"); if ( b & 0x40 ) ms_log (0, " [Bit 6] Undefined bit set\n"); if ( b & 0x80 ) ms_log (0, " [Bit 7] Undefined bit set\n"); /* Data quality flags */ b = msr->fsdh->dq_flags; ms_log (0, " data quality flags: [%u%u%u%u%u%u%u%u] 8 bits\n", bit(b,0x01), bit(b,0x02), bit(b,0x04), bit(b,0x08), bit(b,0x10), bit(b,0x20), bit(b,0x40), bit(b,0x80)); if ( b & 0x01 ) ms_log (0, " [Bit 0] Amplifier saturation detected\n"); if ( b & 0x02 ) ms_log (0, " [Bit 1] Digitizer clipping detected\n"); if ( b & 0x04 ) ms_log (0, " [Bit 2] Spikes detected\n"); if ( b & 0x08 ) ms_log (0, " [Bit 3] Glitches detected\n"); if ( b & 0x10 ) ms_log (0, " [Bit 4] Missing/padded data present\n"); if ( b & 0x20 ) ms_log (0, " [Bit 5] Telemetry synchronization error\n"); if ( b & 0x40 ) ms_log (0, " [Bit 6] A digital filter may be charging\n"); if ( b & 0x80 ) ms_log (0, " [Bit 7] Time tag is questionable\n"); } ms_log (0, " number of blockettes: %d\n", msr->fsdh->numblockettes); ms_log (0, " time correction: %ld\n", (long int) msr->fsdh->time_correct); ms_log (0, " data offset: %d\n", msr->fsdh->data_offset); ms_log (0, " first blockette offset: %d\n", msr->fsdh->blockette_offset); } else { ms_log (0, "%s, %06d, %c, %d, %d samples, %-.10g Hz, %s\n", srcname, msr->sequence_number, msr->dataquality, msr->reclen, msr->samplecnt, msr->samprate, time); } /* Report information in the blockette chain */ if ( details > 0 && msr->blkts ) { BlktLink *cur_blkt = msr->blkts; while ( cur_blkt ) { if ( cur_blkt->blkt_type == 100 ) { struct blkt_100_s *blkt_100 = (struct blkt_100_s *) cur_blkt->blktdata; ms_log (0, " BLOCKETTE %u: (%s)\n", cur_blkt->blkt_type, ms_blktdesc(cur_blkt->blkt_type)); ms_log (0, " next blockette: %u\n", cur_blkt->next_blkt); ms_log (0, " actual sample rate: %.10g\n", blkt_100->samprate); if ( details > 1 ) { b = blkt_100->flags; ms_log (0, " undefined flags: [%u%u%u%u%u%u%u%u] 8 bits\n", bit(b,0x01), bit(b,0x02), bit(b,0x04), bit(b,0x08), bit(b,0x10), bit(b,0x20), bit(b,0x40), bit(b,0x80)); ms_log (0, " reserved bytes (3): %u,%u,%u\n", blkt_100->reserved[0], blkt_100->reserved[1], blkt_100->reserved[2]); } } else if ( cur_blkt->blkt_type == 200 ) { struct blkt_200_s *blkt_200 = (struct blkt_200_s *) cur_blkt->blktdata;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -