Example #1
0
/***************************************************************************
 * msr_update_header:
 *
 * Update the header values that change between records: start time,
 * sequence number, etc.
 *
 * Returns 0 on success or -1 on error.
 ***************************************************************************/
static int
msr_update_header ( MSRecord *msr, char *rawrec, flag swapflag,
		    struct blkt_1001_s *blkt1001, flag verbose )
{
  struct fsdh_s *fsdh;
  char seqnum[7];
  
  if ( ! msr || ! rawrec )
    return -1;
  
  if ( verbose > 2 )
    ms_log (1, "%s: Updating fixed section of data header\n", PACK_SRCNAME);
  
  fsdh = (struct fsdh_s *) rawrec;
  
  /* Pack values into the fixed section of header */
  snprintf (seqnum, 7, "%06d", msr->sequence_number);
  memcpy (fsdh->sequence_number, seqnum, 6);
  
  /* Update fixed-section start time */
  ms_hptime2btime (msr->starttime, &(fsdh->start_time));
  
  /* Swap byte order? */
  if ( swapflag )
    {
      MS_SWAPBTIME (&fsdh->start_time);
    }
  
  /* Update microseconds if Blockette 1001 is present */
  if ( msr->Blkt1001 && blkt1001 )
    {
      hptime_t sec, usec;
      
      /* Calculate microseconds offset */
      sec = msr->starttime / (HPTMODULUS / 10000);
      usec = msr->starttime - (sec * (HPTMODULUS / 10000));
      usec /= (HPTMODULUS / 1000000);
      
      /* Update microseconds offset in blockette chain entry */
      msr->Blkt1001->usec = (int8_t) usec;
      
      /* Update microseconds offset in packed header */
      blkt1001->usec = (int8_t) usec;
    }
  
  return 0;
}  /* End of msr_update_header() */
Example #2
0
/***************************************************************************
 * msr_update_header:
 *
 * Update the header values that change between records: start time,
 * sequence number, etc.
 *
 * Returns 0 on success or -1 on error.
 ***************************************************************************/
static int
msr_update_header (MSRecord *msr, char *rawrec, flag swapflag,
                   struct blkt_1001_s *blkt1001, char *srcname, flag verbose)
{
  struct fsdh_s *fsdh;
  hptime_t hptimems;
  int8_t usecoffset;
  char seqnum[7];

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

  if (verbose > 2)
    ms_log (1, "%s: Updating fixed section of data header\n", srcname);

  fsdh = (struct fsdh_s *)rawrec;

  /* Pack values into the fixed section of header */
  snprintf (seqnum, 7, "%06d", msr->sequence_number);
  memcpy (fsdh->sequence_number, seqnum, 6);

  /* Get start time rounded to tenths of milliseconds and microsecond offset */
  ms_hptime2tomsusecoffset (msr->starttime, &hptimems, &usecoffset);

  /* Update fixed-section start time */
  ms_hptime2btime (hptimems, &(fsdh->start_time));

  /* Swap byte order? */
  if (swapflag)
  {
    MS_SWAPBTIME (&fsdh->start_time);
  }

  /* Update microsecond offset value if Blockette 1001 is present */
  if (msr->Blkt1001 && blkt1001)
  {
    /* Update microseconds offset in blockette chain entry */
    msr->Blkt1001->usec = usecoffset;

    /* Update microseconds offset in packed header */
    blkt1001->usec = usecoffset;
  }

  return 0;
} /* End of msr_update_header() */
Example #3
0
/***************************************************************************
 * ds_streamproc:
 *
 * Save MiniSEED records in a custom directory/file structure.  The
 * appropriate directories and files are created if nesecessary.  If
 * files already exist they are appended to.  If 'msr' is NULL then
 * ds_shutdown() will be called to close all open files and free all
 * associated memory.
 *
 * This version has been modified from others to add the add the suffix
 * integer supplied with ds_streamproc() to the defkey and file name.
 *
 * Returns 0 on success, -1 on error.
 ***************************************************************************/
