示例#1
0
/***************************************************************************
 * msr_writemseed:
 *
 * Pack MSRecord data into Mini-SEED record(s) by calling msr_pack() and
 * write to a specified file.
 *
 * Returns the number of records written on success and -1 on error.
 ***************************************************************************/
int
msr_writemseed (MSRecord *msr, const char *msfile, flag overwrite,
                int reclen, flag encoding, flag byteorder, flag verbose)
{
  FILE *ofp;
  char srcname[50];
  char *perms       = (overwrite) ? "wb" : "ab";
  int packedrecords = 0;

  if (!msr || !msfile)
    return -1;

  /* Open output file or use stdout */
  if (strcmp (msfile, "-") == 0)
  {
    ofp = stdout;
  }
  else if ((ofp = fopen (msfile, perms)) == NULL)
  {
    ms_log (1, "Cannot open output file %s: %s\n", msfile, strerror (errno));

    return -1;
  }

  /* Pack the MSRecord */
  if (msr->numsamples > 0)
  {
    msr->encoding  = encoding;
    msr->reclen    = reclen;
    msr->byteorder = byteorder;

    packedrecords = msr_pack (msr, &ms_record_handler_int, ofp, NULL, 1, verbose - 1);

    if (packedrecords < 0)
    {
      msr_srcname (msr, srcname, 1);
      ms_log (1, "Cannot write Mini-SEED for %s\n", srcname);
    }
  }

  /* Close file and return record count */
  fclose (ofp);

  return (packedrecords >= 0) ? packedrecords : -1;
} /* End of msr_writemseed() */
    bool MSeedWriter::write(IntegerMSeedRecord::SharedPtr_t sampleRange)
    {
        // наполнения хедера mseed
        MSRecord* msr = msr_init(NULL);

        // общие для записей данные
        strcpy(msr->network, sampleRange->network().toLatin1().constData());
        strcpy(msr->station, sampleRange->station().toLatin1().constData());
        strcpy(msr->location, sampleRange->location().toLatin1().constData());
        strcpy(msr->channel, sampleRange->channelName().toLatin1().constData());

        msr->samprate = sampleRange->samplingRateHz();

        msr->reclen = _recordLength;
        msr->record = NULL;
        msr->encoding = _encoding;  // compression
        msr->byteorder = 1;         // big endian byte order

        BTime btime = dateTimeToBTime(sampleRange->startTime());
        msr->starttime = ms_btime2hptime(&btime);

        msr->sampletype = 'i';      // declare type to be 32-bit integers

        msr->datasamples = sampleRange->data().data();
        msr->numsamples = sampleRange->data().size();

        flag verbose = _verbose;
        _packedSamples = 0;
        _packedRecords = msr_pack(msr, &binaryStreamRecorder, _binaryStream.get(), &_packedSamples, 1, verbose);
        if (_packedRecords == -1)
        {
            return false;
        }

        msr->datasamples = NULL;
        msr_free(&msr);

        ms_log(0, "Packed %d samples into %d records\n", _packedSamples, _packedRecords);
        return true;
    }
