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

# rw_strongmotion.c

Go to the documentation of this file.

    00001
    00002 /*
    00003  *   THIS FILE IS UNDER RCS - DO NOT MODIFY UNLESS YOU HAVE
    00004  *   CHECKED IT OUT USING THE COMMAND CHECKOUT.
    00005  *
    00006  *    $Id: rw__strongmotion_8c-source.html,v 1.1 2006/05/19 16:55:02 paulf Exp $
    00007  *
    00008  *    Revision history:
    00009  *     $Log: rw__strongmotion_8c-source.html,v $
    00009  *     Revision 1.1  2006/05/19 16:55:02  paulf
    00009  *     first inclusion
    00009  *
    00010  *     Revision 1.2  2000/02/25 18:07:56  dietz
    00011  *     kludged to ensure that vendor an serialnumber are never null strings
    00012  *
    00013  *     Revision 1.1  2000/02/14 18:51:48  lucky
    00014  *     Initial revision
    00015  *
    00016  *
    00017  */
    00018
    00019 /* rw_strongmotion.c
    00020  *
    00021  * Contains functions in that convert from a
    00022  * TYPE_STRONGMOTION message to a structure and visa versa.
    00023  *
    00024  * written by Lynn Dietz   October, 1999
    00025  */
    00026
    00027 #include <stdio.h>
    00028 #include <string.h>
    00029 #include <time.h>
    00030 #include <chron3.h>
    00031 #include <time_ew.h>
    00032 #include <rw_strongmotion.h>
    00033
    00034 void logit( char *, char *, ... );   /* logit.c      sys-independent  */
    00035 static int strappend( char *s1, int s1max, char *s2 );
    00036 static int tokenlength( char *begtok, char c );
    00037
    00038 static char *sNullDate = "0000/00/00 00:00:00.00";
    00039
    00040 /********************************************************************
    00041  * rd_strongmotion()                                                *
    00042  * Reads an ascii TYPE_STRONGMOTION message and fills in a SM_DATA  *
    00043  * structure.                                                       *
    00044  * Returns 0 on success, -1 on failure                              *
    00045  ********************************************************************/
    00046 int rd_strongmotion( char *msg, int msglen, SM_DATA *sm )
    00047 {
    00048    char      line[256];
    00049    char     *nextline;  /* working pointer into msg */
    00050    char     *begtok;    /* points to the beginning of this token */
    00051    char     *endtok;    /* points to the end of this token */
    00052    char     *endline;   /* points at end of line */
    00053    int       len;       /* length (bytes) of the next token */
    00054    int       nline;     /* number of lines read from msg so far */
    00055    int       nchan;
    00056    int       nfreq;
    00057    int       i,j;
    00058    struct tm stm;       /* time structure for timestamp */
    00059    time_t    tsec;      /* timestamp in whole sec since 1970 */
    00060    int       hsec;      /* hundredths of seconds field of timestamp */
    00061
    00062
    00063    memset( sm, 0, sizeof(SM_DATA) );     /* zero output structure */
    00064    nextline = msg;
    00065    nline = 0;
    00066    nfreq = 0;
    00067
    00068
    00069 /* Read next line from the message into working buffer */
    00070    while( nextline < (msg+msglen-1) )
    00071    {
    00072      len = tokenlength( nextline, '\n' );
    00073      if( len >= 256 ) return( -1 );
    00074      strncpy( line, nextline, len );
    00075      line[len] = 0; /* null terminate the line */
    00076      endline = line + strlen(line);
    00077      nline++;
    00078      nextline += len + 1;
    00079
    00080   /* First line = Vendor */
    00081      if( nline == 1 )
    00082      {
    00083        if( strncmp(line,"Vendor:", 7) != 0 ) return( -1 );
    00084        begtok = line + 7;
    00085        while( begtok[0] == ' ' ) begtok++;    /* go to 1st non-blank char */
    00086        len = strlen(begtok);
    00087        if( len > SM_VENDOR_LEN ) return( -1 );
    00088        strncpy( sm->vendor, begtok, len );
    00089      }
    00090
    00091   /* Second line = Serial number */
    00092      else if( nline == 2 )
    00093      {
    00094        if( strncmp(line,"SerialNo:", 9) != 0 ) return( -1 );
    00095        begtok = line + 9;
    00096        while( begtok[0] == ' ' ) begtok++;    /* go to 1st non-blank char */
    00097        len = strlen(begtok);
    00098        if( len > SM_VENDOR_LEN ) return( -1 );
    00099        strncpy( sm->sn, begtok, len );
    00100      }
    00101
    00102   /* Third line = number of channels */
    00103      else if( nline == 3 )
    00104      {
    00105        if( strncmp(line,"nchan:", 5) != 0 ) return( -1 );
    00106        if( sscanf( line, "nchan: %d", &(sm->nch) ) != 1 ) return( -1 );
    00107      }
    00108
    00109   /* Fourth line = timestamp from field unit */
    00110      else if( nline == 4 )
    00111      {
    00112        if( strncmp(line,"Field Time:", 11) != 0 ) return( -1 );
    00113        memset( &stm, 0, sizeof(struct tm) ); /* zero the time structure */
    00114        if( sscanf( line, "Field Time: %d/%d/%d %d:%d:%d.%d",
    00115                   &stm.tm_year, &stm.tm_mon, &stm.tm_mday, &stm.tm_hour,
    00116                   &stm.tm_min, &stm.tm_sec, &hsec ) != 7 ) return( -1 );
    00117        stm.tm_year -= 1900;  /* to convert to definition of struct tm */
    00118        stm.tm_mon  -= 1;     /* to convert to definition of struct tm */
    00119        tsec  = timegm( &stm );
    00120        sm->tfield = (double)tsec + 0.01*(double)hsec;
    00121      }
    00122
    00123   /* Fifth line = alternate timestamp and its code */
    00124      else if( nline == 5 )
    00125      {
    00126        if( strncmp(line,"Alternate Time:", 15) != 0 ) return( -1 );
    00127        memset( &stm, 0, sizeof(struct tm) ); /* zero the time structure */
    00128        if( sscanf( line, "Alternate Time: %d/%d/%d %d:%d:%d.%d code: %d",
    00129                   &stm.tm_year, &stm.tm_mon, &stm.tm_mday, &stm.tm_hour,
    00130                   &stm.tm_min, &stm.tm_sec, &hsec, &(sm->altcode) ) != 8 )
    00131                   return( -1 );
    00132        if( stm.tm_year == 0 ) {
    00133          sm->talt = 0.0;
    00134        } else {
    00135          stm.tm_year -= 1900;  /* to convert to definition of struct tm */
    00136          stm.tm_mon  -= 1;     /* to convert to definition of struct tm */
    00137          tsec  = timegm( &stm );
    00138          sm->talt = (double)tsec + 0.01*(double)hsec;
    00139        }
    00140      }
    00141
    00142    /* Sixth line = timestamp from DBMS (or other system) */
    00143      else if( nline == 6 )
    00144      {
    00145        if( strncmp(line,"DBMS Load Time:", 15) != 0 ) return( -1 );
    00146        memset( &stm, 0, sizeof(struct tm) ); /* zero the time structure */
    00147        if( sscanf( line, "DBMS Load Time: %d/%d/%d %d:%d:%d.%d",
    00148                   &stm.tm_year, &stm.tm_mon, &stm.tm_mday, &stm.tm_hour,
    00149                   &stm.tm_min, &stm.tm_sec, &hsec ) != 7 ) return( -1 );
    00150        if( stm.tm_year == 0 ) {
    00151          sm->tload = 0.0;
    00152        } else {
    00153          stm.tm_year -= 1900;  /* to convert to definition of struct tm */
    00154          stm.tm_mon  -= 1;     /* to convert to definition of struct tm */
    00155          tsec  = timegm( &stm );
    00156          sm->tload = (double)tsec + 0.01*(double)hsec;
    00157        }
    00158      }
    00159
    00160  /* Seventh line = SCNL names */
    00161      else if( nline == 7 )
    00162      {
    00163        if( strncmp(line,"SCNL:", 5) != 0 ) return( -1 );
    00164        begtok = line + 5;
    00165        for( i=0; i<sm->nch; i++ )
    00166        {
    00167          while( begtok[0] == ' ' ) begtok++;    /* go to 1st non-blank char */
    00168          if( begtok >= endline ) return( -1 );
    00169          len = tokenlength( begtok, '.' );
    00170          if( len > SM_STA_LEN ) return( -1 );
    00171          strncpy( sm->ch[i].sta, begtok, len );
    00172          begtok += len + 1;
    00173
    00174          if( begtok >= endline ) return( -1 );
    00175          len = tokenlength( begtok, '.' );
    00176          if( len > SM_COMP_LEN ) return( -1 );
    00177          strncpy( sm->ch[i].comp, begtok, len );
    00178          begtok += len + 1;
    00179
    00180          if( begtok >= endline ) return( -1 );
    00181          len = tokenlength( begtok, '.' );
    00182          if( len > SM_NET_LEN ) return( -1 );
    00183          strncpy( sm->ch[i].net, begtok, len );
    00184          begtok += len + 1;
    00185
    00186          if( begtok > endline ) return( -1 );
    00187          len = tokenlength( begtok, ' ' );
    00188          if( len > SM_LOC_LEN ) return( -1 );
    00189          strncpy( sm->ch[i].loc, begtok, len );
    00190          begtok += len + 1;
    00191        }
    00192      }
    00193
    00194   /* Eighth line = peak acceleration values */
    00195      else if( nline == 8 )
    00196      {
    00197        if( strncmp(line,"Acc:", 4) != 0 ) return( -1 );
    00198        begtok = line + 4;
    00199        for( i=0; i<sm->nch; i++ )
    00200        {
    00201          while( begtok[0] == ' ' ) begtok++;  /* go to 1st non-blank char */
    00202          if( begtok >= endline ) return( -1 );
    00203          if( sscanf( begtok, "%lf", &(sm->ch[i].acc) ) != 1 ) return( -1 );
    00204          begtok += tokenlength( begtok, ' ' ) + 1;
    00205        }
    00206      }
    00207
    00208   /* Ninth line = peak velocity values */
    00209      else if( nline == 9 )
    00210      {
    00211        if( strncmp(line,"Vel:", 4) != 0 ) return( -1 );
    00212        begtok = line + 4;
    00213        for( i=0; i<sm->nch; i++ )
    00214        {
    00215          while( begtok[0] == ' ' ) begtok++;  /* go to 1st non-blank char */
    00216          if( begtok >= endline ) return( -1 );
    00217          if( sscanf( begtok, "%lf", &(sm->ch[i].vel) ) != 1 ) return( -1 );
    00218          begtok += tokenlength( begtok, ' ' ) + 1;
    00219        }
    00220      }
    00221
    00222   /* Tenth line = peak displacement values */
    00223      else if( nline == 10 )
    00224      {
    00225        if( strncmp(line,"Disp:", 5) != 0 ) return( -1 );
    00226        begtok = line + 5;
    00227        for( i=0; i<sm->nch; i++ )
    00228        {
    00229          while( begtok[0] == ' ' ) begtok++;  /* go to 1st non-blank char */
    00230          if( begtok >= endline ) return( -1 );
    00231          if( sscanf( begtok, "%lf", &(sm->ch[i].disp) ) != 1 ) return( -1 );
    00232          begtok += tokenlength( begtok, ' ' ) + 1;
    00233        }
    00234      }
    00235
    00236   /* Eleventh line = number of points in the response spectrum */
    00237      else if( nline == 11 )
    00238      {
    00239        if( strncmp(line,"nRSA:", 5) != 0 ) return( -1 );
    00240        begtok = line + 5;
    00241        for( i=0; i<sm->nch; i++ )
    00242        {
    00243          while( begtok[0] == ' ' ) begtok++;  /* go to 1st non-blank char */
    00244          if( begtok >= endline ) return( -1 );
    00245          if( sscanf( begtok, "%d", &(sm->ch[i].nRSA) ) != 1 ) return( -1 );
    00246          begtok += tokenlength( begtok, ' ' ) + 1;
    00247          if( sm->ch[i].nRSA > SM_MAX_RSA ) return( -1 );
    00248        }
    00249      }
    00250
    00251   /* Remaining lines = response spectrum */
    00252      else if( nline > 11 )
    00253      {
    00254        double tmp1, tmp2;
    00255        if( strncmp(line,"frq/RSA:", 8) != 0 ) return( -1 );
    00256        begtok = line + 8;
    00257        for( i=0; i<sm->nch; i++ )
    00258        {
    00259          while( begtok[0] == ' ' ) begtok++;  /* go to 1st non-blank char */
    00260          if( begtok >= endline ) return( -1 );
    00261          if( sscanf( begtok, "%lf/%lf", &tmp1, &tmp2 ) != 2 ) return( -1 );
    00262          if( nfreq < sm->ch[i].nRSA )
    00263          {
    00264            sm->ch[i].freq[nfreq] = tmp1;
    00265            sm->ch[i].RSA[nfreq]  = tmp2;
    00266          }
    00267          begtok += tokenlength( begtok, '/' ) + 1; /* skip over freq field */
    00268          while( begtok[0] == ' ' ) begtok++;       /* go to 1st non-blank char */
    00269          begtok += tokenlength( begtok, ' ' ) + 1; /* skip over RSA field */
    00270        }
    00271        nfreq++;
    00272      }
    00273
    00274    } /*end while*/
    00275
    00276
    00277    return( 0 );
    00278 }
    00279
    00280 /********************************************************************
    00281  * wr_strongmotion()                                                *
    00282  * Reads a SM_DATA structure and writes an ascii TYPE_STRONGMOTION  *
    00283  * message (null terminated)                                        *
    00284  * Returns 0 on success, -1 on failure (buffer overflow)            *
    00285  ********************************************************************/
    00286 int wr_strongmotion( SM_DATA *sm, char *buf, int buflen )
    00287 {
    00288    char     tmp[256]; /* working buffer */
    00289    int      nchan;
    00290    int      nRSA;
    00291    int      i,j;
    00292
    00293    memset( buf, 0, (size_t)buflen );    /* zero output buffer */
    00294    nchan = ( sm->nch > SM_MAX_CHAN ) ? SM_MAX_CHAN : sm->nch ;
    00295
    00296 /* Print 3 header lines: vendor, serial number, nchan */
    00297    if( strlen(sm->vendor)==0 ) strcpy( sm->vendor, "unknown" ); /*KLUDGE*/
    00298    if( strlen(sm->sn)==0     ) strcpy( sm->sn,     "unknown" ); /*KLUDGE*/
    00299     sprintf( tmp, "Vendor: %s\nSerialNo: %s\nnchan: %d\nField Time:     ",
    00300             sm->vendor, sm->sn, nchan );
    00301    if( strappend( buf, buflen, tmp ) ) return( -1 );
    00302
    00303 /* field time */
    00304    datestr23( sm->tfield, tmp, 256 );
    00305    if( strappend( buf, buflen, tmp ) ) return( -1 );
    00306
    00307 /* alternate time & its code */
    00308    if( strappend( buf, buflen, "\nAlternate Time: " ) ) return ( -1 );
    00309    if( sm->talt == 0.0 )
    00310    {
    00311      if( strappend( buf, buflen, sNullDate ) ) return( -1 );
    00312    } else {
    00313      datestr23( sm->talt, tmp, 256 );
    00314      if( strappend( buf, buflen, tmp ) ) return( -1 );
    00315    }
    00316    sprintf( tmp, " code: %d", sm->altcode );
    00317    if( strappend( buf, buflen, tmp ) ) return( -1 );
    00318
    00319 /* load time */
    00320    if( strappend( buf, buflen, "\nDBMS Load Time: " ) ) return ( -1 );
    00321    if( sm->tload == 0.0 )
    00322    {
    00323      if( strappend( buf, buflen, sNullDate ) ) return( -1 );
    00324    } else {
    00325      datestr23( sm->tload, tmp, 256 );
    00326      if( strappend( buf, buflen, tmp ) ) return( -1 );
    00327    }
    00328
    00329 /* Print the SCNL names */
    00330    if( strappend( buf, buflen, "\nSCNL:    " ) ) return( -1 );
    00331    for( i=0; i<nchan; i++ )
    00332    {
    00333       sprintf( tmp, "   %s.%s.%s.%s",
    00334                sm->ch[i].sta, sm->ch[i].comp, sm->ch[i].net, sm->ch[i].loc );
    00335       if( strappend( buf, buflen, tmp ) ) return( -1 );
    00336    }
    00337
    00338 /* Print peak acceleration values */
    00339    if( strappend( buf, buflen, "\nAcc:     " ) ) return( -1 );
    00340    for( i=0; i<nchan; i++ )
    00341    {
    00342       sprintf( tmp, " %15.6lf", sm->ch[i].acc );
    00343       if( strappend( buf, buflen, tmp ) ) return( -1 );
    00344    }
    00345
    00346 /* Print peak velocity values */
    00347    if( strappend( buf, buflen, "\nVel:     " ) ) return( -1 );
    00348    for( i=0; i<nchan; i++ )
    00349    {
    00350       sprintf( tmp, " %15.6lf", sm->ch[i].vel );
    00351       if( strappend( buf, buflen, tmp ) ) return( -1 );
    00352    }
    00353
    00354 /* Print peak displacement values */
    00355    if( strappend( buf, buflen, "\nDisp:    " ) ) return( -1 );
    00356    for( i=0; i<nchan; i++ )
    00357    {
    00358       sprintf( tmp, " %15.6lf", sm->ch[i].disp );
    00359       if( strappend( buf, buflen, tmp ) ) return( -1 );
    00360    }
    00361
    00362 /* Print number of points in the response spectrum */
    00363    nRSA = 0;
    00364    if( strappend( buf, buflen, "\nnRSA:    " ) ) return( -1 );
    00365    for( i=0; i<nchan; i++ )
    00366    {
    00367       if( sm->ch[i].nRSA < SM_MAX_RSA ) sprintf( tmp, " %15d", sm->ch[i].nRSA );
    00368       else                              sprintf( tmp, " %15d", SM_MAX_RSA );
    00369       if( strappend( buf, buflen, tmp ) ) return( -1 );
    00370       if( nRSA < sm->ch[i].nRSA ) nRSA = sm->ch[i].nRSA;
    00371    }
    00372
    00373 /* Print the response spectrum (frequency/acceleration pairs) */
    00374    if( nRSA > SM_MAX_RSA ) nRSA = SM_MAX_RSA;
    00375    for( j=0; j<nRSA; j++ )
    00376    {
    00377       if( strappend( buf, buflen, "\nfrq/RSA: " ) ) return( -1 );
    00378       for( i=0; i<nchan; i++ )
    00379       {
    00380         if( j < sm->ch[i].nRSA )  /* print real values for this channel */
    00381         {
    00382           sprintf( tmp, " %6.2lf/%.6lf", sm->ch[i].freq[j], sm->ch[i].RSA[j] );
    00383         }
    00384         else                      /* print null values for this channel */
    00385         {
    00386           sprintf( tmp, " %6.2lf/%.6lf", SM_NULL, SM_NULL );
    00387         }
    00388         if( strappend( buf, buflen, tmp ) ) return( -1 );
    00389       }
    00390    }
    00391    if( strappend( buf, buflen, "\n" ) ) return( -1 );
    00392
    00393    return( 0 );
    00394 }
    00395
    00396
    00397 /********************************************************************
    00398  * log_strongmotion()                                               *
    00399  * Writes the contents of a SM_DATA structure to an Earthworm       *
    00400  * log file                                                         *
    00401  ********************************************************************/
    00402 void log_strongmotion( SM_DATA *sm )
    00403 {
    00404    char date[30];
    00405    int nRSA, i, j;
    00406
    00407    logit("", "Vendor:%s sn:%s nch:%d\n", sm->vendor, sm->sn, sm->nch );
    00408
    00409 /* Log time values */
    00410    datestr23( sm->tfield, date, 30 );
    00411    logit("", "Field Time:     %s  (%.2lf)\n", date, sm->tfield );
    00412    if( sm->talt != 0.0 ) {
    00413      datestr23( sm->talt, date, 30 );
    00414      logit("", "Alternate Time: %s  (%.2lf)  code: %d\n",
    00415            date, sm->talt, sm->altcode );
    00416    } else {
    00417      logit("", "Alternate Time: %s  (%.2lf)  code: %d\n",
    00418            sNullDate, sm->talt, sm->altcode );
    00419    }
    00420
    00421    if( sm->talt != 0.0 ) {
    00422      datestr23( sm->tload, date, 30 );
    00423      logit("", "DBMS Load Time: %s  (%.2lf)\nSCNL:", date, sm->tload );
    00424    } else {
    00425      logit("", "DBMS Load Time: %s  (%.2lf)\nSCNL:", sNullDate, sm->tload );
    00426    }
    00427
    00428 /* Log station codes */
    00429    for( i=0; i<sm->nch; i++ )
    00430    {
    00431      logit("", "   %s.%s.%s.%s",
    00432              sm->ch[i].sta, sm->ch[i].comp, sm->ch[i].net, sm->ch[i].loc );
    00433    }
    00434
    00435 /* Log peak acceleration values */
    00436    logit("", "\nAcc:     ");
    00437    for( i=0; i<sm->nch; i++ )
    00438    {
    00439       logit("", " %15.6lf", sm->ch[i].acc );
    00440    }
    00441
    00442 /* Log peak velocity values */
    00443    logit("", "\nVel:     ");
    00444    for( i=0; i<sm->nch; i++ )
    00445    {
    00446       logit("", " %15.6lf", sm->ch[i].vel );
    00447    }
    00448
    00449 /* Log peak displacement values */
    00450    logit("","\nDisp:    ");
    00451    for( i=0; i<sm->nch; i++ )
    00452    {
    00453       logit("", " %15.6lf", sm->ch[i].disp );
    00454    }
    00455
    00456 /* Log number of points in the response spectrum */
    00457    nRSA = 0;
    00458    logit("","\nnRSA:    ");
    00459    for( i=0; i<sm->nch; i++ )
    00460    {
    00461       logit("", " %15d", sm->ch[i].nRSA );
    00462       if( nRSA < sm->ch[i].nRSA ) nRSA = sm->ch[i].nRSA;
    00463    }
    00464
    00465 /* Log the response spectrum (frequency/acceleration pairs) */
    00466    for( j=0; j<nRSA; j++ )
    00467    {
    00468       logit("", "\nfrq/RSA: " );
    00469       for( i=0; i<sm->nch; i++ )
    00470       {
    00471         if( j < sm->ch[i].nRSA )  /* print real values for this channel */
    00472         {
    00473           logit("", " %6.2lf/%8.6lf", sm->ch[i].freq[j], sm->ch[i].RSA[j] );
    00474         }
    00475         else                      /* print null values for this channel */
    00476         {
    00477           logit("", " %6.2lf/%8.6lf", SM_NULL, SM_NULL );
    00478         }
    00479       }
    00480    }
    00481    logit("","\n");
    00482
    00483    return;
    00484 }
    00485
    00486 /********************************************************************
    00487  * strappend() append second null-terminated character string to    *
    00488  * the first as long as there's enough room in the target buffer    *
    00489  * for both strings an the null-byte                                *
    00490  ********************************************************************/
    00491 int strappend( char *s1, int s1max, char *s2 )
    00492 {
    00493    if( (int)strlen(s1)+(int)strlen(s2)+1 > s1max ) return( -1 );
    00494    strcat( s1, s2 );
    00495    return( 0 );
    00496 }
    00497
    00498 /********************************************************************
    00499  * tokenlength() given a null-terminated character string and a     *
    00500  * character that delimits the end of a token, tokenlength returns  *
    00501  * the length (in bytes) of the next token. If the character wasn't *
    00502  * found, tokenlength returns the length of the string.             *
    00503  ********************************************************************/
    00504 int tokenlength( char *begtok, char c )
    00505 {
    00506    char    *endtok;   /* points to the end of this token */
    00507
    00508    endtok = strchr( begtok, c );
    00509    if( endtok == NULL ) return( (int)strlen(begtok) );
    00510    return( (int)(endtok-begtok) );
    00511 }