extern int
ds_streamproc (DataStream *datastream, MSRecord *msr, long suffix, int verbose)
{
  DataStreamGroup *foundgroup = NULL;
  BTime stime;
  strlist *fnlist, *fnptr;
  char net[3], sta[6], loc[3], chan[4];
  char filename[400];
  char definition[400];
  char pathformat[600];
  char tstr[20];
  int fnlen = 0;
  
  /* Set Verbosity for ds_ functions */
  dsverbose = verbose;
  
  /* Special case for stream shutdown */
  if ( ! msr )
    {
      if ( dsverbose >= 1 )
        fprintf (stderr, "Closing archiving for: %s\n", datastream->path );
      
      ds_shutdown ( datastream );
      return 0;
    }
  
  if ( ! msr->fsdh )
    {
      fprintf (stderr, "ds_streamproc(): msr->fsdh must be available\n");
      return -1;
    }
  
  /* Build file path and name from datastream->path */
  filename[0] = '\0';
  definition[0] = '\0';
  snprintf (pathformat, sizeof(pathformat), "%s", datastream->path);
  strparse (pathformat, "/", &fnlist);

  fnptr = fnlist;

  /* Special case of an absolute path (first entry is empty) */
  if ( *fnptr->element == '\0' )
    {
      if ( fnptr->next != 0 )
	{
	  strncat (filename, "/", sizeof(filename));
	  fnptr = fnptr->next;
	}
      else
	{
	  fprintf (stderr, "ds_streamproc(): empty path format\n");
	  strparse (NULL, NULL, &fnlist);
	  return -1;
	}
    }
  
  /* Convert normalized starttime to BTime structure */
  if ( ms_hptime2btime (msr->starttime, &stime) )
    {
      fprintf (stderr, "ds_streamproc(): cannot convert start time to separate fields\n");
      strparse (NULL, NULL, &fnlist);
      return -1;
    }
  
  while ( fnptr != 0 )
    {
      int tdy;
      char *w, *p, def;

      p = fnptr->element;

      /* Special case of no file given */
      if ( *p == '\0' && fnptr->next == 0 )
	{
	  fprintf (stderr, "ds_streamproc(): no file name specified, only %s\n",
		   filename);
	  strparse (NULL, NULL, &fnlist);
	  return -1;
	}

      while ( (w = strpbrk (p, "%#")) != NULL )
	{
	  def = ( *w == '%' );
	  *w = '\0';
	  strncat (filename, p, (sizeof(filename) - fnlen));
	  fnlen = strlen (filename);

	  w += 1;

	  switch ( *w )
	    {
	    case 'n' :
	      ms_strncpclean (net, msr->fsdh->network, 2);
	      strncat (filename, net, (sizeof(filename) - fnlen));
	      if ( def ) strncat (definition, net, (sizeof(definition) - fnlen));
	      fnlen = strlen (filename);
	      p = w + 1;
	      break;
	    case 's' :
	      ms_strncpclean (sta, msr->fsdh->station, 5);
	      strncat (filename, sta, (sizeof(filename) - fnlen));
	      if ( def ) strncat (definition, sta, (sizeof(definition) - fnlen));
	      fnlen = strlen (filename);
	      p = w + 1;
	      break;
	    case 'l' :
	      ms_strncpclean (loc, msr->fsdh->location, 2);
	      strncat (filename, loc, (sizeof(filename) - fnlen));
	      if ( def ) strncat (definition, loc, (sizeof(definition) - fnlen));
	      fnlen = strlen (filename);
	      p = w + 1;
	      break;
	    case 'c' :
	      ms_strncpclean (chan, msr->fsdh->channel, 3);
	      strncat (filename, chan, (sizeof(filename) - fnlen));
	      if ( def ) strncat (definition, chan, (sizeof(definition) - fnlen));
	      fnlen = strlen (filename);
	      p = w + 1;
	      break;
	    case 'Y' :
	      snprintf (tstr, sizeof(tstr), "%04d", (int) stime.year);
	      strncat (filename, tstr, (sizeof(filename) - fnlen));
	      if ( def ) strncat (definition, tstr, (sizeof(definition) - fnlen));
	      fnlen = strlen (filename);
	      p = w + 1;
	      break;
	    case 'y' :
	      tdy = (int) stime.year;
	      while ( tdy > 100 )
		{
		  tdy -= 100;
		}
	      snprintf (tstr, sizeof(tstr), "%02d", tdy);
	      strncat (filename, tstr, (sizeof(filename) - fnlen));
	      if ( def ) strncat (definition, tstr, (sizeof(definition) - fnlen));
	      fnlen = strlen (filename);
	      p = w + 1;
	      break;
	    case 'j' :
	      snprintf (tstr, sizeof(tstr), "%03d", (int) stime.day);
	      strncat (filename, tstr, (sizeof(filename) - fnlen));
	      if ( def ) strncat (definition, tstr, (sizeof(definition) - fnlen));
	      fnlen = strlen (filename);
	      p = w + 1;
	      break;
	    case 'H' :
	      snprintf (tstr, sizeof(tstr), "%02d", (int) stime.hour);
	      strncat (filename, tstr, (sizeof(filename) - fnlen));
	      if ( def ) strncat (definition, tstr, (sizeof(definition) - fnlen));
	      fnlen = strlen (filename);
	      p = w + 1;
	      break;
	    case 'M' :
	      snprintf (tstr, sizeof(tstr), "%02d", (int) stime.min);
	      strncat (filename, tstr, (sizeof(filename) - fnlen));
	      if ( def ) strncat (definition, tstr, (sizeof(definition) - fnlen));
	      fnlen = strlen (filename);
	      p = w + 1;
	      break;
	    case 'S' :
	      snprintf (tstr, sizeof(tstr), "%02d", (int) stime.sec);
	      strncat (filename, tstr, (sizeof(filename) - fnlen));
	      if ( def ) strncat (definition, tstr, (sizeof(definition) - fnlen));
	      fnlen = strlen (filename);
	      p = w + 1;
	      break;
	    case 'F' :
	      snprintf (tstr, sizeof(tstr), "%04d", (int) stime.fract);
	      strncat (filename, tstr, (sizeof(filename) - fnlen));
	      if ( def ) strncat (definition, tstr, (sizeof(definition) - fnlen));
	      fnlen = strlen (filename);
	      p = w + 1;
	      break;
	    case 'q' :
	      snprintf (tstr, sizeof(tstr), "%c", msr->dataquality);
	      strncat (filename, tstr, (sizeof(filename) - fnlen));
	      if ( def ) strncat (definition, tstr, (sizeof(definition) - fnlen));
	      fnlen = strlen (filename);
	      p = w + 1;
	      break;
	    case 'L' :
	      snprintf (tstr, sizeof(tstr), "%d", msr->reclen);
	      strncat (filename, tstr, (sizeof(filename) - fnlen));
	      if ( def ) strncat (definition, tstr, (sizeof(definition) - fnlen));
	      fnlen = strlen (filename);
	      p = w + 1;
	      break;
	    case 'r' :
	      snprintf (tstr, sizeof(tstr), "%ld", (long int) (msr->samprate+0.5));
	      strncat (filename, tstr, (sizeof(filename) - fnlen));
	      if ( def ) strncat (definition, tstr, (sizeof(definition) - fnlen));
	      fnlen = strlen (filename);
	      p = w + 1;
	      break;
	    case 'R' :
	      snprintf (tstr, sizeof(tstr), "%.6f", msr->samprate);
	      strncat (filename, tstr, (sizeof(filename) - fnlen));
	      if ( def ) strncat (definition, tstr, (sizeof(definition) - fnlen));
	      fnlen = strlen (filename);
	      p = w + 1;
	      break;
	    case '%' :
	      strncat (filename, "%", (sizeof(filename) - fnlen));
	      fnlen = strlen (filename);
	      p = w + 1;
	      break;
	    case '#' :
	      strncat (filename, "#", (sizeof(filename) - fnlen));
	      fnlen = strlen (filename);
	      p = w + 1;
	      break;
	    default :
	      fprintf (stderr, "Unknown layout format code: '%c'\n", *w);
	      p = w;
	      break;
	    }
	}
      
      strncat (filename, p, (sizeof(filename) - fnlen));
      fnlen = strlen (filename);

      /* If not the last entry then it should be a directory */
      if ( fnptr->next != 0 )
	{
	  if ( access (filename, F_OK) )
	    {
	      if ( errno == ENOENT )
		{
		  if ( dsverbose >= 1 )
		    fprintf (stderr, "Creating directory: %s\n", filename);

		  if (mkdir
		      (filename, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH))
		    {
		      fprintf (stderr, "ds_streamproc: mkdir(%s) %s\n", filename, strerror (errno));
		      strparse (NULL, NULL, &fnlist);
		      return -1;
		    }
		}
	      else
		{
		  fprintf (stderr, "%s: access denied, %s\n", filename, strerror(errno));
		  strparse (NULL, NULL, &fnlist);
		  return -1;
		}
	    }

	  strncat (filename, "/", (sizeof(filename) - fnlen));
	  fnlen++;
	}

      fnptr = fnptr->next;
    }

  strparse (NULL, NULL, &fnlist);

  /* Add ".suffix" to filename and definition if suffix is not 0 */
  if ( suffix )
    {
      snprintf (tstr, sizeof(tstr), ".%ld", suffix);
      strncat (filename, tstr, (sizeof(filename) - fnlen));
      strncat (definition, tstr, (sizeof(definition) - fnlen));
      fnlen = strlen (filename);
    }

  /* Make sure the filename and definition are NULL terminated */
  *(filename + sizeof(filename) - 1) = '\0';
  *(definition + sizeof(definition) -1) = '\0';

  /* Check for previously used stream entry, otherwise create it */
  foundgroup = ds_getstream (datastream, msr, definition, filename);

  if (foundgroup != NULL)
    {
      /* Write binary data samples to approriate file */
      if ( msr->datasamples && msr->numsamples )
	{
	  if ( dsverbose >= 3 )
	    fprintf (stderr, "Writing binary data samples to data stream file %s\n", filename);
	  
	  if ( !write (foundgroup->filed, msr->datasamples, msr->numsamples * ms_samplesize(msr->sampletype)) )
	    {
	      fprintf (stderr, "ds_streamproc: failed to write binary data samples\n");
	      return -1;
	    }
	  else
	    {
	      foundgroup->modtime = time (NULL);	  
	    }
	}
      /* Write the data record to the appropriate file */ 
      else
	{
	  if ( dsverbose >= 3 )
	    fprintf (stderr, "Writing data record to data stream file %s\n", filename);
	  
	  if ( !write (foundgroup->filed, msr->record, msr->reclen) )
	    {
	      fprintf (stderr, "ds_streamproc: failed to write data record\n");
	      return -1;
	    }
	  else
	    {
	      foundgroup->modtime = time (NULL);	  
	    }
	}

      return 0;
    }
  
  return -1;
}  /* End of ds_streamproc() */
Example #4
0
/***************************************************************************
 * msr_normalize_header:
 *
 * Normalize header values between the MSRecord struct and the
 * associated fixed-section of the header and blockettes.  Essentially
 * this updates the SEED structured data in the MSRecord.fsdh struct
 * and MSRecord.blkts chain with values stored at the MSRecord level.
 *
 * Returns the header length in bytes on success or -1 on error.
 ***************************************************************************/
