/*************************************************************************** * 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. ***************************************************************************/ void msr_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, %"PRId64" 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; 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, " signal amplitude: %g\n", blkt_200->amplitude); ms_log (0, " signal period: %g\n", blkt_200->period); ms_log (0, " background estimate: %g\n", blkt_200->background_estimate); if ( details > 1 ) { b = blkt_200->flags; ms_log (0, " event detection 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] 1: Dilatation wave\n"); else ms_log (0, " [Bit 0] 0: Compression wave\n"); if ( b & 0x02 ) ms_log (0, " [Bit 1] 1: Units after deconvolution\n"); else ms_log (0, " [Bit 1] 0: Units are digital counts\n"); if ( b & 0x04 ) ms_log (0, " [Bit 2] Bit 0 is undetermined\n"); ms_log (0, " reserved byte: %u\n", blkt_200->reserved); } ms_btime2seedtimestr (&blkt_200->time, time); ms_log (0, " signal onset time: %s\n", time); ms_log (0, " detector name: %.24s\n", blkt_200->detector); } else if ( cur_blkt->blkt_type == 201 ) { struct blkt_201_s *blkt_201 = (struct blkt_201_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, " signal amplitude: %g\n", blkt_201->amplitude); ms_log (0, " signal period: %g\n", blkt_201->period); ms_log (0, " background estimate: %g\n", blkt_201->background_estimate); b = blkt_201->flags; ms_log (0, " event detection 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] 1: Dilation wave\n"); else ms_log (0, " [Bit 0] 0: Compression wave\n"); if ( details > 1 ) ms_log (0, " reserved byte: %u\n", blkt_201->reserved); ms_btime2seedtimestr (&blkt_201->time, time); ms_log (0, " signal onset time: %s\n", time); ms_log (0, " SNR values: "); for (idx=0; idx < 6; idx++) ms_log (0, "%u ", blkt_201->snr_values[idx]); ms_log (0, "\n"); ms_log (0, " loopback value: %u\n", blkt_201->loopback); ms_log (0, " pick algorithm: %u\n", blkt_201->pick_algorithm); ms_log (0, " detector name: %.24s\n", blkt_201->detector); } else if ( cur_blkt->blkt_type == 300 ) { struct blkt_300_s *blkt_300 = (struct blkt_300_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_btime2seedtimestr (&blkt_300->time, time); ms_log (0, " calibration start time: %s\n", time); ms_log (0, " number of calibrations: %u\n", blkt_300->numcalibrations); b = blkt_300->flags; ms_log (0, " calibration 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] First pulse is positive\n"); if ( b & 0x02 ) ms_log (0, " [Bit 1] Calibration's alternate sign\n"); if ( b & 0x04 ) ms_log (0, " [Bit 2] Calibration was automatic\n"); if ( b & 0x08 ) ms_log (0, " [Bit 3] Calibration continued from previous record(s)\n"); ms_log (0, " step duration: %u\n", blkt_300->step_duration); ms_log (0, " interval duration: %u\n", blkt_300->interval_duration); ms_log (0, " signal amplitude: %g\n", blkt_300->amplitude); ms_log (0, " input signal channel: %.3s", blkt_300->input_channel); if ( details > 1 ) ms_log (0, " reserved byte: %u\n", blkt_300->reserved); ms_log (0, " reference amplitude: %u\n", blkt_300->reference_amplitude); ms_log (0, " coupling: %.12s\n", blkt_300->coupling); ms_log (0, " rolloff: %.12s\n", blkt_300->rolloff); } else if ( cur_blkt->blkt_type == 310 ) { struct blkt_310_s *blkt_310 = (struct blkt_310_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_btime2seedtimestr (&blkt_310->time, time); ms_log (0, " calibration start time: %s\n", time); if ( details > 1 ) ms_log (0, " reserved byte: %u\n", blkt_310->reserved1); b = blkt_310->flags; ms_log (0, " calibration 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 & 0x04 ) ms_log (0, " [Bit 2] Calibration was automatic\n"); if ( b & 0x08 ) ms_log (0, " [Bit 3] Calibration continued from previous record(s)\n"); if ( b & 0x10 ) ms_log (0, " [Bit 4] Peak-to-peak amplitude\n"); if ( b & 0x20 ) ms_log (0, " [Bit 5] Zero-to-peak amplitude\n"); if ( b & 0x40 ) ms_log (0, " [Bit 6] RMS amplitude\n"); ms_log (0, " calibration duration: %u\n", blkt_310->duration); ms_log (0, " signal period: %g\n", blkt_310->period); ms_log (0, " signal amplitude: %g\n", blkt_310->amplitude); ms_log (0, " input signal channel: %.3s", blkt_310->input_channel); if ( details > 1 ) ms_log (0, " reserved byte: %u\n", blkt_310->reserved2); ms_log (0, " reference amplitude: %u\n", blkt_310->reference_amplitude); ms_log (0, " coupling: %.12s\n", blkt_310->coupling); ms_log (0, " rolloff: %.12s\n", blkt_310->rolloff); } else if ( cur_blkt->blkt_type == 320 ) { struct blkt_320_s *blkt_320 = (struct blkt_320_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_btime2seedtimestr (&blkt_320->time, time); ms_log (0, " calibration start time: %s\n", time); if ( details > 1 ) ms_log (0, " reserved byte: %u\n", blkt_320->reserved1); b = blkt_320->flags; ms_log (0, " calibration 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 & 0x04 ) ms_log (0, " [Bit 2] Calibration was automatic\n"); if ( b & 0x08 ) ms_log (0, " [Bit 3] Calibration continued from previous record(s)\n"); if ( b & 0x10 ) ms_log (0, " [Bit 4] Random amplitudes\n"); ms_log (0, " calibration duration: %u\n", blkt_320->duration); ms_log (0, " peak-to-peak amplitude: %g\n", blkt_320->ptp_amplitude); ms_log (0, " input signal channel: %.3s", blkt_320->input_channel); if ( details > 1 ) ms_log (0, " reserved byte: %u\n", blkt_320->reserved2); ms_log (0, " reference amplitude: %u\n", blkt_320->reference_amplitude); ms_log (0, " coupling: %.12s\n", blkt_320->coupling); ms_log (0, " rolloff: %.12s\n", blkt_320->rolloff); ms_log (0, " noise type: %.8s\n", blkt_320->noise_type); } else if ( cur_blkt->blkt_type == 390 ) { struct blkt_390_s *blkt_390 = (struct blkt_390_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_btime2seedtimestr (&blkt_390->time, time); ms_log (0, " calibration start time: %s\n", time); if ( details > 1 ) ms_log (0, " reserved byte: %u\n", blkt_390->reserved1); b = blkt_390->flags; ms_log (0, " calibration 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 & 0x04 ) ms_log (0, " [Bit 2] Calibration was automatic\n"); if ( b & 0x08 ) ms_log (0, " [Bit 3] Calibration continued from previous record(s)\n"); ms_log (0, " calibration duration: %u\n", blkt_390->duration); ms_log (0, " signal amplitude: %g\n", blkt_390->amplitude); ms_log (0, " input signal channel: %.3s", blkt_390->input_channel); if ( details > 1 ) ms_log (0, " reserved byte: %u\n", blkt_390->reserved2); } else if ( cur_blkt->blkt_type == 395 ) { struct blkt_395_s *blkt_395 = (struct blkt_395_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_btime2seedtimestr (&blkt_395->time, time); ms_log (0, " calibration end time: %s\n", time); if ( details > 1 ) ms_log (0, " reserved bytes (2): %u,%u\n", blkt_395->reserved[0], blkt_395->reserved[1]); } else if ( cur_blkt->blkt_type == 400 ) { struct blkt_400_s *blkt_400 = (struct blkt_400_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, " beam azimuth (degrees): %g\n", blkt_400->azimuth); ms_log (0, " beam slowness (sec/degree): %g\n", blkt_400->slowness); ms_log (0, " configuration: %u\n", blkt_400->configuration); if ( details > 1 ) ms_log (0, " reserved bytes (2): %u,%u\n", blkt_400->reserved[0], blkt_400->reserved[1]); } else if ( cur_blkt->blkt_type == 405 ) { struct blkt_405_s *blkt_405 = (struct blkt_405_s *) cur_blkt->blktdata; ms_log (0, " BLOCKETTE %u: (%s, incomplete)\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, " first delay value: %u\n", blkt_405->delay_values[0]); } else if ( cur_blkt->blkt_type == 500 ) { struct blkt_500_s *blkt_500 = (struct blkt_500_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, " VCO correction: %g%%\n", blkt_500->vco_correction); ms_btime2seedtimestr (&blkt_500->time, time); ms_log (0, " time of exception: %s\n", time); ms_log (0, " usec: %d\n", blkt_500->usec); ms_log (0, " reception quality: %u%%\n", blkt_500->reception_qual); ms_log (0, " exception count: %u\n", blkt_500->exception_count); ms_log (0, " exception type: %.16s\n", blkt_500->exception_type); ms_log (0, " clock model: %.32s\n", blkt_500->clock_model); ms_log (0, " clock status: %.128s\n", blkt_500->clock_status); } else if ( cur_blkt->blkt_type == 1000 ) { struct blkt_1000_s *blkt_1000 = (struct blkt_1000_s *) cur_blkt->blktdata; int recsize; char order[40]; /* Calculate record size in bytes as 2^(blkt_1000->rec_len) */ recsize = (unsigned int) 1 << blkt_1000->reclen; /* Big or little endian? */ if (blkt_1000->byteorder == 0) strncpy (order, "Little endian", sizeof(order)-1); else if (blkt_1000->byteorder == 1) strncpy (order, "Big endian", sizeof(order)-1); else strncpy (order, "Unknown value", sizeof(order)-1); 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, " encoding: %s (val:%u)\n", (char *) ms_encodingstr (blkt_1000->encoding), blkt_1000->encoding); ms_log (0, " byte order: %s (val:%u)\n", order, blkt_1000->byteorder); ms_log (0, " record length: %d (val:%u)\n", recsize, blkt_1000->reclen); if ( details > 1 ) ms_log (0, " reserved byte: %u\n", blkt_1000->reserved); } else if ( cur_blkt->blkt_type == 1001 ) { struct blkt_1001_s *blkt_1001 = (struct blkt_1001_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, " timing quality: %u%%\n", blkt_1001->timing_qual); ms_log (0, " micro second: %d\n", blkt_1001->usec); if ( details > 1 ) ms_log (0, " reserved byte: %u\n", blkt_1001->reserved); ms_log (0, " frame count: %u\n", blkt_1001->framecnt); } else if ( cur_blkt->blkt_type == 2000 ) { struct blkt_2000_s *blkt_2000 = (struct blkt_2000_s *) cur_blkt->blktdata; char order[40]; /* Big or little endian? */ if (blkt_2000->byteorder == 0) strncpy (order, "Little endian", sizeof(order)-1); else if (blkt_2000->byteorder == 1) strncpy (order, "Big endian", sizeof(order)-1); else strncpy (order, "Unknown value", sizeof(order)-1); 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, " blockette length: %u\n", blkt_2000->length); ms_log (0, " data offset: %u\n", blkt_2000->data_offset); ms_log (0, " record number: %u\n", blkt_2000->recnum); ms_log (0, " byte order: %s (val:%u)\n", order, blkt_2000->byteorder); b = blkt_2000->flags; ms_log (0, " data 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 ( details > 1 ) { if ( b & 0x01 ) ms_log (0, " [Bit 0] 1: Stream oriented\n"); else ms_log (0, " [Bit 0] 0: Record oriented\n"); if ( b & 0x02 ) ms_log (0, " [Bit 1] 1: Blockette 2000s may NOT be packaged\n"); else ms_log (0, " [Bit 1] 0: Blockette 2000s may be packaged\n"); if ( ! (b & 0x04) && ! (b & 0x08) ) ms_log (0, " [Bits 2-3] 00: Complete blockette\n"); else if ( ! (b & 0x04) && (b & 0x08) ) ms_log (0, " [Bits 2-3] 01: First blockette in span\n"); else if ( (b & 0x04) && (b & 0x08) ) ms_log (0, " [Bits 2-3] 11: Continuation blockette in span\n"); else if ( (b & 0x04) && ! (b & 0x08) ) ms_log (0, " [Bits 2-3] 10: Final blockette in span\n"); if ( ! (b & 0x10) && ! (b & 0x20) ) ms_log (0, " [Bits 4-5] 00: Not file oriented\n"); else if ( ! (b & 0x10) && (b & 0x20) ) ms_log (0, " [Bits 4-5] 01: First blockette of file\n"); else if ( (b & 0x10) && ! (b & 0x20) ) ms_log (0, " [Bits 4-5] 10: Continuation of file\n"); else if ( (b & 0x10) && (b & 0x20) ) ms_log (0, " [Bits 4-5] 11: Last blockette of file\n"); } ms_log (0, " number of headers: %u\n", blkt_2000->numheaders); /* Crude display of the opaque data headers */ if ( details > 1 ) ms_log (0, " headers: %.*s\n", (blkt_2000->data_offset - 15), blkt_2000->payload); } else { ms_log (0, " BLOCKETTE %u: (%s, not parsed)\n", cur_blkt->blkt_type, ms_blktdesc(cur_blkt->blkt_type)); ms_log (0, " next blockette: %u\n", cur_blkt->next_blkt); } cur_blkt = cur_blkt->next; } } } /* End of msr_print() */
/************************************************************************ * msr_unpack_data: * * Unpack Mini-SEED data samples for a given MSRecord. The packed * data is accessed in the record indicated by MSRecord->record and * the unpacked samples are placed in MSRecord->datasamples. The * resulting data samples are either 32-bit integers, 32-bit floats * or 64-bit floats in host byte order. * * Return number of samples unpacked or negative libmseed error code. ************************************************************************/ static int msr_unpack_data ( MSRecord *msr, int swapflag, int verbose ) { int datasize; /* byte size of data samples in record */ int nsamples; /* number of samples unpacked */ int unpacksize; /* byte size of unpacked samples */ int samplesize = 0; /* size of the data samples in bytes */ const char *dbuf; int32_t *diffbuff; int32_t x0, xn; /* Sanity record length */ if ( msr->reclen == -1 ) { ms_log (2, "msr_unpack_data(%s): Record size unknown\n", UNPACK_SRCNAME_2); return MS_NOTSEED; } switch (msr->encoding) { case DE_ASCII: samplesize = 1; break; case DE_INT16: case DE_INT32: case DE_FLOAT32: case DE_STEIM1: case DE_STEIM2: case DE_GEOSCOPE24: case DE_GEOSCOPE163: case DE_GEOSCOPE164: case DE_CDSN: case DE_SRO: case DE_DWWSSN: samplesize = 4; break; case DE_FLOAT64: samplesize = 8; break; default: samplesize = 0; break; } /* Calculate buffer size needed for unpacked samples */ unpacksize = msr->samplecnt * samplesize; /* (Re)Allocate space for the unpacked data */ if ( unpacksize > 0 ) { msr->datasamples = realloc (msr->datasamples, unpacksize); if ( msr->datasamples == NULL ) { ms_log (2, "msr_unpack_data(%s): Cannot (re)allocate memory\n", UNPACK_SRCNAME_2); return MS_GENERROR; } } else { if ( msr->datasamples ) free (msr->datasamples); msr->datasamples = 0; msr->numsamples = 0; } datasize = msr->reclen - msr->fsdh->data_offset; dbuf = msr->record + msr->fsdh->data_offset; if ( verbose > 2 ) ms_log (1, "%s: Unpacking %d samples\n", UNPACK_SRCNAME_2, msr->samplecnt); /* Decide if this is a encoding that we can decode */ switch (msr->encoding) { case DE_ASCII: if ( verbose > 1 ) ms_log (1, "%s: Found ASCII data\n", UNPACK_SRCNAME_2); nsamples = msr->samplecnt; memcpy (msr->datasamples, dbuf, nsamples); msr->sampletype = 'a'; break; case DE_INT16: if ( verbose > 1 ) ms_log (1, "%s: Unpacking INT-16 data samples\n", UNPACK_SRCNAME_2); nsamples = msr_unpack_int_16 ((int16_t *)dbuf, msr->samplecnt, msr->samplecnt, msr->datasamples, swapflag); msr->sampletype = 'i'; break; case DE_INT32: if ( verbose > 1 ) ms_log (1, "%s: Unpacking INT-32 data samples\n", UNPACK_SRCNAME_2); nsamples = msr_unpack_int_32 ((int32_t *)dbuf, msr->samplecnt, msr->samplecnt, msr->datasamples, swapflag); msr->sampletype = 'i'; break; case DE_FLOAT32: if ( verbose > 1 ) ms_log (1, "%s: Unpacking FLOAT-32 data samples\n", UNPACK_SRCNAME_2); nsamples = msr_unpack_float_32 ((float *)dbuf, msr->samplecnt, msr->samplecnt, msr->datasamples, swapflag); msr->sampletype = 'f'; break; case DE_FLOAT64: if ( verbose > 1 ) ms_log (1, "%s: Unpacking FLOAT-64 data samples\n", UNPACK_SRCNAME_2); nsamples = msr_unpack_float_64 ((double *)dbuf, msr->samplecnt, msr->samplecnt, msr->datasamples, swapflag); msr->sampletype = 'd'; break; case DE_STEIM1: diffbuff = (int32_t *) malloc(unpacksize); if ( diffbuff == NULL ) { ms_log (2, "msr_unpack_data(%s): Cannot allocate diff buffer\n", UNPACK_SRCNAME_2); return MS_GENERROR; } if ( verbose > 1 ) ms_log (1, "%s: Unpacking Steim-1 data frames\n", UNPACK_SRCNAME_2); nsamples = msr_unpack_steim1 ((FRAME *)dbuf, datasize, msr->samplecnt, msr->samplecnt, msr->datasamples, diffbuff, &x0, &xn, swapflag, verbose); msr->sampletype = 'i'; free (diffbuff); break; case DE_STEIM2: diffbuff = (int32_t *) malloc(unpacksize); if ( diffbuff == NULL ) { ms_log (2, "msr_unpack_data(%s): Cannot allocate diff buffer\n", UNPACK_SRCNAME_2); return MS_GENERROR; } if ( verbose > 1 ) ms_log (1, "%s: Unpacking Steim-2 data frames\n", UNPACK_SRCNAME_2); nsamples = msr_unpack_steim2 ((FRAME *)dbuf, datasize, msr->samplecnt, msr->samplecnt, msr->datasamples, diffbuff, &x0, &xn, swapflag, verbose); msr->sampletype = 'i'; free (diffbuff); break; case DE_GEOSCOPE24: case DE_GEOSCOPE163: case DE_GEOSCOPE164: if ( verbose > 1 ) { if ( msr->encoding == DE_GEOSCOPE24 ) ms_log (1, "%s: Unpacking GEOSCOPE 24bit integer data samples\n", UNPACK_SRCNAME_2); if ( msr->encoding == DE_GEOSCOPE163 ) ms_log (1, "%s: Unpacking GEOSCOPE 16bit gain ranged/3bit exponent data samples\n", UNPACK_SRCNAME_2); if ( msr->encoding == DE_GEOSCOPE164 ) ms_log (1, "%s: Unpacking GEOSCOPE 16bit gain ranged/4bit exponent data samples\n", UNPACK_SRCNAME_2); } nsamples = msr_unpack_geoscope (dbuf, msr->samplecnt, msr->samplecnt, msr->datasamples, msr->encoding, swapflag); msr->sampletype = 'f'; break; case DE_CDSN: if ( verbose > 1 ) ms_log (1, "%s: Unpacking CDSN encoded data samples\n", UNPACK_SRCNAME_2); nsamples = msr_unpack_cdsn ((int16_t *)dbuf, msr->samplecnt, msr->samplecnt, msr->datasamples, swapflag); msr->sampletype = 'i'; break; case DE_SRO: if ( verbose > 1 ) ms_log (1, "%s: Unpacking SRO encoded data samples\n", UNPACK_SRCNAME_2); nsamples = msr_unpack_sro ((int16_t *)dbuf, msr->samplecnt, msr->samplecnt, msr->datasamples, swapflag); msr->sampletype = 'i'; break; case DE_DWWSSN: if ( verbose > 1 ) ms_log (1, "%s: Unpacking DWWSSN encoded data samples\n", UNPACK_SRCNAME_2); nsamples = msr_unpack_dwwssn ((int16_t *)dbuf, msr->samplecnt, msr->samplecnt, msr->datasamples, swapflag); msr->sampletype = 'i'; break; default: ms_log (2, "%s: Unsupported encoding format %d (%s)\n", UNPACK_SRCNAME_2, msr->encoding, (char *) ms_encodingstr(msr->encoding)); return MS_UNKNOWNFORMAT; } return nsamples; } /* End of msr_unpack_data() */
/*************************************************************************** * ms_parse_raw: * * Parse and verify a SEED data record header (fixed section and * blockettes) at the lowest level, printing error messages for * invalid header values and optionally print raw header values. The * memory at 'record' is assumed to be a Mini-SEED record. Not every * possible test is performed, common errors and those causing * libmseed parsing to fail should be detected. * * The 'details' argument is interpreted as follows: * * details: * 0 = only print error messages for invalid header fields * 1 = print basic fields in addition to invalid field errors * 2 = print all fields in addition to invalid field errors * * The 'swapflag' argument is interpreted as follows: * * swapflag: * 1 = swap multibyte quantities * 0 = do no swapping * -1 = autodetect byte order using year test, swap if needed * * Any byte swapping performed by this routine is applied directly to * the memory reference by the record pointer. * * This routine is primarily intended to diagnose invalid Mini-SEED headers. * * Returns 0 when no errors were detected or a positive count of * errors detected. ***************************************************************************/ int ms_parse_raw ( char *record, int maxreclen, flag details, flag swapflag ) { struct fsdh_s *fsdh; double nomsamprate; char srcname[50]; char *X; char b; int retval = 0; int b1000encoding = -1; int b1000reclen = -1; int endofblockettes = -1; int idx; if ( ! record ) return 1; /* Generate a source name string */ srcname[0] = '\0'; ms_recsrcname (record, srcname, 1); fsdh = (struct fsdh_s *) record; /* Check to see if byte swapping is needed by testing the year */ if ( swapflag == -1 && ((fsdh->start_time.year < 1900) || (fsdh->start_time.year > 2050)) ) swapflag = 1; else swapflag = 0; if ( details > 1 ) { if ( swapflag == 1 ) ms_log (0, "Swapping multi-byte quantities in header\n"); else ms_log (0, "Not swapping multi-byte quantities in header\n"); } /* Swap byte order */ if ( swapflag ) { MS_SWAPBTIME (&fsdh->start_time); ms_gswap2a (&fsdh->numsamples); ms_gswap2a (&fsdh->samprate_fact); ms_gswap2a (&fsdh->samprate_mult); ms_gswap4a (&fsdh->time_correct); ms_gswap2a (&fsdh->data_offset); ms_gswap2a (&fsdh->blockette_offset); } /* Validate fixed section header fields */ X = record; /* Pointer of convenience */ /* Check record sequence number, 6 ASCII digits */ if ( ! isdigit((unsigned char) *(X)) || ! isdigit ((unsigned char) *(X+1)) || ! isdigit((unsigned char) *(X+2)) || ! isdigit ((unsigned char) *(X+3)) || ! isdigit((unsigned char) *(X+4)) || ! isdigit ((unsigned char) *(X+5)) ) { ms_log (2, "%s: Invalid sequence number: '%c%c%c%c%c%c'\n", srcname, X, X+1, X+2, X+3, X+4, X+5); retval++; } /* Check header/quality indicator */ if ( ! MS_ISDATAINDICATOR(*(X+6)) ) { ms_log (2, "%s: Invalid header indicator (DRQM): '%c'\n", srcname, X+6); retval++; } /* Check reserved byte, space or NULL */ if ( ! (*(X+7) == ' ' || *(X+7) == '\0') ) { ms_log (2, "%s: Invalid fixed section reserved byte (Space): '%c'\n", srcname, X+7); retval++; } /* Check station code, 5 alphanumerics or spaces */ if ( ! (isalnum((unsigned char) *(X+8)) || *(X+8) == ' ') || ! (isalnum((unsigned char) *(X+9)) || *(X+9) == ' ') || ! (isalnum((unsigned char) *(X+10)) || *(X+10) == ' ') || ! (isalnum((unsigned char) *(X+11)) || *(X+11) == ' ') || ! (isalnum((unsigned char) *(X+12)) || *(X+12) == ' ') ) { ms_log (2, "%s: Invalid station code: '%c%c%c%c%c'\n", srcname, X+8, X+9, X+10, X+11, X+12); retval++; } /* Check location ID, 2 alphanumerics or spaces */ if ( ! (isalnum((unsigned char) *(X+13)) || *(X+13) == ' ') || ! (isalnum((unsigned char) *(X+14)) || *(X+14) == ' ') ) { ms_log (2, "%s: Invalid location ID: '%c%c'\n", srcname, X+13, X+14); retval++; } /* Check channel codes, 3 alphanumerics or spaces */ if ( ! (isalnum((unsigned char) *(X+15)) || *(X+15) == ' ') || ! (isalnum((unsigned char) *(X+16)) || *(X+16) == ' ') || ! (isalnum((unsigned char) *(X+17)) || *(X+17) == ' ') ) { ms_log (2, "%s: Invalid channel codes: '%c%c%c'\n", srcname, X+15, X+16, X+17); retval++; } /* Check network code, 2 alphanumerics or spaces */ if ( ! (isalnum((unsigned char) *(X+18)) || *(X+18) == ' ') || ! (isalnum((unsigned char) *(X+19)) || *(X+19) == ' ') ) { ms_log (2, "%s: Invalid network code: '%c%c'\n", srcname, X+18, X+19); retval++; } /* Check start time fields */ if ( fsdh->start_time.year < 1920 || fsdh->start_time.year > 2050 ) { ms_log (2, "%s: Unlikely start year (1920-2050): '%d'\n", srcname, fsdh->start_time.year); retval++; } if ( fsdh->start_time.day < 1 || fsdh->start_time.day > 366 ) { ms_log (2, "%s: Invalid start day (1-366): '%d'\n", srcname, fsdh->start_time.day); retval++; } if ( fsdh->start_time.hour > 23 ) { ms_log (2, "%s: Invalid start hour (0-23): '%d'\n", srcname, fsdh->start_time.hour); retval++; } if ( fsdh->start_time.min > 59 ) { ms_log (2, "%s: Invalid start minute (0-59): '%d'\n", srcname, fsdh->start_time.min); retval++; } if ( fsdh->start_time.sec > 60 ) { ms_log (2, "%s: Invalid start second (0-60): '%d'\n", srcname, fsdh->start_time.sec); retval++; } if ( fsdh->start_time.fract > 9999 ) { ms_log (2, "%s: Invalid start fractional seconds (0-9999): '%d'\n", srcname, fsdh->start_time.fract); retval++; } /* Check number of samples, max samples in 4096-byte Steim-2 encoded record: 6601 */ if ( fsdh->numsamples > 20000 ) { ms_log (2, "%s: Unlikely number of samples (>20000): '%d'\n", srcname, fsdh->numsamples); retval++; } /* Sanity check that there is space for blockettes when both data and blockettes are present */ if ( fsdh->numsamples > 0 && fsdh->numblockettes > 0 && fsdh->data_offset <= fsdh->blockette_offset ) { ms_log (2, "%s: No space for %d blockettes, data offset: %d, blockette offset: %d\n", srcname, fsdh->numblockettes, fsdh->data_offset, fsdh->blockette_offset); retval++; } /* Print raw header details */ if ( details >= 1 ) { /* Determine nominal sample rate */ nomsamprate = ms_nomsamprate (fsdh->samprate_fact, fsdh->samprate_mult); /* Print header values */ ms_log (0, "RECORD -- %s\n", srcname); ms_log (0, " sequence number: '%c%c%c%c%c%c'\n", fsdh->sequence_number[0], fsdh->sequence_number[1], fsdh->sequence_number[2], fsdh->sequence_number[3], fsdh->sequence_number[4], fsdh->sequence_number[5]); ms_log (0, " data quality indicator: '%c'\n", fsdh->dataquality); if ( details > 0 ) ms_log (0, " reserved: '%c'\n", fsdh->reserved); ms_log (0, " station code: '%c%c%c%c%c'\n", fsdh->station[0], fsdh->station[1], fsdh->station[2], fsdh->station[3], fsdh->station[4]); ms_log (0, " location ID: '%c%c'\n", fsdh->location[0], fsdh->location[1]); ms_log (0, " channel codes: '%c%c%c'\n", fsdh->channel[0], fsdh->channel[1], fsdh->channel[2]); ms_log (0, " network code: '%c%c'\n", fsdh->network[0], fsdh->network[1]); ms_log (0, " start time: %d,%d,%d:%d:%d.%04d (unused: %d)\n", fsdh->start_time.year, fsdh->start_time.day, fsdh->start_time.hour, fsdh->start_time.min, fsdh->start_time.sec, fsdh->start_time.fract, fsdh->start_time.unused); ms_log (0, " number of samples: %d\n", fsdh->numsamples); ms_log (0, " sample rate factor: %d (%.10g samples per second)\n", fsdh->samprate_fact, nomsamprate); ms_log (0, " sample rate multiplier: %d\n", fsdh->samprate_mult); /* Print flag details if requested */ if ( details > 1 ) { /* Activity flags */ b = 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 = 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 = 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", fsdh->numblockettes); ms_log (0, " time correction: %ld\n", (long int) fsdh->time_correct); ms_log (0, " data offset: %d\n", fsdh->data_offset); ms_log (0, " first blockette offset: %d\n", fsdh->blockette_offset); } /* Done printing raw header details */ /* Validate and report information in the blockette chain */ if ( fsdh->blockette_offset > 46 && fsdh->blockette_offset < maxreclen ) { int blkt_offset = fsdh->blockette_offset; int blkt_count = 0; int blkt_length; uint16_t blkt_type; uint16_t next_blkt; char *blkt_desc; /* Traverse blockette chain */ while ( blkt_offset != 0 && blkt_offset < maxreclen ) { /* Every blockette has a similar 4 byte header: type and next */ memcpy (&blkt_type, record + blkt_offset, 2); memcpy (&next_blkt, record + blkt_offset+2, 2); if ( swapflag ) { ms_gswap2 (&blkt_type); ms_gswap2 (&next_blkt); } /* Print common header fields */ if ( details >= 1 ) { blkt_desc = ms_blktdesc(blkt_type); ms_log (0, " BLOCKETTE %u: (%s)\n", blkt_type, (blkt_desc) ? blkt_desc : "Unknown"); ms_log (0, " next blockette: %u\n", next_blkt); } blkt_length = ms_blktlen (blkt_type, record + blkt_offset, swapflag); if ( blkt_length == 0 ) { ms_log (2, "%s: Unknown blockette length for type %d\n", srcname, blkt_type); retval++; } /* Track end of blockette chain */ endofblockettes = blkt_offset + blkt_length - 1; /* Sanity check that the blockette is contained in the record */ if ( endofblockettes > maxreclen ) { ms_log (2, "%s: Blockette type %d at offset %d with length %d does not fix in record (%d)\n", srcname, blkt_type, blkt_offset, blkt_length, maxreclen); retval++; break; } if ( blkt_type == 100 ) { struct blkt_100_s *blkt_100 = (struct blkt_100_s *) (record + blkt_offset + 4); if ( swapflag ) ms_gswap4 (&blkt_100->samprate); if ( details >= 1 ) { 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 ( blkt_type == 200 ) { struct blkt_200_s *blkt_200 = (struct blkt_200_s *) (record + blkt_offset + 4); if ( swapflag ) { ms_gswap4 (&blkt_200->amplitude); ms_gswap4 (&blkt_200->period); ms_gswap4 (&blkt_200->background_estimate); MS_SWAPBTIME (&blkt_200->time); } if ( details >= 1 ) { ms_log (0, " signal amplitude: %g\n", blkt_200->amplitude); ms_log (0, " signal period: %g\n", blkt_200->period); ms_log (0, " background estimate: %g\n", blkt_200->background_estimate); if ( details > 1 ) { b = blkt_200->flags; ms_log (0, " event detection 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] 1: Dilatation wave\n"); else ms_log (0, " [Bit 0] 0: Compression wave\n"); if ( b & 0x02 ) ms_log (0, " [Bit 1] 1: Units after deconvolution\n"); else ms_log (0, " [Bit 1] 0: Units are digital counts\n"); if ( b & 0x04 ) ms_log (0, " [Bit 2] Bit 0 is undetermined\n"); ms_log (0, " reserved byte: %u\n", blkt_200->reserved); } ms_log (0, " signal onset time: %d,%d,%d:%d:%d.%04d (unused: %d)\n", blkt_200->time.year, blkt_200->time.day, blkt_200->time.hour, blkt_200->time.min, blkt_200->time.sec, blkt_200->time.fract, blkt_200->time.unused); ms_log (0, " detector name: %.24s\n", blkt_200->detector); } } else if ( blkt_type == 201 ) { struct blkt_201_s *blkt_201 = (struct blkt_201_s *) (record + blkt_offset + 4); if ( swapflag ) { ms_gswap4 (&blkt_201->amplitude); ms_gswap4 (&blkt_201->period); ms_gswap4 (&blkt_201->background_estimate); MS_SWAPBTIME (&blkt_201->time); } if ( details >= 1 ) { ms_log (0, " signal amplitude: %g\n", blkt_201->amplitude); ms_log (0, " signal period: %g\n", blkt_201->period); ms_log (0, " background estimate: %g\n", blkt_201->background_estimate); b = blkt_201->flags; ms_log (0, " event detection 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] 1: Dilation wave\n"); else ms_log (0, " [Bit 0] 0: Compression wave\n"); if ( details > 1 ) ms_log (0, " reserved byte: %u\n", blkt_201->reserved); ms_log (0, " signal onset time: %d,%d,%d:%d:%d.%04d (unused: %d)\n", blkt_201->time.year, blkt_201->time.day, blkt_201->time.hour, blkt_201->time.min, blkt_201->time.sec, blkt_201->time.fract, blkt_201->time.unused); ms_log (0, " SNR values: "); for (idx=0; idx < 6; idx++) ms_log (0, "%u ", blkt_201->snr_values[idx]); ms_log (0, "\n"); ms_log (0, " loopback value: %u\n", blkt_201->loopback); ms_log (0, " pick algorithm: %u\n", blkt_201->pick_algorithm); ms_log (0, " detector name: %.24s\n", blkt_201->detector); } } else if ( blkt_type == 300 ) { struct blkt_300_s *blkt_300 = (struct blkt_300_s *) (record + blkt_offset + 4); if ( swapflag ) { MS_SWAPBTIME (&blkt_300->time); ms_gswap4 (&blkt_300->step_duration); ms_gswap4 (&blkt_300->interval_duration); ms_gswap4 (&blkt_300->amplitude); ms_gswap4 (&blkt_300->reference_amplitude); } if ( details >= 1 ) { ms_log (0, " calibration start time: %d,%d,%d:%d:%d.%04d (unused: %d)\n", blkt_300->time.year, blkt_300->time.day, blkt_300->time.hour, blkt_300->time.min, blkt_300->time.sec, blkt_300->time.fract, blkt_300->time.unused); ms_log (0, " number of calibrations: %u\n", blkt_300->numcalibrations); b = blkt_300->flags; ms_log (0, " calibration 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] First pulse is positive\n"); if ( b & 0x02 ) ms_log (0, " [Bit 1] Calibration's alternate sign\n"); if ( b & 0x04 ) ms_log (0, " [Bit 2] Calibration was automatic\n"); if ( b & 0x08 ) ms_log (0, " [Bit 3] Calibration continued from previous record(s)\n"); ms_log (0, " step duration: %u\n", blkt_300->step_duration); ms_log (0, " interval duration: %u\n", blkt_300->interval_duration); ms_log (0, " signal amplitude: %g\n", blkt_300->amplitude); ms_log (0, " input signal channel: %.3s", blkt_300->input_channel); if ( details > 1 ) ms_log (0, " reserved byte: %u\n", blkt_300->reserved); ms_log (0, " reference amplitude: %u\n", blkt_300->reference_amplitude); ms_log (0, " coupling: %.12s\n", blkt_300->coupling); ms_log (0, " rolloff: %.12s\n", blkt_300->rolloff); } } else if ( blkt_type == 310 ) { struct blkt_310_s *blkt_310 = (struct blkt_310_s *) (record + blkt_offset + 4); if ( swapflag ) { MS_SWAPBTIME (&blkt_310->time); ms_gswap4 (&blkt_310->duration); ms_gswap4 (&blkt_310->period); ms_gswap4 (&blkt_310->amplitude); ms_gswap4 (&blkt_310->reference_amplitude); } if ( details >= 1 ) { ms_log (0, " calibration start time: %d,%d,%d:%d:%d.%04d (unused: %d)\n", blkt_310->time.year, blkt_310->time.day, blkt_310->time.hour, blkt_310->time.min, blkt_310->time.sec, blkt_310->time.fract, blkt_310->time.unused); if ( details > 1 ) ms_log (0, " reserved byte: %u\n", blkt_310->reserved1); b = blkt_310->flags; ms_log (0, " calibration 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 & 0x04 ) ms_log (0, " [Bit 2] Calibration was automatic\n"); if ( b & 0x08 ) ms_log (0, " [Bit 3] Calibration continued from previous record(s)\n"); if ( b & 0x10 ) ms_log (0, " [Bit 4] Peak-to-peak amplitude\n"); if ( b & 0x20 ) ms_log (0, " [Bit 5] Zero-to-peak amplitude\n"); if ( b & 0x40 ) ms_log (0, " [Bit 6] RMS amplitude\n"); ms_log (0, " calibration duration: %u\n", blkt_310->duration); ms_log (0, " signal period: %g\n", blkt_310->period); ms_log (0, " signal amplitude: %g\n", blkt_310->amplitude); ms_log (0, " input signal channel: %.3s", blkt_310->input_channel); if ( details > 1 ) ms_log (0, " reserved byte: %u\n", blkt_310->reserved2); ms_log (0, " reference amplitude: %u\n", blkt_310->reference_amplitude); ms_log (0, " coupling: %.12s\n", blkt_310->coupling); ms_log (0, " rolloff: %.12s\n", blkt_310->rolloff); } } else if ( blkt_type == 320 ) { struct blkt_320_s *blkt_320 = (struct blkt_320_s *) (record + blkt_offset + 4); if ( swapflag ) { MS_SWAPBTIME (&blkt_320->time); ms_gswap4 (&blkt_320->duration); ms_gswap4 (&blkt_320->ptp_amplitude); ms_gswap4 (&blkt_320->reference_amplitude); } if ( details >= 1 ) { ms_log (0, " calibration start time: %d,%d,%d:%d:%d.%04d (unused: %d)\n", blkt_320->time.year, blkt_320->time.day, blkt_320->time.hour, blkt_320->time.min, blkt_320->time.sec, blkt_320->time.fract, blkt_320->time.unused); if ( details > 1 ) ms_log (0, " reserved byte: %u\n", blkt_320->reserved1); b = blkt_320->flags; ms_log (0, " calibration 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 & 0x04 ) ms_log (0, " [Bit 2] Calibration was automatic\n"); if ( b & 0x08 ) ms_log (0, " [Bit 3] Calibration continued from previous record(s)\n"); if ( b & 0x10 ) ms_log (0, " [Bit 4] Random amplitudes\n"); ms_log (0, " calibration duration: %u\n", blkt_320->duration); ms_log (0, " peak-to-peak amplitude: %g\n", blkt_320->ptp_amplitude); ms_log (0, " input signal channel: %.3s", blkt_320->input_channel); if ( details > 1 ) ms_log (0, " reserved byte: %u\n", blkt_320->reserved2); ms_log (0, " reference amplitude: %u\n", blkt_320->reference_amplitude); ms_log (0, " coupling: %.12s\n", blkt_320->coupling); ms_log (0, " rolloff: %.12s\n", blkt_320->rolloff); ms_log (0, " noise type: %.8s\n", blkt_320->noise_type); } } else if ( blkt_type == 390 ) { struct blkt_390_s *blkt_390 = (struct blkt_390_s *) (record + blkt_offset + 4); if ( swapflag ) { MS_SWAPBTIME (&blkt_390->time); ms_gswap4 (&blkt_390->duration); ms_gswap4 (&blkt_390->amplitude); } if ( details >= 1 ) { ms_log (0, " calibration start time: %d,%d,%d:%d:%d.%04d (unused: %d)\n", blkt_390->time.year, blkt_390->time.day, blkt_390->time.hour, blkt_390->time.min, blkt_390->time.sec, blkt_390->time.fract, blkt_390->time.unused); if ( details > 1 ) ms_log (0, " reserved byte: %u\n", blkt_390->reserved1); b = blkt_390->flags; ms_log (0, " calibration 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 & 0x04 ) ms_log (0, " [Bit 2] Calibration was automatic\n"); if ( b & 0x08 ) ms_log (0, " [Bit 3] Calibration continued from previous record(s)\n"); ms_log (0, " calibration duration: %u\n", blkt_390->duration); ms_log (0, " signal amplitude: %g\n", blkt_390->amplitude); ms_log (0, " input signal channel: %.3s", blkt_390->input_channel); if ( details > 1 ) ms_log (0, " reserved byte: %u\n", blkt_390->reserved2); } } else if ( blkt_type == 395 ) { struct blkt_395_s *blkt_395 = (struct blkt_395_s *) (record + blkt_offset + 4); if ( swapflag ) MS_SWAPBTIME (&blkt_395->time); if ( details >= 1 ) { ms_log (0, " calibration end time: %d,%d,%d:%d:%d.%04d (unused: %d)\n", blkt_395->time.year, blkt_395->time.day, blkt_395->time.hour, blkt_395->time.min, blkt_395->time.sec, blkt_395->time.fract, blkt_395->time.unused); if ( details > 1 ) ms_log (0, " reserved bytes (2): %u,%u\n", blkt_395->reserved[0], blkt_395->reserved[1]); } } else if ( blkt_type == 400 ) { struct blkt_400_s *blkt_400 = (struct blkt_400_s *) (record + blkt_offset + 4); if ( swapflag ) { ms_gswap4 (&blkt_400->azimuth); ms_gswap4 (&blkt_400->slowness); ms_gswap4 (&blkt_400->configuration); } if ( details >= 1 ) { ms_log (0, " beam azimuth (degrees): %g\n", blkt_400->azimuth); ms_log (0, " beam slowness (sec/degree): %g\n", blkt_400->slowness); ms_log (0, " configuration: %u\n", blkt_400->configuration); if ( details > 1 ) ms_log (0, " reserved bytes (2): %u,%u\n", blkt_400->reserved[0], blkt_400->reserved[1]); } } else if ( blkt_type == 405 ) { struct blkt_405_s *blkt_405 = (struct blkt_405_s *) (record + blkt_offset + 4); uint16_t firstvalue = blkt_405->delay_values[0]; /* Work on a private copy */ if ( swapflag ) ms_gswap2 (&firstvalue); if ( details >= 1 ) ms_log (0, " first delay value: %u\n", firstvalue); } else if ( blkt_type == 500 ) { struct blkt_500_s *blkt_500 = (struct blkt_500_s *) (record + blkt_offset + 4); if ( swapflag ) { ms_gswap4 (&blkt_500->vco_correction); MS_SWAPBTIME (&blkt_500->time); ms_gswap4 (&blkt_500->exception_count); } if ( details >= 1 ) { ms_log (0, " VCO correction: %g%%\n", blkt_500->vco_correction); ms_log (0, " time of exception: %d,%d,%d:%d:%d.%04d (unused: %d)\n", blkt_500->time.year, blkt_500->time.day, blkt_500->time.hour, blkt_500->time.min, blkt_500->time.sec, blkt_500->time.fract, blkt_500->time.unused); ms_log (0, " usec: %d\n", blkt_500->usec); ms_log (0, " reception quality: %u%%\n", blkt_500->reception_qual); ms_log (0, " exception count: %u\n", blkt_500->exception_count); ms_log (0, " exception type: %.16s\n", blkt_500->exception_type); ms_log (0, " clock model: %.32s\n", blkt_500->clock_model); ms_log (0, " clock status: %.128s\n", blkt_500->clock_status); } } else if ( blkt_type == 1000 ) { struct blkt_1000_s *blkt_1000 = (struct blkt_1000_s *) (record + blkt_offset + 4); char order[40]; /* Calculate record size in bytes as 2^(blkt_1000->rec_len) */ b1000reclen = (unsigned int) 1 << blkt_1000->reclen; /* Big or little endian? */ if (blkt_1000->byteorder == 0) strncpy (order, "Little endian", sizeof(order)-1); else if (blkt_1000->byteorder == 1) strncpy (order, "Big endian", sizeof(order)-1); else strncpy (order, "Unknown value", sizeof(order)-1); if ( details >= 1 ) { ms_log (0, " encoding: %s (val:%u)\n", (char *) ms_encodingstr (blkt_1000->encoding), blkt_1000->encoding); ms_log (0, " byte order: %s (val:%u)\n", order, blkt_1000->byteorder); ms_log (0, " record length: %d (val:%u)\n", b1000reclen, blkt_1000->reclen); if ( details > 1 ) ms_log (0, " reserved byte: %u\n", blkt_1000->reserved); } /* Save encoding format */ b1000encoding = blkt_1000->encoding; /* Sanity check encoding format */ if ( ! (b1000encoding >= 0 && b1000encoding <= 5) && ! (b1000encoding >= 10 && b1000encoding <= 19) && ! (b1000encoding >= 30 && b1000encoding <= 33) ) { ms_log (2, "%s: Blockette 1000 encoding format invalid (0-5,10-19,30-33): %d\n", srcname, b1000encoding); retval++; } /* Sanity check byte order flag */ if ( blkt_1000->byteorder != 0 && blkt_1000->byteorder != 1 ) { ms_log (2, "%s: Blockette 1000 byte order flag invalid (0 or 1): %d\n", srcname, blkt_1000->byteorder); retval++; } } else if ( blkt_type == 1001 ) { struct blkt_1001_s *blkt_1001 = (struct blkt_1001_s *) (record + blkt_offset + 4); if ( details >= 1 ) { ms_log (0, " timing quality: %u%%\n", blkt_1001->timing_qual); ms_log (0, " micro second: %d\n", blkt_1001->usec); if ( details > 1 ) ms_log (0, " reserved byte: %u\n", blkt_1001->reserved); ms_log (0, " frame count: %u\n", blkt_1001->framecnt); } } else if ( blkt_type == 2000 ) { struct blkt_2000_s *blkt_2000 = (struct blkt_2000_s *) (record + blkt_offset + 4); char order[40]; if ( swapflag ) { ms_gswap2 (&blkt_2000->length); ms_gswap2 (&blkt_2000->data_offset); ms_gswap4 (&blkt_2000->recnum); } /* Big or little endian? */ if (blkt_2000->byteorder == 0) strncpy (order, "Little endian", sizeof(order)-1); else if (blkt_2000->byteorder == 1) strncpy (order, "Big endian", sizeof(order)-1); else strncpy (order, "Unknown value", sizeof(order)-1); if ( details >= 1 ) { ms_log (0, " blockette length: %u\n", blkt_2000->length); ms_log (0, " data offset: %u\n", blkt_2000->data_offset); ms_log (0, " record number: %u\n", blkt_2000->recnum); ms_log (0, " byte order: %s (val:%u)\n", order, blkt_2000->byteorder); b = blkt_2000->flags; ms_log (0, " data 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 ( details > 1 ) { if ( b & 0x01 ) ms_log (0, " [Bit 0] 1: Stream oriented\n"); else ms_log (0, " [Bit 0] 0: Record oriented\n"); if ( b & 0x02 ) ms_log (0, " [Bit 1] 1: Blockette 2000s may NOT be packaged\n"); else ms_log (0, " [Bit 1] 0: Blockette 2000s may be packaged\n"); if ( ! (b & 0x04) && ! (b & 0x08) ) ms_log (0, " [Bits 2-3] 00: Complete blockette\n"); else if ( ! (b & 0x04) && (b & 0x08) ) ms_log (0, " [Bits 2-3] 01: First blockette in span\n"); else if ( (b & 0x04) && (b & 0x08) ) ms_log (0, " [Bits 2-3] 11: Continuation blockette in span\n"); else if ( (b & 0x04) && ! (b & 0x08) ) ms_log (0, " [Bits 2-3] 10: Final blockette in span\n"); if ( ! (b & 0x10) && ! (b & 0x20) ) ms_log (0, " [Bits 4-5] 00: Not file oriented\n"); else if ( ! (b & 0x10) && (b & 0x20) ) ms_log (0, " [Bits 4-5] 01: First blockette of file\n"); else if ( (b & 0x10) && ! (b & 0x20) ) ms_log (0, " [Bits 4-5] 10: Continuation of file\n"); else if ( (b & 0x10) && (b & 0x20) ) ms_log (0, " [Bits 4-5] 11: Last blockette of file\n"); } ms_log (0, " number of headers: %u\n", blkt_2000->numheaders); /* Crude display of the opaque data headers */ if ( details > 1 ) ms_log (0, " headers: %.*s\n", (blkt_2000->data_offset - 15), blkt_2000->payload); } } else { ms_log (2, "%s: Unrecognized blockette type: %d\n", srcname, blkt_type); retval++; } /* Sanity check the next blockette offset */ if ( next_blkt && next_blkt <= endofblockettes ) { ms_log (2, "%s: Next blockette offset (%d) is within current blockette ending at byte %d\n", srcname, next_blkt, endofblockettes); blkt_offset = 0; } else { blkt_offset = next_blkt; } blkt_count++; } /* End of looping through blockettes */ /* Check that the blockette offset is within the maximum record size */ if ( blkt_offset > maxreclen ) { ms_log (2, "%s: Blockette offset (%d) beyond maximum record length (%d)\n", srcname, blkt_offset, maxreclen); retval++; } /* Check that the data and blockette offsets are within the record */ if ( b1000reclen && fsdh->data_offset > b1000reclen ) { ms_log (2, "%s: Data offset (%d) beyond record length (%d)\n", srcname, fsdh->data_offset, b1000reclen); retval++; } if ( b1000reclen && fsdh->blockette_offset > b1000reclen ) { ms_log (2, "%s: Blockette offset (%d) beyond record length (%d)\n", srcname, fsdh->blockette_offset, b1000reclen); retval++; } /* Check that the data offset is beyond the end of the blockettes */ if ( fsdh->numsamples && fsdh->data_offset <= endofblockettes ) { ms_log (2, "%s: Data offset (%d) is within blockette chain (end of blockettes: %d)\n", srcname, fsdh->data_offset, endofblockettes); retval++; } /* Check that the correct number of blockettes were parsed */ if ( fsdh->numblockettes != blkt_count ) { ms_log (2, "%s: Specified number of blockettes (%d) not equal to those parsed (%d)\n", srcname, fsdh->numblockettes, blkt_count); retval++; } } return retval; } /* End of ms_parse_raw() */