Main Page   Class Hierarchy   Compound List   File List   Compound Members   File Members  

rw_strongmotionII.c

Go to the documentation of this file.
00001 /*
00002  *   THIS FILE IS UNDER RCS - DO NOT MODIFY UNLESS YOU HAVE
00003  *   CHECKED IT OUT USING THE COMMAND CHECKOUT.
00004  *
00005  *    $Id: rw__strongmotionII_8c-source.html 2161 2006-05-19 16:55:03Z paulf $
00006  *
00007  *    Revision history:
00008  *     $Log$
00008  *     Revision 1.1  2006/05/19 16:55:02  paulf
00008  *     first inclusion
00008  *
00009  *     Revision 1.3  2001/06/19 17:26:02  dietz
00010  *     Fixed wr_strongmotionII to print SM_NULL values properly (it had been
00011  *     taking the absolute value of them by mistake)
00012  *
00013  *     Revision 1.2  2001/04/18 17:56:27  dietz
00014  *     wr_strongmotionII: made sure pga,pgv,pgd are written as absolute values
00015  *
00016  *     Revision 1.1  2001/04/17 17:25:46  davidk
00017  *     Initial revision
00018  *
00019  *
00020  *
00021  */
00022 
00023 /* rw_strongmotionII.c
00024  *
00025  * Contains functions in that convert from a
00026  * TYPE_STRONGMOTION message to a structure and visa versa.
00027  *
00028  * written by Lynn Dietz   October, 1999
00029  */
00030 
00031 #include <stdio.h>
00032 #include <string.h>
00033 #include <time.h>
00034 #include <chron3.h>
00035 #include <time_ew.h>
00036 #include <rw_strongmotionII.h>
00037 
00038 #define ABS(X) (((X) >= 0) ? (X) : -(X))
00039 
00040 void logit( char *, char *, ... );   /* logit.c      sys-independent  */
00041 static int   strappend( char *s1, int s1max, char *s2 );
00042 static int   tokenlength( char *begtok, char c );
00043 static char *datestr24( double t, char *pbuf, int len );
00044 static int   addtimestr( char *buf, int buflen, double t );
00045 
00046 static char *sNullDate = "0000/00/00 00:00:00.000";
00047 static char *sUnknown  = "?";
00048 
00049 /********************************************************************
00050  * rd_strongmotionII()                                              *
00051  * Reads an ascii TYPE_STRONGMOTION2 message and fills in a SM_INFO *
00052  * structure.                                                       *
00053  * Returns 0 on success, -1 on failure                              *
00054  ********************************************************************/
00055 int rd_strongmotionII( char *msg, int msglen, SM_INFO *sm )
00056 {
00057    char     *line;      /* pointer to current line in msg */
00058    char     *nextline;  /* working pointer into msg */
00059    char     *begtok;    /* points to the beginning of this token */
00060    char     *endline;   /* points at end of line */
00061    int       len;       /* length (bytes) of the next token */
00062    int       nline;     /* number of lines read from msg so far */
00063    int       nfreq;
00064    int       i;
00065    struct tm stm;       /* time structure for timestamp */
00066    time_t    tsec;      /* timestamp in whole sec since 1970 */    
00067    int       msec;      /* thousandths of seconds field of timestamp */
00068 
00069 
00070    memset( sm, 0, sizeof(SM_INFO) );     /* zero output structure */
00071    nextline = msg;
00072    nline = 0;
00073    nfreq = 0;
00074 
00075 
00076 /* Read next line from the message into working buffer */
00077    while( nextline < (msg+msglen-1) )
00078    {
00079      line    = nextline;
00080      len     = tokenlength( line, '\n' ); 
00081      endline = line + len;
00082      nline++;
00083      nextline += len + 1;
00084 
00085  /* First line = SCNL name */
00086      if( nline == 1 )
00087      {
00088        if( strncmp(line,"SCNL:", 5) != 0 ) return( -1 );
00089        begtok = line + 5;
00090 
00091        while( begtok[0] == ' ' ) begtok++;    /* go to 1st non-blank char */
00092        if( begtok >= endline ) return( -1 );
00093        len = tokenlength( begtok, '.' );
00094        if( len >= TRACE_STA_LEN ) return( -1 );
00095        strncpy( sm->sta, begtok, len ); 
00096        begtok += len + 1;
00097 
00098        if( begtok >= endline ) return( -1 );
00099        len = tokenlength( begtok, '.' );
00100        if( len >= TRACE_CHAN_LEN ) return( -1 );
00101        strncpy( sm->comp, begtok, len ); 
00102        begtok += len + 1;
00103 
00104        if( begtok >= endline ) return( -1 );
00105        len = tokenlength( begtok, '.' );
00106        if( len >= TRACE_NET_LEN ) return( -1 );
00107        strncpy( sm->net, begtok, len ); 
00108        begtok += len + 1;
00109 
00110        if( begtok > endline ) return( -1 );
00111        len = tokenlength( begtok, '\n' );
00112        if( len >= TRACE_LOC_LEN ) return( -1 );
00113        strncpy( sm->loc, begtok, len ); 
00114      }
00115 
00116   /* Second line = timestamp from field unit */
00117      else if( nline == 2 )
00118      {
00119        memset( &stm, 0, sizeof(struct tm) ); /* zero the time structure */
00120        if( sscanf( line, "TIME: %d/%d/%d %d:%d:%d.%d", 
00121                   &stm.tm_year, &stm.tm_mon, &stm.tm_mday, &stm.tm_hour,
00122                   &stm.tm_min, &stm.tm_sec, &msec ) != 7 ) return( -1 );
00123        stm.tm_year -= 1900;  /* to convert to definition of struct tm */
00124        stm.tm_mon  -= 1;     /* to convert to definition of struct tm */
00125        tsec  = timegm( &stm );
00126        sm->t = (double)tsec + 0.001*(double)msec;
00127      }
00128 
00129   /* Third line = alternate timestamp and its code */
00130      else if( nline == 3 )
00131      {
00132        memset( &stm, 0, sizeof(struct tm) ); /* zero the time structure */
00133        if( sscanf( line, "ALT: %d/%d/%d %d:%d:%d.%d CODE: %d", 
00134                   &stm.tm_year, &stm.tm_mon, &stm.tm_mday, &stm.tm_hour,
00135                   &stm.tm_min, &stm.tm_sec, &msec, &(sm->altcode) ) != 8 ) 
00136                   return( -1 );
00137        if( stm.tm_year == 0 ) {
00138          sm->talt = 0.0;
00139        } else {
00140          stm.tm_year -= 1900;  /* to convert to definition of struct tm */
00141          stm.tm_mon  -= 1;     /* to convert to definition of struct tm */
00142          tsec  = timegm( &stm );
00143          sm->talt = (double)tsec + 0.001*(double)msec;
00144        }
00145      }
00146 
00147   /* Fourth line = peak acceleration values */
00148      else if( nline == 4 )
00149      {
00150        memset( &stm, 0, sizeof(struct tm) ); /* zero the time structure */
00151        if( sscanf( line, "PGA: %lf TPGA: %d/%d/%d %d:%d:%d.%d", 
00152                   &(sm->pga), &stm.tm_year, &stm.tm_mon, &stm.tm_mday,
00153                   &stm.tm_hour, &stm.tm_min, &stm.tm_sec, &msec ) != 8 ) 
00154                   return( -1 );
00155        if( stm.tm_year == 0 ) {
00156          sm->tpga = 0.0;
00157        } else {
00158          stm.tm_year -= 1900;  /* to convert to definition of struct tm */
00159          stm.tm_mon  -= 1;     /* to convert to definition of struct tm */
00160          tsec  = timegm( &stm );
00161          sm->tpga = (double)tsec + 0.001*(double)msec;
00162        }
00163      }
00164 
00165   /* Fifth line = peak velocity values */
00166      else if( nline == 5 )
00167      {
00168        memset( &stm, 0, sizeof(struct tm) ); /* zero the time structure */
00169        if( sscanf( line, "PGV: %lf TPGV: %d/%d/%d %d:%d:%d.%d", 
00170                   &(sm->pgv), &stm.tm_year, &stm.tm_mon, &stm.tm_mday,
00171                   &stm.tm_hour, &stm.tm_min, &stm.tm_sec, &msec ) != 8 ) 
00172                   return( -1 );
00173        if( stm.tm_year == 0 ) {
00174          sm->tpgv = 0.0;
00175        } else {
00176          stm.tm_year -= 1900;  /* to convert to definition of struct tm */
00177          stm.tm_mon  -= 1;     /* to convert to definition of struct tm */
00178          tsec  = timegm( &stm );
00179          sm->tpgv = (double)tsec + 0.001*(double)msec;
00180        }
00181      }
00182 
00183   /* Sixth line = peak displacement values */
00184      else if( nline == 6 )
00185      {
00186        memset( &stm, 0, sizeof(struct tm) ); /* zero the time structure */
00187        if( sscanf( line, "PGD: %lf TPGD: %d/%d/%d %d:%d:%d.%d", 
00188                   &(sm->pgd), &stm.tm_year, &stm.tm_mon, &stm.tm_mday,
00189                   &stm.tm_hour, &stm.tm_min, &stm.tm_sec, &msec ) != 8 ) 
00190                   return( -1 );
00191        if( stm.tm_year == 0 ) {
00192          sm->tpgd = 0.0;
00193        } else {
00194          stm.tm_year -= 1900;  /* to convert to definition of struct tm */
00195          stm.tm_mon  -= 1;     /* to convert to definition of struct tm */
00196          tsec  = timegm( &stm );
00197          sm->tpgd = (double)tsec + 0.001*(double)msec;
00198        }
00199      }
00200 
00201   /* Seventh line = response spectral acceleration */
00202      else if( nline == 7 )
00203      {
00204        if( sscanf( line, "RSA: %d", &(sm->nrsa) ) != 1 ) return( -1 );
00205        if( sm->nrsa > SM_MAX_RSA ) return( -1 );
00206        begtok = line;
00207        for( i=0; i<sm->nrsa; i++ )
00208        {
00209          begtok += tokenlength( begtok, '/' ) + 1;
00210          if( begtok >= endline ) return( -1 );
00211          if( sscanf( begtok, "%lf %lf", 
00212                     &(sm->pdrsa[i]), &(sm->rsa[i]) ) != 2 ) return( -1 );
00213        } 
00214      }
00215 
00216   /* Eighth line = eventid and author */
00217      else if( nline == 8 )
00218      {
00219        if( strncmp(line,"QID:", 4) != 0 ) return( -1 );
00220        begtok = line + 4;
00221 
00222        while( begtok[0] == ' ' ) begtok++;    /* go to 1st non-blank char */
00223        if( begtok >= endline ) return( -1 );
00224        len = tokenlength( begtok, ' ' );
00225        if( len >= EVENTID_SIZE ) return( -1 );
00226        strncpy( sm->qid, begtok, len ); 
00227        if( strcmp( sm->qid, sUnknown ) == 0 ) sm->qid[0] = '\0';
00228        begtok += len + 1;
00229 
00230        while( begtok[0] == ' ' ) begtok++;    /* go to 1st non-blank char */
00231        if( begtok >= endline ) return( -1 );
00232        len = tokenlength( begtok, '\n' );
00233        if( len >= AUTHOR_FIELD_SIZE ) return( -1 );
00234        strncpy( sm->qauthor, begtok, len ); 
00235        if( strcmp( sm->qauthor, sUnknown ) == 0 ) sm->qauthor[0] = '\0';
00236      }
00237 
00238    } /*end while*/
00239 
00240 
00241    return( 0 );
00242 }
00243 
00244 /********************************************************************
00245  * wr_strongmotionII()                                              *
00246  * Reads a SM_INFO structure and writes an ascii TYPE_STRONGMOTION2 *
00247  * message (null terminated)                                        *
00248  * Returns 0 on success, -1 on failure (buffer overflow)            *
00249  ********************************************************************/
00250 int wr_strongmotionII( SM_INFO *sm, char *buf, int buflen )
00251 {
00252    char     tmp[256]; /* working buffer */
00253    char    *qid;
00254    char    *qauthor;
00255    int      i;
00256 
00257    memset( buf, 0, (size_t)buflen );    /* zero output buffer */
00258 
00259 /* channel codes */
00260    sprintf( buf, "SCNL: %s.%s.%s.%s", 
00261             sm->sta, sm->comp, sm->net, sm->loc );
00262 
00263 /* field time */
00264    if( strappend( buf, buflen, "\nTIME: " ) ) return ( -1 );
00265    datestr24( sm->t, tmp, 256 );  
00266    if( strappend( buf, buflen, tmp ) ) return( -1 );
00267 
00268 /* alternate time & its code */
00269    if( strappend( buf, buflen, "\nALT: " ) ) return ( -1 );
00270    if( addtimestr( buf, buflen, sm->talt ) ) return ( -1 );
00271    sprintf( tmp, " CODE: %d", sm->altcode );
00272    if( strappend( buf, buflen, tmp ) ) return( -1 );
00273 
00274 /* Print peak acceleration value & time */
00275    sprintf( tmp, "\nPGA: %.6lf TPGA: ", (sm->pga!=SM_NULL ? ABS(sm->pga) : sm->pga) );
00276    if( strappend( buf, buflen, tmp ) ) return( -1 );
00277    if( addtimestr( buf, buflen, sm->tpga ) ) return ( -1 );
00278       
00279 /* Print peak velocity value & time */
00280    sprintf( tmp, "\nPGV: %.6lf TPGV: ", (sm->pgv!=SM_NULL ? ABS(sm->pgv) : sm->pgv) );
00281    if( strappend( buf, buflen, tmp ) ) return( -1 );
00282    if( addtimestr( buf, buflen, sm->tpgv ) ) return ( -1 );
00283       
00284 /* Print peak displacement value & time */
00285    sprintf( tmp, "\nPGD: %.6lf TPGD: ", (sm->pgd!=SM_NULL ? ABS(sm->pgd) : sm->pgd) );
00286    if( strappend( buf, buflen, tmp ) ) return( -1 );
00287    if( addtimestr( buf, buflen, sm->tpgd ) ) return ( -1 );
00288 
00289 /* Print the response spectrum */
00290    sprintf( tmp, "\nRSA: %d", sm->nrsa );
00291    if( strappend( buf, buflen, tmp ) ) return( -1 );
00292    for( i=0; i<sm->nrsa; i++ )
00293    {
00294      sprintf( tmp, "/%.2lf %.6lf", sm->pdrsa[i], sm->rsa[i] );
00295      if( strappend( buf, buflen, tmp ) ) return( -1 );
00296    }   
00297 
00298 /* Print the eventid & event author */
00299    qid     = sm->qid;
00300    qauthor = sm->qauthor;
00301    if( strlen(qid)     == 0 ) qid     = sUnknown;
00302    if( strlen(qauthor) == 0 ) qauthor = sUnknown;
00303    sprintf( tmp, "\nQID: %s %s\n", qid, qauthor );
00304    if( strappend( buf, buflen, tmp ) ) return( -1 );
00305 
00306    return( 0 );
00307 }
00308 
00309 
00310 
00311 /********************************************************************
00312  * log_strongmotionII()                                             *
00313  * Writes the contents of a SM_INFO structure to an Earthworm       *
00314  * log file                                                         *
00315  ********************************************************************/
00316 void log_strongmotionII( SM_INFO *sm )
00317 {
00318    char date[30];
00319    int  i;
00320 
00321    logit("", "SCNL: %s.%s.%s.%s\n", 
00322            sm->sta, sm->comp, sm->net, sm->loc );
00323   
00324 /* Log time values */
00325    datestr24( sm->t, date, 30 );
00326    logit("", "Time: %s  (%.3lf)\n", date, sm->t );
00327    datestr24( sm->talt, date, 30 );
00328    logit("", "Alt:  %s  (%.3lf)  code: %d\n", 
00329             date, sm->talt, sm->altcode );
00330 
00331 
00332 /* Print peak acceleration values */
00333    datestr24( sm->tpga, date, 30 );
00334    logit("", "PGA: %.6lf  TGPA: %s (%.3lf)\n",
00335             sm->pga, date, sm->tpga );
00336       
00337 /* Print peak velocity values */
00338    datestr24( sm->tpgv, date, 30 );
00339    logit("", "PGV: %.6lf  TGPV: %s (%.3lf)\n",
00340             sm->pgv, date, sm->tpgv );
00341 
00342 /* Print peak displacement values */
00343    datestr24( sm->tpgd, date, 30 );
00344    logit("", "PGD: %.6lf  TGPD: %s (%.3lf)\n",
00345             sm->pgd, date, sm->tpgd );
00346 
00347 
00348 /* Print number of points in the response spectrum */
00349    logit("","RSA: %d ", sm->nrsa );
00350    for( i=0; i<sm->nrsa; i++ )
00351    {
00352       logit("", " /%.2lf %.6lf", sm->pdrsa[i], sm->rsa[i] );
00353    }   
00354 
00355 /* Print eventid & author */
00356    logit("","\nQID: %s %s\n", sm->qid, sm->qauthor);
00357 
00358    return;
00359 }
00360 
00361 
00362 /**********************************************************
00363  * Converts time (double, seconds since 1970:01:01) to    *
00364  * a 23-character, null-terminated string in the form of  *
00365  *            yyyy/mm/dd hh:mm:ss.sss                     *
00366  * Time is displayed in UTC                               *
00367  * Target buffer must be 24-chars long to have room for   *
00368  * null-character                                         *
00369  **********************************************************/
00370 char *datestr24( double t, char *pbuf, int len )
00371 {
00372    time_t    tt;       /* time as time_t                  */
00373    struct tm stm;      /* time as struct tm               */
00374    int       t_msec;   /* milli-seconds part of time      */
00375 
00376 /* Make sure target is big enough
00377  ********************************/
00378    if( len < 24 ) return( (char *)NULL );
00379 
00380 /* Convert double time to other formats
00381  **************************************/
00382    t += 0.0005;  /* prepare to round to the nearest 1000th */
00383    tt     = (time_t) t;
00384    t_msec = (int)( (t - tt) * 1000. );
00385    gmtime_ew( &tt, &stm );
00386 
00387 /* Build character string
00388  ************************/
00389    sprintf( pbuf,
00390            "%04d/%02d/%02d %02d:%02d:%02d.%03d",
00391             stm.tm_year+1900,
00392             stm.tm_mon+1,
00393             stm.tm_mday,
00394             stm.tm_hour,
00395             stm.tm_min,
00396             stm.tm_sec,
00397             t_msec );
00398 
00399    return( pbuf );
00400 }
00401 
00402 
00403 /********************************************************************
00404  * addtimestr() append a date string to the end of existing string  *
00405  *   Return -1 if result would overflow the target,                 *
00406  *           0 if everything went OK                                *
00407  ********************************************************************/
00408 int addtimestr( char *buf, int buflen, double t )
00409 {
00410    char tmp[30];
00411 
00412    if( t == 0.0 )
00413    {
00414      if( strappend( buf, buflen, sNullDate ) ) return( -1 );
00415    } else {
00416      datestr24( t, tmp, 30 );  
00417      if( strappend( buf, buflen, tmp ) ) return( -1 );
00418    }
00419    return( 0 );
00420 }
00421 
00422 /********************************************************************
00423  * strappend() append second null-terminated character string to    *
00424  * the first as long as there's enough room in the target buffer    * 
00425  * for both strings and the null-byte                               *
00426  ********************************************************************/
00427 int strappend( char *s1, int s1max, char *s2 )
00428 {
00429    if( (int)strlen(s1)+(int)strlen(s2)+1 > s1max ) return( -1 );
00430    strcat( s1, s2 );
00431    return( 0 );
00432 }
00433 
00434 /********************************************************************
00435  * tokenlength() given a null-terminated character string and a     *
00436  * character that delimits the end of a token, tokenlength returns  * 
00437  * the length (in bytes) of the next token. If the character wasn't * 
00438  * found, tokenlength returns the length of the string.             *
00439  ********************************************************************/
00440 int tokenlength( char *begtok, char c )
00441 {
00442    char    *endtok;   /* points to the end of this token */
00443 
00444    endtok = strchr( begtok, c );
00445    if( endtok == NULL ) return( (int)strlen(begtok) );
00446    return( (int)(endtok-begtok) );
00447 }
00448 
00449 
00450 /* Sample TYPE_STRONGMOTION2 message (between ------):
00451 ------------------------------------------------
00452 SCNL: CMB.BHZ.BK.
00453 TIME: 2001/02/25 02:37:00.000
00454 ALT:  2001/02/25 02:40:40.000 CODE: 1
00455 PGA: 6.846210 TPGA: 2001/02/25 02:37:00.000
00456 PGV: 0.140000 TPGV: 2001/02/25 02:37:00.000
00457 PGD: 0.000000 TPGD: 2001/02/25 02:37:00.000
00458 RSA: 3/0.30 4.415404/1.00 0.925639/3.00 0.297907
00459 QID: 41059467 014024003:UCB
00460 ------------------------------------------------
00461 */

Generated on Tue May 6 09:16:08 2003 for Earthworm Libs by doxygen1.3-rc3