int
msr_normalize_header ( MSRecord *msr, flag verbose )
{
  struct blkt_link_s *cur_blkt;
  char seqnum[7];
  int offset = 0;
  int blktcnt = 0;
  int reclenexp = 0;
  int reclenfind;
  
  if ( ! msr )
    return -1;
  
  /* Update values in fixed section of data header */
  if ( msr->fsdh )
    {
      if ( verbose > 2 )
	ms_log (1, "Normalizing fixed section of data header\n");
      
      /* Roll-over sequence number if necessary */
      if ( msr->sequence_number > 999999 )
	msr->sequence_number = 1;
      
      /* Update values in the MSRecord.fsdh struct */
      snprintf (seqnum, 7, "%06d", msr->sequence_number);
      memcpy (msr->fsdh->sequence_number, seqnum, 6);
      msr->fsdh->dataquality = msr->dataquality;
      msr->fsdh->reserved = ' ';
      ms_strncpopen (msr->fsdh->network, msr->network, 2);
      ms_strncpopen (msr->fsdh->station, msr->station, 5);
      ms_strncpopen (msr->fsdh->location, msr->location, 2);
      ms_strncpopen (msr->fsdh->channel, msr->channel, 3);
      ms_hptime2btime (msr->starttime, &(msr->fsdh->start_time));
      
      /* When the sampling rate is <= 32767 Hertz determine the factor
       * and multipler through rational approximation.  For higher rates
       * set the factor and multiplier to 0. */
      if ( msr->samprate <= 32767.0 )
	{
	  ms_genfactmult (msr->samprate, &(msr->fsdh->samprate_fact), &(msr->fsdh->samprate_mult));
	}
      else
	{
	  if ( verbose > 1 )
	    ms_log (1, "Sampling rate too high to approximate factor & multiplier: %g\n",
		    msr->samprate);
	  msr->fsdh->samprate_fact = 0;
	  msr->fsdh->samprate_mult = 0;
	}
      
      offset += 48;
      
      if ( msr->blkts )
	msr->fsdh->blockette_offset = offset;
      else
	msr->fsdh->blockette_offset = 0;
    }
  
  /* Traverse blockette chain and performs necessary updates*/
  cur_blkt = msr->blkts;
  
  if ( cur_blkt && verbose > 2 )
    ms_log (1, "Normalizing blockette chain\n");
  
  while ( cur_blkt )
    {
      offset += 4;
      
      if ( cur_blkt->blkt_type == 100 && msr->Blkt100 )
	{
	  msr->Blkt100->samprate = (float)msr->samprate;
	  offset += sizeof (struct blkt_100_s);
	}
      else if ( cur_blkt->blkt_type == 1000 && msr->Blkt1000 )
	{
	  msr->Blkt1000->byteorder = msr->byteorder;
	  msr->Blkt1000->encoding = msr->encoding;
	  
	  /* Calculate the record length as an exponent of 2 */
	  for (reclenfind=1, reclenexp=1; reclenfind <= MAXRECLEN; reclenexp++)
	    {
	      reclenfind *= 2;
	      if ( reclenfind == msr->reclen ) break;
	    }
	  
	  if ( reclenfind != msr->reclen )
	    {
	      ms_log (2, "msr_normalize_header(): Record length %d is not a power of 2\n",
		      msr->reclen);
	      return -1;
	    }
	  
	  msr->Blkt1000->reclen = reclenexp;
	  
	  offset += sizeof (struct blkt_1000_s);
	}
      
      else if ( cur_blkt->blkt_type == 1001 )
	{
	  hptime_t sec, usec;
	  
	  /* Insert microseconds offset */
	  sec = msr->starttime / (HPTMODULUS / 10000);
	  usec = msr->starttime - (sec * (HPTMODULUS / 10000));
	  usec /= (HPTMODULUS / 1000000);
	  
	  msr->Blkt1001->usec = (int8_t) usec;
	  offset += sizeof (struct blkt_1001_s);
	}
      
      blktcnt++;
      cur_blkt = cur_blkt->next;
    }

  if ( msr->fsdh )
    msr->fsdh->numblockettes = blktcnt;
  
  return offset;
} /* End of msr_normalize_header() */