示例#3
0
int
main (int argc, char **argv)
{
  MSRecord *msr = 0;
  MSTraceGroup *mstg = 0;
  MSTrace *mst;
  int retcode;

  int totalrecs  = 0;
  int totalsamps = 0;
  int packedsamples;
  int packedrecords;
  int lastrecord;
  int iseqnum = 1;
  
#ifndef WIN32
  /* Signal handling, use POSIX calls with standardized semantics */
  struct sigaction sa;
  
  sa.sa_flags = SA_RESTART;
  sigemptyset (&sa.sa_mask);
  
  sa.sa_handler = term_handler;
  sigaction (SIGINT, &sa, NULL);
  sigaction (SIGQUIT, &sa, NULL);
  sigaction (SIGTERM, &sa, NULL);
  
  sa.sa_handler = SIG_IGN;
  sigaction (SIGHUP, &sa, NULL);
  sigaction (SIGPIPE, &sa, NULL);
#endif
  
  /* Process given parameters (command line and parameter file) */
  if (parameter_proc (argc, argv) < 0)
    return -1;
  
  /* Setup input encoding format if specified */
  if ( encodingstr )
    {
      int inputencoding = strtoul (encodingstr, NULL, 10);
      
      if ( inputencoding == 0 && errno == EINVAL )
	{
	  ms_log (2, "Error parsing input encoding format: %s\n", encodingstr);
	  return -1;
	}
      
      MS_UNPACKENCODINGFORMAT (inputencoding);
    }
  
  /* Init MSTraceGroup */
  mstg = mst_initgroup (mstg);
  
  /* Loop over the input file */
  while ( (retcode = ms_readmsr (&msr, inputfile, reclen, NULL, &lastrecord,
				 1, 1, verbose)) == MS_NOERROR )
    {
      totalrecs++;
      totalsamps += msr->samplecnt;
      
      msr_print (msr, ppackets);
      
      if ( packreclen >= 0 )
	msr->reclen = packreclen;
      else
	packreclen = msr->reclen;
      
      if ( packencoding >= 0 )
	msr->encoding = packencoding;
      else
	packencoding = msr->encoding;
      
      if ( byteorder >= 0 )
	msr->byteorder = byteorder;
      else
	byteorder = msr->byteorder;
      
      /* After unpacking the record, the start time in msr->starttime
	 is a potentially corrected start time, if correction has been
	 applied make sure the correction bit flag is set as it will
	 be used as a packing template. */
      if ( msr->fsdh->time_correct && ! (msr->fsdh->act_flags & 0x02) )
	{
	  ms_log (1, "Setting time correction applied flag for %s_%s_%s_%s\n",
		  msr->network, msr->station, msr->location, msr->channel);
	  msr->fsdh->act_flags |= 0x02;
	}
      
      /* If no samples in the record just pack the header */
      if ( outfile && msr->numsamples == 0 )
	{
	  msr_pack_header (msr, 1, verbose);
	  record_handler (msr->record, msr->reclen, NULL);
	}
      
      /* Pack each record individually */
      else if ( outfile && ! tracepack )
	{
	  msr->sequence_number = iseqnum;
	  
	  packedrecords = msr_pack (msr, &record_handler, NULL, &packedsamples, 1, verbose);
	  
	  if ( packedrecords == -1 )
	    ms_log (2, "Cannot pack records\n"); 
	  else
	    ms_log (1, "Packed %d records\n", packedrecords); 
	  
	  iseqnum = msr->sequence_number;
	}
      
      /* Pack records from a MSTraceGroup */
      else if ( outfile && tracepack )
	{
	  mst = mst_addmsrtogroup (mstg, msr, 0, -1.0, -1.0);
	  
	  if ( ! mst )
	    {
	      ms_log (2, "Error adding MSRecord to MStrace!\n");
	      break;
	    }
	  	  
	  /* Reset sequence number and free previous template */
	  if ( mst->prvtptr )
	    {
	      MSRecord *tmsr = (MSRecord *) mst->prvtptr;
	      
	      /* Retain sequence number from previous template */
	      msr->sequence_number = tmsr->sequence_number;
	      
	      msr_free (&tmsr);
	    }
	  else
	    {
	      msr->sequence_number = 1;
	    }
	  
	  /* Copy MSRecord and store as template */
	  mst->prvtptr = msr_duplicate (msr, 0);
	  
	  if ( ! mst->prvtptr )
	    {
	      ms_log (2, "Error duplicating MSRecord for template!\n");
	      break;
	    }
	  
	  /* Pack traces based on selected method */
	  packedrecords = 0;
	  if ( tracepack == 1 )
	    {
	      mst = mstg->traces;
	      while ( mst )
		{
		  packedrecords += mst_pack (mst, &record_handler, NULL, packreclen,
					     packencoding, byteorder, &packedsamples,
					     lastrecord, verbose, (MSRecord *)mst->prvtptr);
		  mst = mst->next;
		}
	      
	      ms_log (1, "Packed %d records\n", packedrecords);
	    }
	  if ( tracepack == 2 && lastrecord )
	    {
	      mst = mstg->traces;
	      while ( mst )
		{
		  packedrecords += mst_pack (mst, &record_handler, NULL, packreclen,
					     packencoding, byteorder, &packedsamples,
					     lastrecord, verbose, (MSRecord *)mst->prvtptr);
		  mst = mst->next;
		}
	      
	      ms_log (1, "Packed %d records\n", packedrecords);
	    }
	}
    }
  
  if ( retcode != MS_ENDOFFILE )
    ms_log (2, "Error reading %s: %s\n", inputfile, ms_errorstr(retcode));
  
  /* Make sure everything is cleaned up */
  ms_readmsr (&msr, NULL, 0, NULL, NULL, 0, 0, 0);
  mst_freegroup (&mstg);
  
  if ( outfile )
    fclose (outfile);
  
  getchar();

  return 0;
}  /* End of main() */
示例#4
0
/***************************************************************************
 * collect_and_write:
 *
 * Attempt to connect to a device, slows down the loop checking
 * after 20 attempts with a larger delay to reduce pointless
 * work being done.
 *
 * Returns 0 on success and -1 otherwise.
 ***************************************************************************/
