⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 traceutils.c

📁 C编写的格式转换程序
💻 C
📖 第 1 页 / 共 3 页
字号:
      mst->endtime = endtime;          }    /* Add samples at the beginning of trace */  else if ( whence == 2 )    {      if ( datasamples && numsamples > 0 )	{	  /* Move any samples to end of buffer */	  if ( mst->numsamples > 0 )	    {	      memmove ((char *)mst->datasamples + (numsamples * samplesize),		       mst->datasamples,		       mst->numsamples * samplesize);	    }	  	  memcpy (mst->datasamples,		  datasamples,		  numsamples * samplesize);	  	  mst->numsamples += numsamples;	}            mst->starttime = starttime;    }    /* Update MSTrace sample count */  if ( numsamples > 0 )    mst->samplecnt += numsamples;    return 0;} /* End of mst_addspan() *//*************************************************************************** * mst_addmsrtogroup: * * Add data samples from a MSRecord to a MSTrace in a MSTraceGroup by * searching the group for the approriate MSTrace and either adding data * to it or creating a new MSTrace if no match found. * * Matching traces are found using the mst_findadjacent() routine.  If * the dataquality flag is true the data quality bytes must also match * otherwise they are ignored. * * Return a pointer to the MSTrace updated or 0 on error. ***************************************************************************/MSTrace *mst_addmsrtogroup ( MSTraceGroup *mstg, MSRecord *msr, flag dataquality,		    double timetol, double sampratetol ){  MSTrace *mst = 0;  hptime_t endtime;  flag whence;  char dq;  if ( ! mstg || ! msr )    return 0;    dq = ( dataquality ) ? msr->dataquality : 0;    endtime = msr_endtime (msr);    if ( endtime == HPTERROR )    {      ms_log (2, "mst_addmsrtogroup(): Error calculating record end time\n");      return 0;    }    /* Find matching, time adjacent MSTrace */  mst = mst_findadjacent (mstg, &whence, dq,			  msr->network, msr->station, msr->location, msr->channel,			  msr->samprate, sampratetol,			  msr->starttime, endtime, timetol);    /* If a match was found update it otherwise create a new MSTrace and     add to end of MSTrace chain */  if ( mst )    {      /* Records with no time coverage do not contribute to a trace */      if ( msr->samplecnt <= 0 || msr->samprate <= 0.0 )	return mst;            if ( mst_addmsr (mst, msr, whence) )	{	  return 0;	}    }  else    {      mst = mst_init (NULL);            mst->dataquality = dq;            strncpy (mst->network, msr->network, sizeof(mst->network));      strncpy (mst->station, msr->station, sizeof(mst->station));      strncpy (mst->location, msr->location, sizeof(mst->location));      strncpy (mst->channel, msr->channel, sizeof(mst->channel));            mst->starttime = msr->starttime;      mst->samprate = msr->samprate;      mst->sampletype = msr->sampletype;            if ( mst_addmsr (mst, msr, 1) )	{	  mst_free (&mst);	  return 0;	}            /* Link new MSTrace into the end of the chain */      if ( ! mstg->traces )	{	  mstg->traces = mst;	}      else	{	  MSTrace *lasttrace = mstg->traces;	  	  while ( lasttrace->next )	    lasttrace = lasttrace->next;	  	  lasttrace->next = mst;	}            mstg->numtraces++;    }    return mst;}  /* End of mst_addmsrtogroup() *//*************************************************************************** * mst_addtracetogroup: * * Add a MSTrace to a MSTraceGroup at the end of the MSTrace chain. * * Return a pointer to the MSTrace added or 0 on error. ***************************************************************************/MSTrace *mst_addtracetogroup ( MSTraceGroup *mstg, MSTrace *mst ){  MSTrace *lasttrace;  if ( ! mstg || ! mst )    return 0;    if ( ! mstg->traces )    {      mstg->traces = mst;    }  else    {      lasttrace = mstg->traces;            while ( lasttrace->next )	lasttrace = lasttrace->next;            lasttrace->next = mst;    }    mst->next = 0;    mstg->numtraces++;    return mst;} /* End of mst_addtracetogroup() *//*************************************************************************** * mst_groupheal: * * Check if traces in MSTraceGroup can be healed, if contiguous segments * belong together they will be merged.  This routine is only useful * if the trace group was assembled from segments out of time order * (e.g. a file of Mini-SEED records not in time order) but forming * contiguous time coverage.  The MSTraceGroup will be sorted using * mst_groupsort() before healing. * * The time tolerance and sample rate tolerance are used to determine * if the traces are indeed the same.  If timetol is -1.0 the default * tolerance of 1/2 the sample period will be used.  If samprratetol * is -1.0 the default tolerance check of abs(1-sr1/sr2) < 0.0001 is * used (defined in libmseed.h). * * Return number of trace mergings on success otherwise -1 on error. ***************************************************************************/intmst_groupheal ( MSTraceGroup *mstg, double timetol, double sampratetol ){  int mergings = 0;  MSTrace *curtrace = 0;  MSTrace *nexttrace = 0;  MSTrace *searchtrace = 0;  MSTrace *prevtrace = 0;  int8_t merged = 0;  double postgap, pregap, delta;    if ( ! mstg )    return -1;    /* Sort MSTraceGroup before any healing */  if ( mst_groupsort (mstg, 1) )    return -1;    curtrace = mstg->traces;    while ( curtrace )    {      nexttrace = mstg->traces;      prevtrace = mstg->traces;            while ( nexttrace )	{	  searchtrace = nexttrace;	  nexttrace = searchtrace->next;	  	  /* Do not process the same MSTrace we are trying to match */	  if ( searchtrace == curtrace )	    {	      prevtrace = searchtrace;	      continue;	    }	  	  /* Check if this trace matches the curtrace */	  if ( strcmp (searchtrace->network, curtrace->network) ||	       strcmp (searchtrace->station, curtrace->station) ||	       strcmp (searchtrace->location, curtrace->location) ||	       strcmp (searchtrace->channel, curtrace->channel) )	    {	      prevtrace = searchtrace;	      continue;	    }      	  	  /* Perform default samprate tolerance check if requested */	  if ( sampratetol == -1.0 )	    {	      if ( ! MS_ISRATETOLERABLE (searchtrace->samprate, curtrace->samprate) )		{		  prevtrace = searchtrace;		  continue;		}	    }	  /* Otherwise check against the specified sample rates tolerance */	  else if ( ms_dabs(searchtrace->samprate - curtrace->samprate) > sampratetol )	    {	      prevtrace = searchtrace;	      continue;	    }	  	  merged = 0;	  	  /* post/pregap are negative when searchtrace overlaps curtrace	   * segment and positive when there is a time gap.	   */	  delta = ( curtrace->samprate ) ? (1.0 / curtrace->samprate) : 0.0;	  	  postgap = ((double)(searchtrace->starttime - curtrace->endtime)/HPTMODULUS) - delta;	  	  pregap = ((double)(curtrace->starttime - searchtrace->endtime)/HPTMODULUS) - delta;	  	  /* Calculate default time tolerance (1/2 sample period) if needed */	  if ( timetol == -1.0 )	    timetol = 0.5 * delta;	  	  /* Fits right at the end of curtrace */	  if ( ms_dabs(postgap) <= timetol )	    {	      /* Merge searchtrace with curtrace */	      mst_addspan (curtrace, searchtrace->starttime, searchtrace->endtime,			   searchtrace->datasamples, searchtrace->numsamples,			   searchtrace->sampletype, 1);	      	      /* If no data is present, make sure sample count is updated */	      if ( searchtrace->numsamples <= 0 )		curtrace->samplecnt += searchtrace->samplecnt;	      	      /* If qualities do not match reset the indicator */	      if (curtrace->dataquality != searchtrace->dataquality)		curtrace->dataquality = 0;	      merged = 1;	    }	  	  /* Fits right at the beginning of curtrace */	  else if ( ms_dabs(pregap) <= timetol )	    {	      /* Merge searchtrace with curtrace */	      mst_addspan (curtrace, searchtrace->starttime, searchtrace->endtime,			   searchtrace->datasamples, searchtrace->numsamples,			   searchtrace->sampletype, 2);	      	      /* If no data is present, make sure sample count is updated */	      if ( searchtrace->numsamples <= 0 )		curtrace->samplecnt += searchtrace->samplecnt;	      	      /* If qualities do not match reset the indicator */	      if (curtrace->dataquality != searchtrace->dataquality)		curtrace->dataquality = 0;	      	      merged = 1;	    }	 	  /* If searchtrace was merged with curtrace remove it from the chain */	  if ( merged )	    {	      /* Re-link trace chain and free searchtrace */	      if ( searchtrace == mstg->traces )		mstg->traces = nexttrace;	      else		prevtrace->next = nexttrace;	      	      mst_free (&searchtrace);	      	      mstg->numtraces--;	      mergings++;	    }	  else	    {	      prevtrace = searchtrace;	    }	}            curtrace = curtrace->next;    }  return mergings;}  /* End of mst_groupheal() *//*************************************************************************** * mst_groupsort: * * Sort a MSTraceGroup using a mergesort algorithm.  MSTrace entries * are compared using the mst_groupsort_cmp() function. * * The mergesort implementation was inspired by the listsort function * published and copyright 2001 by Simon Tatham. * * Return 0 on success and -1 on error. ***************************************************************************/intmst_groupsort ( MSTraceGroup *mstg, flag quality ){  MSTrace *p, *q, *e, *top, *tail;  int nmerges;  int insize, psize, qsize, i;    if ( ! mstg )    return -1;    if ( ! mstg->traces )    return 0;    top = mstg->traces;  insize = 1;    for (;;)    {      p = top;      top = NULL;      tail = NULL;            nmerges = 0;  /* count number of merges we do in this pass */            while ( p )        {          nmerges++;  /* there exists a merge to be done */	            /* step `insize' places along from p */          q = p;          psize = 0;          for (i = 0; i < insize; i++)            {              psize++;              q = q->next;              if ( ! q )                break;            }                    /* if q hasn't fallen off end, we have two lists to merge */          qsize = insize;	            /* now we have two lists; merge them */          while ( psize > 0 || (qsize > 0 && q) )            {              /* decide whether next element of merge comes from p or q */              if ( psize == 0 )                {  /* p is empty; e must come from q. */                  e = q; q = q->next; qsize--;                }              else if ( qsize == 0 || ! q )                {  /* q is empty; e must come from p. */                  e = p; p = p->next; psize--;                }              else if ( mst_groupsort_cmp (p, q, quality) <= 0 )                {  /* First element of p is lower (or same), e must come from p. */                  e = p; p = p->next; psize--;                }              else                {  /* First element of q is lower; e must come from q. */                  e = q; q = q->next; qsize--;                }	                    /* add the next element to the merged list */              if ( tail )                tail->next = e;              else                top = e;	                    tail = e;            }	            /* now p has stepped `insize' places along, and q has too */          p = q;        }            tail->next = NULL;            /* If we have done only one merge, we're finished. */      if ( nmerges <= 1 )   /* allow for nmerges==0, the empty list case */        {          mstg->traces = top;          	  return 0;        }            /* Otherwise repeat, merging lists twice the size */      insize *= 2;    }} /* End of mst_groupsort() *//*************************************************************************** * mst_groupsort_cmp: * * Compare two MSTrace entities for the purposes of sorting a * MSTraceGroup.  Criteria for MSTrace comparison are (in order of * testing): source name, start time, descending endtime (longest * trace first) and sample rate. * * Return 1 if mst1 is "greater" than mst2, otherwise return 0. ***************************************************************************/static intmst_groupsort_cmp ( MSTrace *mst1, MSTrace *mst2, flag quality ){  char src1[50], src2[50];  int strcmpval;    if ( ! mst1 || ! mst2 )    return -1;    mst_srcname (mst1, src1, quality);  mst_srcname (mst2, src2, quality);    strcmpval = strcmp (src1, src2);    /* If the source names do not match make sure the "greater" string is 2nd,   * otherwise, if source names do match, make sure the later start time is 2nd   * otherwise, if start times match, make sure the earlier end time is 2nd   * otherwise, if end times match, make sure the highest sample rate is 2nd   */  if ( strcmpval > 0 )    {      return 1;    }  else if ( strcmpval == 0 )    {      if ( mst1->starttime > mst2->starttime )	{	  return 1;	}      else if ( mst1->starttime == mst2->starttime )	{	  if ( mst1->endtime < mst2->endtime )	    {	      return 1;	    }	  else if ( mst1->endtime == mst2->endtime )	    {	      if ( ! MS_ISRATETOLERABLE (mst1->samprate, mst2->samprate) &&		   mst1->samprate > mst2->samprate )		{		  return 1;		}	    }	}    }    return 0;} /* End of mst_groupsort_cmp() *//*************************************************************************** * mst_srcname: * * Generate a source name string for a specified MSTrace in the * format: 'NET_STA_LOC_CHAN[_QUAL]'.  The quality is added to the * srcname if the quality flag argument is 1 and mst->dataquality is * not zero.  The passed srcname must have enough room for the * resulting string. * * Returns a pointer to the resulting string or NULL on error. ***************************************************************************/char *mst_srcname (MSTrace *mst, char *srcname, flag quality){  char *src = srcname;  char *cp = srcname;    if ( ! mst || ! srcname )    return NULL;    /* Build the source name string */  cp = mst->network;  while ( *cp ) { *src++ = *cp++; }  *src++ = '_';  cp = mst->station;  while ( *cp ) { *src++ = *cp++; }    *src++ = '_';  cp = mst->location;  while ( *cp ) { *src++ = *cp++; }    *src++ = '_';  cp = mst->channel;  while ( *cp ) { *src++ = *cp++; }      if ( quality && mst->dataquality )    {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -