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 2161 2006-05-19 16:55:03Z paulf $
00007  *
00008  *    Revision history:
00009  *     $Log$
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 }

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