int anza_par( uchar_t *packet,
          double pkttime,
          char *srcname,
	  struct Packet **Pkt
	  )

{

    struct PreHdr *hdr;
    struct PktChannel *achan;
    char net[64], sta[8];
    int i, off, ch;
    short sval; 
    int val;
    long lval;

    hdr = ( struct PreHdr *) packet;
    
    (*Pkt)->pkttype = ntohl (hdr->pkttype);
    (*Pkt)->hdrtype = ntohl (hdr->hdrtype);


    parse_srcname( srcname, &net[0], &sta[0], 0, 0 );

    for( i = 0, ch = 0; i < ANZA_DAS; i++, ch++ )  {

        achan = (PktChannel *) gettbl((*Pkt)->chan, ch) ;
        if ( achan == 0 ) {
              allot ( PktChannel *, achan, 1 ) ;
              achan->data = (void *) malloc( sizeof(int)  );
        }
        strcpy( achan->chan, ANZA_DAS_NAME[i] ) ;
        strcpy( achan->net, net);
        strcpy( achan->sta, sta);
        achan->samprate = 1.0/DINTV;                                
        achan->calib = 0;                     
        achan->datatype = trINT;
        achan->nsamp = 1;                   
        achan->nbytes = sizeof(int);
        achan->time = pkttime;   

        off = hdr->hdrsiz + ANZA_DAS_OFF[i];
        if( strncmp(ANZA_DAS_NAME[i], "BUFDEL", strlen("BUFDEL")) == 0 )  
	    val = packet[off];
	else  {
	    memcpy( (char *) &sval, (char *) &packet[off], 2 );
	    val = sval ;
	   /*
	    fprintf( stderr, "%lf %s_%s %d\n", achan->time, achan->sta, achan->chan, val ); 
	    if( val < 1100  )   hexdump( stderr, packet + hdr->hdrsiz, 62 ); 
	    fflush(stderr);
	    */
	}
        memcpy(achan->data, (char *) &val, sizeof(int) );

        settbl((*Pkt)->chan, ch, achan ) ;
     } 
void InitPkt()
{
    Pkt = newPkt ();
    Pkt->pkttype = suffix2pkttype ("GENC");

    PktChan = newPktChannel ();
    Pkt->nchannels=1;
    settbl(Pkt->channels, 0, PktChan);
}
/* Recursively removes pf instances from the pf object and returns the
 * objects' contents in an entirely new structure so that no memory is reused.
 * Requires the caller have some knowledge about the structure of the data. */
void *
pf_collapse( Pf * pf )
{
    Arr * currarr;
    Tbl * currtbl;
    char * key;
    void * value;
    int i;
    int size;
    
    if ( pf == NULL ) return NULL;
    switch( pf->type )
    {
        case PFARR:     currtbl = keysarr( pf->value.arr );
                        size = maxtbl( currtbl );
                        /* currarr = newarr( pf->value.arr->rb_comp ); */
                        currarr = newarr( strcmp );
                        for ( i = 0; i < size; i++ )
                        {
                            key = poptbl( currtbl );
                            value = pf_collapse( getarr( pf->value.arr, key ) );
                            setarr( currarr, key, value );
                        }
                        freetbl( currtbl, 0 );
                        return currarr;

        case PFTBL:     size = maxtbl( pf->value.tbl );
                        currtbl = newtbl( size );
                        for ( i = 0; i < size; i++ )
                            settbl( currtbl, i,
                                    pf_collapse( gettbl( pf->value.tbl, i ) ) );
                        return currtbl;

        default:        return strdup( pf->value.s );
    }
}
int grdb_sc_loadcss (Dbptr dbin, char *net_expr, char *sta_expr,
        char *chan_expr, double tstart, double tend, 
        int coords, int ir, int orient, Dbptr *dbscgr, Dbptr *dbsc)
{
	Dbptr dbout, db, dbout2;
	char string[1024];
	char string2[1024];
	char sta_wfdisc[32], chan_wfdisc[32];
	int i, j, n, sensor=0, ok;
	Tbl *pat1, *pat2;
	Tbl *sortfields, *groupfields;
	FILE *file;
	Response *resp;
	int is_view=0;
	Dbptr db_to_clear;

	/* Subset the wfdisc by station-channel-time sifters. */

	dbout = dblookup (dbin, 0, "wfdisc", 0, 0);
	strcpy (string, "");
	if (sta_expr) {
		strcpy (string, "( ");
        	sprintf (string2, "sta =~ /%s/", sta_expr);
        	strcat (string, string2);
	}
	if (chan_expr) {
		if (string[0]) strcat (string, " && ");
		else strcpy (string, "( ");
        	sprintf (string2, "chan =~ /%s/", chan_expr);
        	strcat (string, string2);
	}
	if (tstart != 0.0 || tend != 0.0) {
		if (string[0]) strcat (string, " && ");
		else strcpy (string, "( ");
        	sprintf (string2, "(time < %.5f && endtime > %.5f)", tend, tstart);
        	strcat (string, string2);
	}
	if (string[0]) {
		strcat (string, " )");
		dbout = dbsubset (dbout, string, 0);
		is_view=1;
	}
        dbquery (dbout, dbRECORD_COUNT, &n);
        if (n < 1) {
		register_error (0, "grdb_sc_loadcss: No wfdisc rows to process.\n");
		return (-1);
        }

        /* Make the necessary joins and check for completeness. */

        if (coords) {
        	db = dblookup (dbin, 0, "site", 0, 0);
		if(is_view)db_to_clear=dbout;
        	dbout = dbjoin (dbout, db, 0, 0, 1, 0, 0);
		if(is_view) dbfree(db_to_clear);
		is_view=1;
		
        	dbquery (dbout, dbRECORD_COUNT, &n);
        	if (n < 1) {
			register_error (0, "grdb_sc_loadcss: No data rows to process.\n");
			return (-1);
        	}
        	for (dbout.record=0; dbout.record<n; dbout.record++) {
        		if (dbgetv (dbout, 0, "wfdisc.sta", sta_wfdisc,
        				"wfdisc.chan", chan_wfdisc,
        				"site.sta", string, 0) == dbINVALID) {
			    register_error (0, "grdb_sc_loadcss: dbgetv() error while checking site.\n");
			    return (-1);
			}
        		if (coords > 1 && strcmp(string, sta_wfdisc)) {
        			register_error (0, "grdb_sc_loadcss: Cannot find site parameters for %s %s.\n", 
        									sta_wfdisc, chan_wfdisc);
        			return (-1);
        		}
        	}
        }
        if (ir) {
        	db = dblookup (dbin, 0, "sensor", 0, 0);
		if(is_view)db_to_clear=dbout;
        	dbout = dbjoin (dbout, db, 0, 0, 1, 0, 0);
		if(is_view) dbfree(db_to_clear);
		is_view=1;
        	dbquery (dbout, dbRECORD_COUNT, &n);
        	if (n < 1) {
			register_error (0, "grdb_sc_loadcss: No data rows to process.\n");
			return (-1);
        	}
        	for (dbout.record=0; dbout.record<n; dbout.record++) {
        		if (dbgetv (dbout, 0, "wfdisc.sta", sta_wfdisc,
        				"wfdisc.chan", chan_wfdisc,
        				"sensor.sta", string, 0) == dbINVALID) {
			    register_error (0, "grdb_sc_loadcss: dbgetv() error while checking sensor.\n");
			    return (-1);
			}
        		if (ir > 1 && strcmp(string, sta_wfdisc)) {
        			register_error (0, "grdb_sc_loadcss: Cannot find sensor parameters for %s %s.\n", 
        									sta_wfdisc, chan_wfdisc);
        			return (-1);
        		}
        	}
        	sensor = 1;
		if(is_view)db_to_clear=dbout;
        	db = dblookup (dbin, 0, "instrument", 0, 0);
        	dbout = dbjoin (dbout, db, 0, 0, 1, 0, 0);
		if(is_view) dbfree(db_to_clear);
		is_view=1;
        	dbquery (dbout, dbRECORD_COUNT, &n);
        	if (n < 1) {
			register_error (0, "grdb_sc_loadcss: No data rows to process.\n");
			return (-1);
        	}
        	for (dbout.record=0; dbout.record<n; dbout.record++) {
        		if (dbgetv (dbout, 0, "wfdisc.sta", sta_wfdisc,
        				"wfdisc.chan", chan_wfdisc,
        				"sensor.inid", &j,
        				"instrument.insname", string2,
        				"instrument.inid", &i, 0) == dbINVALID) {
			    register_error (0, "grdb_sc_loadcss: dbgetv() error while checking instrument.\n");
			    return (-1);
			}
        		if (ir > 1 && (i != j)) {
        			register_error (0, "grdb_sc_loadcss: Cannot find instrument parameters for %s %s.\n", 
        									sta_wfdisc, chan_wfdisc);
        			return (-1);
        		}
        		if (i >= 0) {
				if (resp_arr == NULL) {
					resp_arr = newarr (0);
					if (resp_arr == NULL) {
        					register_error (0, "grdb_sc_loadcss: newarr() error.\n");
        					return (-1);
					}
				}
				dbextfile (dbout, "instrument", string);
				resp = (Response *) getarr (resp_arr, string);
				if (resp == NULL) {
					file = fopen (string, "r");
					if (file == NULL) {
						if (ir > 1) {
        						register_error (1, "grdb_sc_loadcss: fopen('%s') error.\n", string);
        						return (-1);
						}
					} else {
						if (read_response (file, &resp)) {
        						register_error (0, "grdb_sc_loadcss: read_response('%s') error.\n", string);
        						return (-1);
						}
						fclose (file);
						resp->insname = strdup(string2);
					}
					setarr (resp_arr, string, resp);
				}
			}
        	}
        }
        if (orient) {
        	ok = 1;
		if(is_view)db_to_clear=dbout;
        	db = dblookup (dbin, 0, "sitechan", 0, 0);
        	dbout2 = dbjoin (dbout, db, 0, 0, 1, 0, 0);
		is_view=1;
        	dbquery (dbout2, dbRECORD_COUNT, &n);
        	if (n < 1) {
        		ok = 0;
        	} else {
        		for (dbout2.record=0; dbout2.record<n; dbout2.record++) {
        			dbgetv (dbout2, 0, "wfdisc.sta", sta_wfdisc,
        				"wfdisc.chan", chan_wfdisc,
        				"sitechan.sta", string, 0);
        			if (strcmp(string, sta_wfdisc)) {
        				ok = 0;
        				break;
        			}
        		}
		}
		if (ok) {
			dbout = dbout2;
			if(is_view) dbfree(db_to_clear);
		} else {
			if (!sensor) {
        			db = dblookup (dbin, 0, "sensor", 0, 0);
				if(is_view)db_to_clear=dbout;
	       			dbout = dbjoin (dbout, db, 0, 0, 1, 0, 0);
				if(is_view) 
				{
					dbfree(dbout2);
					dbfree(db_to_clear);
				}
				is_view=1;
        			dbquery (dbout, dbRECORD_COUNT, &n);
        			if (n < 1) {
					register_error (0, "grdb_sc_loadcss: No data rows to process.\n");
					return (-1);
        			}
        			for (dbout.record=0; dbout.record<n; dbout.record++) {
        				if (dbgetv (dbout, 0, "wfdisc.sta", sta_wfdisc,
        						"wfdisc.chan", chan_wfdisc,
        						"sensor.sta", string, 0) == dbINVALID) {
			    			register_error (0, "grdb_sc_loadcss: dbgetv() error while checking sensor.\n");
			    			return (-1);
					}
        				if (orient > 1 && strcmp(string, sta_wfdisc)) {
        					register_error (0, "grdb_sc_loadcss: Cannot find sensor parameters for %s %s.\n", 
        											sta_wfdisc, chan_wfdisc);
        					return (-1);
        				}
        			}
			}
        		db = dblookup (dbin, 0, "sitechan", 0, 0);
        		pat1 = newtbl(1);
        		if (pat1 == NULL) {
        			register_error (0, "grdb_sc_loadcss: newtbl() error.\n");
        			return (-1);
        		}
        		pat2 = newtbl(1);
        		if (pat2 == NULL) {
        			register_error (0, "grdb_sc_loadcss: newtbl() error.\n");
        			return (-1);
        		}
			if(is_view)db_to_clear=dbout;
        		settbl (pat1, 0, strdup("sensor.chanid"));
        		settbl (pat2, 0, strdup("sitechan.chanid"));
        		dbout = dbjoin (dbout, db, &pat1, &pat2, 1, 0, 0);
			if(is_view) dbfree(db_to_clear);
			is_view=1;
        		freetbl (pat1, free);
        		freetbl (pat2, free);
        		dbquery (dbout, dbRECORD_COUNT, &n);
        		if (n < 1) {
				register_error (0, "grdb_sc_loadcss: No data rows to process.\n");
				return (-1);
        		} else {
        			for (dbout.record=0; dbout.record<n; dbout.record++) {
        				if (dbgetv (dbout, 0, "wfdisc.sta", sta_wfdisc,
        					"wfdisc.chan", chan_wfdisc,
        					"sitechan.sta", string, 0) == dbINVALID) {
			    		   register_error (0, "grdb_sc_loadcss: dbgetv() error while checking sitechan.\n");
			    		   return (-1);
					}
        				if (orient > 1 && strcmp(string, sta_wfdisc)) {
        					register_error (0, "grdb_sc_loadcss: Cannot find sitechan parameters for %s %s.\n", 
        											sta_wfdisc, chan_wfdisc);
        					return (-1);
        				}
        			}
			}
		}
        }

        /* Sort and group the output view. */

	if(is_view)db_to_clear=dbout;
	sortfields = newtbl (3);
	if (sortfields == NULL) {
		register_error (0, "grdb_sc_loadcss: newtbl() error.\n");
		return (-1);
	}
	settbl (sortfields, 0, strdup("wfdisc.sta"));
	settbl (sortfields, 1, strdup("wfdisc.chan"));
	settbl (sortfields, 2, strdup("wfdisc.time"));
        *dbsc = dbsort (dbout, sortfields, 0, 0);
	if(is_view) dbfree(db_to_clear);
	groupfields = newtbl (2);
	if (groupfields == NULL) {
		register_error (0, "grdb_sc_loadcss: newtbl() error.\n");
		return (-1);
	}
	settbl (groupfields, 0, strdup("sta"));
	settbl (groupfields, 1, strdup("chan"));
	*dbscgr = dbgroup (*dbsc, groupfields, 0, 1);
	freetbl (sortfields, free);
	freetbl (groupfields, free);

	/* Normal exit */

	return (0);
}
int unstuff_BBAHdr(
    uchar_t *packet, 
    Packet **Pkt,
    void *par )
{

    int i, ch=0;
    struct DataPar *dhdr;
    BBAHdr bbahdr;
    PktChannel *achan;
    float calib;
    float samprate;
    short  chlen, nsamp, nchan, doff; 
    short hdrsize, pktsize;
    ushort_t hdrtype, pkttype;
    short datatype;
    char  *name, chnames[64];
    uchar_t *hdr, hdrbuf[512];

    dhdr = ( struct DataPar *) par;

    memcpy( &hdrbuf[0], packet, 512);
    hdr = &hdrbuf[0];

    memcpy( &hdrsize, hdr, sizeof(short ));
    hdr += sizeof(short );
    hdrsize =  ntohs(  hdrsize );
    bbahdr.prehdr.hdrsiz = hdrsize;
    memcpy( &pktsize, hdr, sizeof( short ));
    hdr += sizeof( short );
    pktsize =   ntohs(  pktsize );
    bbahdr.prehdr.pktsiz = pktsize;
    memcpy( &hdrtype, hdr, sizeof(short));
    hdr += sizeof(short);
    hdrtype =  (ushort_t) ntohs( hdrtype );
    bbahdr.prehdr.hdrtype = hdrtype;
    memcpy( &pkttype, hdr, sizeof(short));
    hdr += sizeof(short);
    pkttype =  (ushort_t)ntohs( pkttype );
    bbahdr.prehdr.pkttype = pkttype;
    
    memcpy( &calib, hdr, sizeof(float));
    hdr += sizeof(float);
    ntohfp( &calib, &calib );
    bbahdr.calib = calib;
    memcpy( &samprate, hdr, sizeof(float));
    hdr += sizeof(float);
    ntohfp( &samprate, &samprate );
    bbahdr.samprate = samprate;
    
    memcpy( &datatype, hdr, sizeof(short));
    hdr += sizeof(short);
    datatype = ntohs( datatype );
    bbahdr.datatype = datatype;
    memcpy( &nsamp, hdr, sizeof(short));
    hdr += sizeof(short);
    nsamp =  ntohs( nsamp );
    bbahdr.nsamp = nsamp;
    memcpy( &nchan, hdr, sizeof(short));
    hdr += sizeof(short);
    nchan =  ntohs( nchan );
    bbahdr.nchan = nchan;
    memcpy( &doff, hdr, sizeof(short));
    hdr += sizeof(short);
    doff =  ntohs( doff );
    bbahdr.doff = doff;
    memcpy( &chlen, hdr, sizeof(short));
    hdr += sizeof(short);
    chlen = ntohs( chlen );
    bbahdr.chanlen = chlen;
    memcpy( (char *) &bbahdr.channels[0], hdr, chlen );
    bbahdr.channels[chlen] = '\0';
    strcpy( chnames,&bbahdr.channels );

    dhdr->pktsize = (int) bbahdr.prehdr.pktsiz;
    dhdr->datatype = (int) bbahdr.datatype;
    dhdr->doff = (int) bbahdr.doff;
    dhdr->nsamp = (int) bbahdr.nsamp;

    if( *Pkt == 0 ) *Pkt = newpkt();
    
    (*Pkt)->pkttype = (int) bbahdr.prehdr.pkttype;
    (*Pkt)->hdrtype = (int) bbahdr.prehdr.hdrtype;
    (*Pkt)->nchannels = (int) bbahdr.nchan;
   
    name = strtok( bbahdr.channels, "_" ) ;
    
    while ( name != 0 ) {
      if( ch > nchan )  {
        complain( 0,"There are more chan names ( %s ) than channels (%d)\n", chnames, nchan );
	return 0;
      }
      achan = (PktChannel *) gettbl((*Pkt)->chan, ch) ;
      if ( achan == 0 ) {
          allot ( PktChannel *, achan, 1 ) ;
          achan->data = NULL;
          strcpy (achan->segtype, "V");
      }
      strcpy( achan->chan, name ) ;
      achan->samprate = (double) bbahdr.samprate;
      achan->calib = (double) bbahdr.calib; 
      achan->nsamp = (int) bbahdr.nsamp;
      settbl((*Pkt)->chan, ch, (char *) achan ) ;
      name = strtok(0, "_" ) ;
      ch++ ;
   }  
int pfput_mxArray( Pf *pf, char *name, const mxArray *array )
{
	Pf	*sub_pf;
	double	number;
	char	*string;
	mxArray *in[2], *out[1];
	char	warning[STRSZ];
	char	*fieldname;
	mxArray	*mxfield;
	mxArray	*mxcell;
	int	M,N;
	int	rc;
	int	i;

	if( mxIsClass( array, "dbpf" ) )
	{
		if( ! get_pf( array, &sub_pf ) )
		{
			return PFINVALID;
		}

		if( sub_pf->type == PFFILE) 
		{
			/* Don't embed a PFFILE in something else */
			sub_pf->type = PFARR;
		}

    		switch (pf->type) {
        	case PFFILE:
        	case PFARR:
            		setarr ( pf->value.arr, name, sub_pf ) ;
            		break ;

        	case PFTBL:
            		settbl ( pf->value.tbl, (int) name, sub_pf ) ;
            		break ;
	
        	default :
			return PFINVALID;
        	}
		antelope_mex_clear_register( 1 );
	}
	else if( mxIsDouble( array ) )
	{
		if( ! get_scalar( array, &number ) )
		{
			return PFINVALID;
		}
	
		in[0] = (mxArray *) array; /* Input scalar */
		mexCallMATLAB( 1, out, 1, in, "floor" );
		in[1] = out[0];  /* floor( Input scalar ) */
		mexCallMATLAB( 1, out, 2, in, "eq" );
		mxDestroyArray( in[1] );
	
		if( mxIsLogicalScalarTrue( out[0] ) ) 
		{
			pfput_int( pf, name, (int) number );
		} 
		else 
		{
			pfput_double( pf, name, number );
		}
		antelope_mex_clear_register( 1 );

		mxDestroyArray( out[0] );
	}
	else if( mxIsChar( array ) )
	{
		if( ! mtlb_get_string( array, &string ) )
		{
			sprintf( warning, 
			  "failed to extract string for parameter %s\n",
			  name );
			mexWarnMsgTxt( warning );
			return PFINVALID;
		}

		pfput_string( pf, name, string );

		antelope_mex_clear_register( 1 );

		mxFree( string );
	}
	else if( mxIsStruct( array ) )
	{
		if( mxGetNumberOfDimensions( array ) > 2 ) 
		{
			sprintf( warning,
			  "structure has too many dimensions for parameter %s\n",
			  name );
			mexWarnMsgTxt( warning );
			return PFINVALID;
		}
		else if( mxGetM( array ) != 1 || mxGetN( array ) != 1 )
		{
			sprintf( warning,
			  "structure has too many elements for parameter %s\n",
			  name );
			mexWarnMsgTxt( warning );
			return PFINVALID;
		}
		N = mxGetNumberOfFields( array );

		sub_pf = pfnew( PFARR );

		for( i = 0; i < N; i++ ) 
		{
			fieldname = (char *) mxGetFieldNameByNumber( array, i );
			mxfield = mxGetFieldByNumber( array, 0, i );
			rc = pfput_mxArray( sub_pf, fieldname, mxfield );

			if( rc == PFINVALID )
			{
				pffree( sub_pf );
				return PFINVALID;
			}
		}

    		switch (pf->type) {
        	case PFFILE:
        	case PFARR:
            		setarr ( pf->value.arr, name, sub_pf ) ;
            		break ;

        	case PFTBL:
            		settbl ( pf->value.tbl, (int) name, sub_pf ) ;
            		break ;
	
        	default :
            		pffree( sub_pf );
			return PFINVALID;
        	}
		antelope_mex_clear_register( 1 );
	}
	else if( mxIsCell( array ) )
	{
                if( mxGetNumberOfDimensions( array ) > 2 )
                {
                        sprintf( warning,
                          "cell array has too many dimensions for parameter %s\n",
                          name );
                        mexWarnMsgTxt( warning );
                        return PFINVALID;
                }
                M = mxGetM( array );
                N = mxGetN( array );

		sub_pf = pfnew( PFTBL );
		for( i = 0; i < M * N; i++ ) 
		{
			mxcell = mxGetCell( array, i );
			rc = pfput_mxArray( sub_pf, (char *) i, mxcell );

			if( rc == PFINVALID )
			{
				pffree( sub_pf );
				return PFINVALID;
			}
		} 
    		switch (pf->type) {
        	case PFFILE:
        	case PFARR:
            		setarr ( pf->value.arr, name, sub_pf ) ;
            		break ;

        	case PFTBL:
            		settbl ( pf->value.tbl, (int) name, sub_pf ) ;
            		break ;
	
        	default :
            		pffree( sub_pf );
			return PFINVALID;
        	}
		antelope_mex_clear_register( 1 );
	}
	else 
	{
		return PFINVALID;
	}
	
	return 0;
}
static int
autodrm_response (Dbptr db)
{

    Dbptr           dbstage;
    static Hook    *hook = 0;
    char            sta[MAX_STA_SIZE],
                    chan[MAX_CHAN_SIZE];
    double          time,
                    endtime;
    long            stageid;
    char           *s;
    Response       *response;
    Response_group *group;
    char            iunits[96],
                    ounits[96];
    char            gtype[100];
    long            i,
                    j;
    Paz            *paz;
    Fir            *fir;
    Fap            *fap;
    Fap2           *fap2;
    FILE           *file;
    double          samprate,
                    gnom,
                    gcalib;
    double          calper=0.0;
    long            decifac;
    char            dir[100],
                    dfile[100];
    char            filename[STRSZ];
    long            nmatches;
    int             errors = 0;
    Tbl            *tbl,
                   *stbl;
    double          mintime=0,
                    maxtime=0;
    char            segtype;
    static Tbl     *keys1 = 0,
                   *keys2 = 0;

    if (keys1 == 0) {
	keys1 = strtbl ("sta", "chan", "time", NULL);
	keys2 = strtbl ("sta", "chan", "time::endtime", NULL);
    }
    dbstage = dblookup (db, 0, "stage", 0, 0);
    nmatches = dbmatches (db, dbstage, &keys1, &keys2, &hook, &tbl);

    switch (nmatches) {
      case dbINVALID:
      case 0:
	dbgetv (db, 0, "sta", sta, "chan", chan, "time", &time, NULL);
	complain (0, "Can't match record for %s:%s @ %s in stage table",
		  sta, chan, s = strydtime (time));
	free (s);
	errors++;
	break;

      default:
	stbl = newtbl (maxtbl (tbl));
	for (i = 0; i < nmatches; i++) {
	    dbstage.record = (long) gettbl (tbl, i);
	    dbgetv (dbstage, 0,
		    "stageid", &stageid,
		    "time", &time,
		    "endtime", &endtime,
		    NULL);
	    if (i == 0) {
		mintime = time;
		maxtime = endtime;
	    } else {
		mintime = MAX (time, mintime);
		maxtime = MIN (endtime, maxtime);
	    }
	    settbl (stbl, stageid - 1, (char *) i);
	}
	if (maxtbl (tbl) != maxtbl (stbl)) {
	    dbgetv (db, 0, "sta", sta, "chan", chan, "time", &time, NULL);
	    complain (0, "stageid numbers for %s:%s @ %s don't add up.",
		      sta, chan, s = strydtime (time));
	    free (s);
	    errors++;
	} else {
	    errors += write_cal2 (db, mintime, maxtime, &calper);

	    for (i = 0; i < nmatches; i++) {
		j = (long) gettbl (stbl, i);
		dbstage.record = (long) gettbl (tbl, j);
		dbgetv (dbstage, 0,
			"sta", sta,
			"chan", chan,
			"time", &time,
			"endtime", &endtime,
			"stageid", &stageid,
			"decifac", &decifac,
			"samprate", &samprate,
			"gnom", &gnom,
			"gcalib", &gcalib,
			"dir", dir,
			"dfile", dfile,
			"gtype", gtype,
			"iunits", iunits,
			"ounits", ounits,
			NULL);

		if (gcalib > 0.0) {
		    gnom *= gcalib;
		} else if (gcalib < 0.0) {
		    complain (0, "gcalib = %10.3f < 0. is invalid for %s:%s @ %s.\n",
			      gcalib, sta, chan, s = strydtime (time));
		    free (s);
		    errors++;
		}
		if (*dir != '-' || *dfile != '-') {
		    long            mark;
		    dbextfile (dbstage, "stage", filename);
		    mark = elog_mark ();
		    elog_log (0, "response file is '%s'", filename);
		    if ((file = fopen (filename, "r")) == 0
			    || read_response (file, &response) < 0) {
			register_error (0,
			      "Can't read response file %s  for %s_%s @ %s",
				 filename, sta, chan, s = strydtime (time));
			free (s);
			fclose (file);
			errors++;
		    } else {
			fclose (file);
			if (response->ngroups > 1) {
			    register_error (0,
			      "stage response file %s has %d stages, not 1",
					    filename, response->ngroups);
			    errors++;
			} else {

			    group = response->groups;

			    switch (group->id) {

			      case PAZ:
				/* The normalization frequency chosen in the
				 * response file may not necessarily be the
				 * same as the one chosen by calibration
				 * table for insertion into the seed volumes.
				 * Consequently, we have to adjust the
				 * specified gnom to be correct for the seed
				 * normalization frequency.  Since the gain
				 * is
				 * 
				 * G(f) = gnom_db * A_response_file * P(f) =
				 * gnom_seed * A_seed * P(f)
				 * 
				 * We have
				 * 
				 * gnom_seed = gnom_db * A_response_file /
				 * A_seed
				 * 
				 * gnom_db is just the gnom from the stage
				 * table. A_response_file is the
				 * normalization from the response file, left
				 * in the stage structure. Below, we
				 * calculate A_seed by setting
				 * A_response_file to 1.0.
				 * 
				 */

				paz = (Paz *) group->pvt;
				for (j = 0; j < strlen (iunits); j++) {
				    iunits[j] = tolower (iunits[j]);
				}
				s = getarr (Segtype, iunits);
				if (s == 0) {
				    segtype = 'D';
				} else {
				    segtype = *s;
				}
				adwrite_paz (stageid, 0, gnom, segtype, ounits, paz);
				break;

			      case IIR:
				paz = (Paz *) group->pvt;
				for (j = 0; j < strlen (iunits); j++) {
				    iunits[j] = tolower (iunits[j]);
				}
				s = getarr (Segtype, iunits);
				if (s == 0) {
				    segtype = 'D';
				} else {
				    segtype = *s;
				}
				adwrite_paz (stageid, 1, gnom, segtype, ounits, paz);
				break;

			      case FIR:
				fir = (Fir *) group->pvt;
				errors += adwrite_fir (stageid, gnom, fir);
				break;

			      case FAP:
				fap = (Fap *) group->pvt;
				errors += adwrite_fap (stageid, ounits, fap);
				break;

			      case FAP2:
				fap2 = (Fap2 *) group->pvt;
				errors += adwrite_fap2 (stageid, ounits, fap2);
				break;


			      default:
				complain (0, "Unknown filter type %d in response file %s\n",
					  group->id, filename);
				errors++;
				break;

			    }
			}
		    }
		    elog_flush (mark, 0);
		} else {
		    char           *desc = "";

		    if (gcalib > 0.0) {
			gnom *= gcalib;
		    } else if (gcalib < 0.0) {
			complain (0, "gcalib = %10.3f < 0. is an invalid value.\n", gcalib);
			errors++;
		    }
		    if (strcmp (gtype, "digitizer") == 0
		    /* following hack for psd2db */
			    || strcmp (gtype, "sensor") == 0) {
			fprintf (stdout, "DIG2 %2ld %15.8e %11.5f %s\n",
				 stageid, gnom, samprate, desc);
		    } else if (strcmp (gtype, "amplifier") == 0) {
			/* no corners */
			fprintf (stdout, "GEN2 %2ld %c %15.8e %7.3f                 0 %s\n",
				 stageid, *ounits, gnom, calper, desc);
		    } else {
			complain (0, "Unrecognized gtype='%s' for %s:%s @ %s",
				  gtype, sta, chan, s = strydtime (time));
			free (s);
			errors++;
		    }
		}
	    }
	}
	freetbl (stbl, 0);
	break;

    }
    freetbl (tbl, 0);
    return errors;
}
Exemple #8
0
int
buf_intake( ImportThread *it ) 
{
	unsigned short received_checksum;
	unsigned short recomputed_checksum;
	unsigned char *cp;
	RYO2orbPacket *r2opkt;
	int	isat;
	SatelliteInfo *si;

	cp = it->buf + it->nbytes - 2;
	uvs2hs( &cp, &received_checksum, 1 );

	recomputed_checksum = RYOChecksum( it->buf, it->nbytes-2 );

	if( recomputed_checksum != received_checksum ) {
		
		elog_complain( 0, "Checksum mismatch! Skipping packet\n" );

		return -1;
	}

	r2opkt = new_RYO2orbPacket();

	cp = it->buf + 4;
	r2opkt->message_type = (int) *cp;
	cp++;

	if( r2opkt->message_type != 1 ) {

		elog_complain( 0, "Only messagees of type 1 (Message ID 0x01) "
			     "are currently supported by ryo2orb. " 
			     "Skipping packet\n" );

		free_RYO2orbPacket( r2opkt );

		return -1;
	}

	vs2hi( &cp, &r2opkt->GPS_week, 1 );

	vi2hi( &cp, &r2opkt->GPS_millisecond, 1 );

	r2opkt->time = GPS_epoch + r2opkt->GPS_week * 7 * 24 * 3600 + 
		       r2opkt->GPS_millisecond / 1000 - GPS_leapseconds;

	r2opkt->site_index = (int) *cp;
	cp++;

	r2opkt->site_count = (int) *cp;
	cp++;

	strncpy( r2opkt->site_id, (char *) cp, 6 );
	cp += 6;
	r2opkt->site_id[6] = '\0';

	vd2hd( &cp, &r2opkt->XYZT[0], 4 );

	r2opkt->position_byte = (int) *cp;
	cp++;

	switch( r2opkt->position_byte & 3 ) {
	case 0:
		r2opkt->position_signal = RYO_SIGNAL_UNDETERMINED;
		break;
	case 1:
		r2opkt->position_signal = RYO_SIGNAL_L1;
		break;
	case 2:
		r2opkt->position_signal = RYO_SIGNAL_L1L2;
		break;
	default:
		elog_complain( 0, "L1/L2 bits in position-quality field "
			     "not understood!\n" );
		break;
	}
	
	switch( ( r2opkt->position_byte >> 2 ) & 7 ) {
	case 1:
		r2opkt->position_method = RYO_METHOD_UNDETERMINED;
		break;
	case 2:
		r2opkt->position_method = RYO_METHOD_ABSCODE;
		break;
	case 3:
		r2opkt->position_method = RYO_METHOD_RELCODE;
		break;
	case 4:
		r2opkt->position_method = RYO_METHOD_PHASEPLUSCODE;
		break;
	default:
		elog_complain( 0, "calculation-method bits in position-quality "
			     "field not understood!\n" );
		break;
	}

	r2opkt->flags_byte = (int) *cp;
	cp++;

	if( r2opkt->flags_byte & 1 ) {
		r2opkt->xyz_cov_present = 1;
	}

	if( r2opkt->flags_byte & 2 ) {
		r2opkt->tropo_cov_present = 1;
	}

	if( r2opkt->flags_byte & 4 ) {
		r2opkt->sat_info_present = 1;
	}

	if( r2opkt->xyz_cov_present ) {

		vd2hd( &cp, &r2opkt->variance_scale, 1 );
		vd2hd( &cp, &r2opkt->variance_X, 1 );
		vd2hd( &cp, &r2opkt->variance_Y, 1 );
		vd2hd( &cp, &r2opkt->variance_Z, 1 );
		vd2hd( &cp, &r2opkt->covariance_YX, 1 );
		vd2hd( &cp, &r2opkt->covariance_YZ, 1 );
		vd2hd( &cp, &r2opkt->covariance_ZX, 1 );
	}

	if( r2opkt->tropo_cov_present ) {

		vd2hd( &cp, &r2opkt->variance_T, 1 );
		vd2hd( &cp, &r2opkt->covariance_TX, 1 );
		vd2hd( &cp, &r2opkt->covariance_TY, 1 );
		vd2hd( &cp, &r2opkt->covariance_TZ, 1 );
	}

	if( r2opkt->sat_info_present ) {

		r2opkt->satellite_count = (int) *cp;
		cp++;

		vd2hd( &cp, &r2opkt->pdop, 1 );

		for( isat = 0; isat < r2opkt->satellite_count; isat++ ) {

			si = new_SatelliteInfo();

			si->sv_prn = (int) *cp;
			cp++;

			si->prn_flags = (int) *cp;
			cp++;

			if( si->prn_flags & 1 ) {
				si->ephemeris_available = 1;
			}

			if( si->prn_flags & 2 ) {
				si->L1_track = 1;
			}

			if( si->prn_flags & 4 ) {
				si->L2_track = 1;
			}

			vs2hi( &cp, &si->elevation, 1 );
			vs2hi( &cp, &si->azimuth, 1 );

			settbl( r2opkt->satellites, isat, si );
		}
	}

	if( VeryVerbose ) {
		elog_notify( 0, "...appending healthy RYO packet to queue\n" );
	}

	pmtfifo_push( RYO2orbPackets_mtf, (void *) r2opkt );

	return 0;
}