int collect_and_write() {

    int32_t idata[2000]; // enough space for data of 2 records
    hptime_t hptime;
    hptime_t start_hptime_est = 0;
    hptime_t last_hptime;
    DOUBLE dt, dt_est, sample_rate_est;
    DOUBLE start_hptime_current, record_window_current, record_window_est;
    DOUBLE prev_start_hptime_est = -1;
    int n_start_hptime_est;

    // debug
    hptime_t start_hptime_nominal = 0;
    hptime_t prev_start_next_hptime_est = 0;
    double diff_end, diff_end_cumul = 0.0;

    char seedtimestr[64];

    // decay constant depends on required decay time and sample rate
    //double decay_minutes = 60.0; // 1 hour
    double decay_minutes = 1.0;
    double decay_consant = 1.0 / (decay_minutes * 60.0 * (double) nominal_sample_rate);


    // initialize last_hptime to current time
    last_hptime = current_utc_hptime();

    // initialize dt_est based on nominal sample rate
    dt_est = (nominal_sample_rate == 80) ? 1.0 / SAMP_PER_SEC_80 : (nominal_sample_rate == 40) ? 1.0 / SAMP_PER_SEC_40 : 1.0 / SAMP_PER_SEC_20;
    //	‘a’: 20.032 SPS
    //	‘b’: 39.860 SPS
    //	‘c’: 79.719 SPS
    // initialize record_window_est based on  nominal sample rate and record length
    record_window_est = dt_est * num_samples_in_record;

    if (DEBUG) {
        logprintf(MSG_FLAG, "Initialize: last_hptime=%lld, dt_est=%lld, dt=%lf, dt_end=%lf, dt_end_cumul=%lf)\n",
                last_hptime, dt_est, record_window_est);
    }

    int first = 1;
    MSRecord *pmsrecord = msr_init(NULL);
    strcpy(pmsrecord->network, station_network);
    strcpy(pmsrecord->station, station_name);
    strcpy(pmsrecord->location, "");
    sprintf(pmsrecord->channel, "%s%s", channel_prefix, component);
    pmsrecord->samprate = 1.0;
    pmsrecord->reclen = SLRECSIZE;
    pmsrecord->encoding = mswrite_data_encoding_type_code;
    pmsrecord->byteorder = 1;
    pmsrecord->datasamples = idata;
    pmsrecord->numsamples = 0;
    pmsrecord->sampletype = 'i';

    while (1) {

        // load data up to SLRECSIZE
        long ivalue;
        int nsamp = 0;
        start_hptime_current = 0;
        n_start_hptime_est = 0;
        while (nsamp < num_samples_in_record) {
            ivalue = read_next_value(&hptime, TIMEOUT_LARGE);
            if (ivalue == READ_ERROR || ivalue < MIN_DATA || ivalue > MAX_DATA) {
                logprintf(MSG_FLAG, "READ_ERROR: port=%s, nsamp=%d, ivalue=%ld\n", port_path, nsamp, ivalue);
                pmsrecord->datasamples = NULL;
                msr_free(&pmsrecord);
                return (-1);
            }
            if (DEBUG && nsamp == 0) {
                start_hptime_nominal = hptime;
            }
            idata[pmsrecord->numsamples + nsamp] = (int32_t) ivalue;
            dt = (DOUBLE) (hptime - last_hptime) / (DOUBLE) HPTMODULUS;
            last_hptime = hptime;
            if (verbose > 3) {
                logprintf(MSG_FLAG, "%d %ld %s (dt=%lf)\n", nsamp, ivalue, ms_hptime2seedtimestr(hptime, seedtimestr, 1), (double) dt);
            }
            // estimate start time and dt
            // use only later samples in record since writing previous record may delay reading of first samples of this record
            if (nsamp >= num_samples_in_record / 2) {
                // 20131107 AJL - use all samples, may give better start time estimate, since buffering should compensate for any delay of first samples
                //if (1) {
                // start time estimate is timestamp of current data minus dt_est*nsamp
                start_hptime_current += (hptime - (hptime_t) ((DOUBLE) 0.5 + dt_est * (DOUBLE) HPTMODULUS * (DOUBLE) nsamp));
                n_start_hptime_est++;
                // accumulate dt_est using low-pass filter
                //dt_est = dt_est + (DOUBLE) decay_consant * (dt - dt_est);
            }
            nsamp++;
        }
        start_hptime_current /= n_start_hptime_est;
        if (prev_start_hptime_est > 0) {
            record_window_current = (DOUBLE) (start_hptime_current - prev_start_hptime_est) / (DOUBLE) HPTMODULUS;
        } else {
            record_window_current = record_window_est;
        }
        // accumulate record_window_est using low-pass filter
        record_window_est = record_window_est + (DOUBLE) decay_consant * (record_window_current - record_window_est);
        if (prev_start_hptime_est > 0) {
            start_hptime_est = prev_start_hptime_est + (hptime_t) ((DOUBLE) 0.5 + record_window_est * (DOUBLE) HPTMODULUS);
        } else {
            start_hptime_est = start_hptime_current;
        }
        prev_start_hptime_est = start_hptime_est;
        // test - truncate dt to 1/10000 s to match precision of miniseed btime
        //logprintf(MSG_FLAG, "0 sample_rate_est=%lf (dt=%lfs)\n", (double) ((DOUBLE) 1.0 / dt_est), (double) dt_est);
        dt_est = record_window_est / (DOUBLE) num_samples_in_record;
        sample_rate_est = (DOUBLE) 1.0 / dt_est;
        if (DEBUG) {
            diff_end = (double) (start_hptime_est - prev_start_next_hptime_est) / (double) HPTMODULUS;
            if (!first)
                diff_end_cumul += diff_end;
            logprintf(MSG_FLAG, "sample_rate_est=%lf (dt=%lfs)\n", (double) sample_rate_est, (double) dt_est);
            logprintf(MSG_FLAG, "start_hptime_est=%lld, start_hptime_nominal=%lld, dt=%lf, dt_end=%lf, dt_end_cumul=%lf)\n", start_hptime_est, start_hptime_nominal,
                    (double) ((DOUBLE) (start_hptime_est - start_hptime_nominal) / (DOUBLE) HPTMODULUS), diff_end, diff_end_cumul);
            prev_start_next_hptime_est = start_hptime_est + (hptime_t) ((DOUBLE) 0.5 + dt_est * (DOUBLE) HPTMODULUS * (DOUBLE) nsamp);
        }

        pmsrecord->starttime = start_hptime_est - (DOUBLE) HPTMODULUS * pmsrecord->numsamples / pmsrecord->samprate;
        pmsrecord->samprate = mswrite_header_sample_rate > 0.0 ? mswrite_header_sample_rate : sample_rate_est;
        pmsrecord->numsamples += nsamp;

        int64_t npackedsamples = 0;
        if (msr_pack(pmsrecord, record_handler, NULL, &npackedsamples, 0, verbose) < 0) {
            logprintf(ERROR_FLAG, "Error encoding data!\n");
            exit(1);
        }

        pmsrecord->numsamples -= npackedsamples;
        memmove(&idata[0], &idata[npackedsamples], pmsrecord->numsamples * 4);
    }

    return (0);

}