Exemple #1
1
int
main (int argc, char **argv)
{

    int             c,
                    errflg = 0;

    char           *in,
                   *out;
    int             orbin,
                    orbout;
    double          maxpkts = VERY_LARGE_NUMBER ;
    int             quit;
    char           *pktmatch = strdup(".*/pf/evtinfo"),
                   *reject = 0;
    int             nmatch;
    int             specified_after = 0;
    double          after = 0.0,
                    until = VERY_LARGE_NUMBER ;
    double          start_time,
                    end_time,
                    delta_t ;
    double          totpkts = 0,
                    totbytes = 0;
    Flags           flags;
    static int      last_pktid = -1;
    static double   last_pkttime = 0.0;
    char           *statefile = 0;
    double          last_burial = 0.0;
    double          decent_interval = 300.0;
    int             mode = PKT_NOSAMPLES;
    int             rcode;
    char            srcname[ORBSRCNAME_SIZE];
    double          pkttime = 0.0 ;
    int             pktid;
    int             nbytes;
    char           *packet = 0;
    int             packetsz = 0;
    Packet         *unstuffed = 0;
	Pf				*pf;
	Tbl				*tbl;
	Arr				*arr;
	char			*arrkey;
	char			*pffilename;

	Tbl				*channels;
	char			*net;
	char			*sta;
	char			*chan;
	char			netstachan[ORBSRCNAME_SIZE];
	Srcname			parts;
	double			maxtime,mintime,starttime,triggertime,duration,min_g,max_g,snr;
	char			*datalogger;
	int				evtfilesize,channelno,maxcts,mincts;
	char			*errors,*evtfilename,*ft,*filter,*srcid;
	char			*line;
	int				i;
	Pf				*pfnew;
	Dbptr			db;
	int 			put_tests=0;
	char 			*chanmatch=0;
	Hook			*hook=0;
	char			*tdummy=0;
	char 			*match=malloc(100);

	


    memset (&flags, 0, sizeof (flags));
    elog_init (argc, argv);
    elog_notify (0, "%s $Revision: 1.5 $ $Date: 2005/05/10 07:34:43 $\n",
		 Program_Name);

    while ((c = getopt (argc, argv, "m:n:r:S:c:tvV")) != -1) {
	switch (c) {
	  case 'm':
	    match = optarg;
		sprintf(pktmatch,"%s/pf/evtinfo",match);
	    break;
	  case 'c':
	 	chanmatch = optarg;
		break;
	  case 't':
	  	put_tests = 1;
		break;
	  case 'n':
	    maxpkts = atoi (optarg);
	    break;

	  case 'r':
	    reject = optarg;
	    break;

	  case 'S':
	    statefile = optarg;
	    break;

	  case 'v':
	    flags.verbose++;
	    break;

	  case 'V':
		flags.verbose++;
		flags.verbose++;
	    break;

	  case '?':
	    errflg++;
	}
    }

    if (errflg || argc - optind < 2 || argc - optind > 4)
	usage ();

    in = argv[optind++];
    out = argv[optind++];

    if (argc > optind) {
	after = str2epoch (argv[optind++]);
	specified_after = 1;
	if (argc > optind) {
	    until = str2epoch (argv[optind++]);
	    if (until < after) {
		until += after ;
	    }
	}
    }
    if ((orbin = orbopen (in, "r&")) < 0)
	die (0, "Can't open input '%s'\n", in);

    if (statefile != 0) {
		char           *s;
		if (exhume (statefile, &quit, RT_MAX_DIE_SECS, 0) != 0) {
	    elog_notify (0, "read old state file\n");
		}
		if (orbresurrect (orbin, &last_pktid, &last_pkttime) == 0) {
	    	elog_notify (0, "resurrection successful: repositioned to pktid #%d @ %s\n",
			 last_pktid, s = strtime (last_pkttime));
	    	free (s);
		} else {
	    	complain (0, "resurrection unsuccessful\n");
		}
    }
    if ((orbout = orbopen (out, "w&")) < 0) {
	die (0, "Can't open output '%s'\n", out);
    }
    if (pktmatch) {
	nmatch = orbselect (orbin, pktmatch);
    }
    if (nmatch < 0) {
	die (1, "select '%s' returned %d\n", pktmatch, nmatch);
    }
    if (reject) {
	nmatch = orbreject (orbin, reject);
    }
    if (nmatch < 0) {
		elog_die (1, "reject '%s' returned %d\n", reject, nmatch);
    } else {
		if (flags.verbose) {
			elog_notify (1,"%d sources selected\n", nmatch);
		}	
    }

    if (specified_after) {
	pktid = orbafter (orbin, after);
	if (pktid < 0) {
	    char           *s;
	    elog_complain (1, "seek to %s failed\n", s = strtime (after));
	    free (s);
	    pktid = forbtell (orbin);
	    elog_complain (1,"pktid is still #%d\n", pktid);
	} else {
	    if (flags.verbose) elog_notify (1,"new starting pktid is #%d\n", pktid);
	}
    }
    start_time = now ();

	db = dbtmp("rt1.0");

    while (!quit && pkttime < until && totpkts < maxpkts) {
	rcode = orbreap (orbin,
		    &pktid, srcname, &pkttime, &packet, &nbytes, &packetsz);

	switch (rcode) {
	  case 0:
	    totpkts++;
	    totbytes += nbytes;

	    if (flags.verbose>2) {
		showPkt (pktid, srcname, pkttime, packet, nbytes, stdout, mode);
	    }
	    if (statefile != 0
		    && last_pkttime - last_burial > decent_interval) {
		bury ();
		last_burial = pkttime;
	    }
	    if ((unstuffPkt (srcname, pkttime, packet, nbytes, &unstuffed))==Pkt_pf) {
		  	pf = 			unstuffed->pf;
			tbl=			pfkeys(pf);
			arrkey=			gettbl(tbl,0);
			pfget(pf,arrkey,&pfnew);
			datalogger=		pfget_string(pfnew,"datalogger");
			duration=		pfget_double(pfnew,"duration");
			errors=			pfget_string(pfnew,"errors");
			evtfilename=	pfget_string(pfnew,"evtfilename");
			evtfilesize=	pfget_int(pfnew,"evtfilesize");
			ft=				pfget_string(pfnew,"ft");
			starttime=		pfget_double(pfnew,"time");
			triggertime=	pfget_double(pfnew,"triggertime");

			channels=pfget_tbl(pfnew,"channels");
			if (strcasecmp(ft,"no")==0 || put_tests == 1) {
				for (i=0; i<maxtbl(channels);i++) {
					line=gettbl(channels,i);
					sscanf(line,"%s %d %lf %d %lf %lf %d %lf",
						netstachan,&channelno,&maxtime,&maxcts,&max_g,&mintime,&mincts,&min_g);
					split_srcname(netstachan,&parts);	
					strcpy(parts.src_suffix,"GENC");
					join_srcname(&parts,netstachan);
					if (flags.verbose>1) printf("%s,%s\n", netstachan,tdummy=strtime(triggertime));	
					if (chanmatch == 0 || 
							strmatches(parts.src_chan,chanmatch,&hook)) {
						if (flags.verbose) elog_notify(1,"putting detev for %s,%s\n", netstachan,tdummy=strtime(triggertime));	
						
						db=dblookup(db,0,"detev",0,"dbSCRATCH");
						dbputv(db,0,"sta",parts.src_sta,"chan",parts.src_chan,
							"filter",K2_FILTER,
							"time",	triggertime,
							"tron",  starttime - triggertime,
							"troff", starttime - triggertime + duration,
							"iphase","K2",
							"snr",(max_g * 1000.0  - min_g * 1000.0)/2.0,
							0);
						db2orbpkt(db,orbout);
					} else {
						if (flags.verbose>1) elog_notify(1,"ignoring %s,%s\n", netstachan,tdummy=strtime(triggertime));	

					}
				}
			}
			
	    }

	    last_pktid = pktid;
	    last_pkttime = pkttime;
	}

    }

    if (statefile != 0)
	bury ();

    end_time = now ();
    delta_t = end_time - start_time;
	if (flags.verbose>1) {
		if (totpkts > 0) {
		elog_notify (1,"\n%.0f %.2f byte packets (%.1f kbytes) in %.3f seconds\n\t%10.3f kbytes/s\n\t%10.3f kbaud\n\t%10.3f pkts/s\n",
			totpkts, totbytes / totpkts, totbytes / 1024,
			delta_t,
			totbytes / delta_t / 1024,
			totbytes / delta_t / 1024 * 8,
			totpkts / delta_t);
		} else {

		elog_notify (1,"\nno packets read\n");
		}
	}

    if (orbclose (orbin)) {
	elog_complain (1, "error closing read orb\n");
    }
    if (orbclose (orbout)) {
	elog_complain (1, "error closing write orb\n");
    }
    return 0;
}
int save_origin(int nass, int evid, Dbptr master_db, Dbptr dbtmp,
			Hypocenter h,Location_options o, int orb)
{
	int ndef;
	char dtype[2];
        char algorithm[16]="ggnloc";
	char auth[16]="orbgenloc";
	int grn, srn;
	int orid;  /* orid returned */

	orid = dbnextid(master_db,"orid");
	if(orid  < 0 )
		elog_die(1,"save_origin:  dbnextid failure asking for new orid\n");
        if(o.fix[2])
        {
                ndef = h.degrees_of_freedom + 3;
                strcpy(dtype,"r");
        }
        else
        {
                ndef = h.degrees_of_freedom + 4;
                strcpy(dtype,"f");
        }
	grn = grnumber(h.lat, h.lon) ;
	srn = srnumber ( grn ) ;
	dbtmp = dblookup(dbtmp,0,"origin",0,0);
	dbtmp.record = dbSCRATCH;
	if((dbputv(dbtmp,0,
                "lat",h.lat,
                "lon",h.lon,
                "depth",h.z,
                "time",h.time,
                "orid",orid,
		"evid",evid,
		"nass",nass,
		"grn", grn,
		"srn", srn,
		"dtype",dtype,
		"ndef",ndef,
		"algorithm",algorithm,
		"auth",auth,0))
			 == dbINVALID)
	{
		elog_complain(0,"dbputv error while building origin record for orid %d\nNo results saved\n",
			orid);
	}
	else
	{
		if(save_dbrecord(dbtmp,orb))
			elog_complain(0,"Errors saving orid %d\n",orid);
	}
	return(orid);
}
/*This function adds a single row to the origerr table for this event.

arguements:
	orid - orid assign to this solution
	h - Hypocenter object for this solution
	dbo - output db

This version doesn't set much of this large table.  Eventually, it 
needs to include all the error terms, but that function is not 
written yet. 

Author:  Gary L. Pavlis
Written:  February 1997
*/
void save_origerr(int orid, Hypocenter h, double **C, Dbptr db, int orb)
{
	double sdobs; 
	int rc;
	double smajax,sminax,strike,sdepth,stime;
	double conf=0.683;

	db = dblookup(db,0,"origerr",0,0);
	db.record = dbSCRATCH;

	/* computer error ellipse parameters */
	rc = project_covariance(C,CHI_SQUARE,&conf,
			h.rms_weighted,h.degrees_of_freedom,
			&smajax,&sminax,&strike,&sdepth,&stime);

	/* Bad news here is that we can't save the more useful 
	statistics that this program calculates.  css3.0 only allows
	sdobs = sswr/ndgf */

	sdobs = h.rms_raw;
	if(dbputv(db,0,
		"orid",orid,
                "sxx",C[0][0],
                "syy",C[1][1],
                "szz",C[2][2],
                "stt",C[3][3],
                "sxy",C[0][1],
                "sxz",C[0][2],
                "syz",C[1][2],
                "stx",C[0][3],
                "sty",C[1][3],
                "stz",C[2][3],
		"sdobs",sdobs,
		"smajax",smajax,
		"sminax",sminax,
		"strike",strike,
		"sdepth",sdepth,
		"stime",stime,
		"conf",conf,
			0) == dbINVALID)
	{
		elog_complain(0,"save_origerr: dbputv error writing origerr record for orid %d\norigerr record not saved anywhere\n",
				orid);
	}
	else
	{
		if(save_dbrecord(db,orb))
			elog_complain(0,"Error saving origerr record for orid %d\n",
				orid);
	}

}
Exemple #4
0
int save_tcorr( Dset *bset, Dset *gset, double tcorr)
{

    Dbtc.record = dbaddnull( Dbtc );
    dbputv( Dbtc, 0,
	   "time", bset->stime,
	   "tcor", tcorr,
	   "gnet", gset->net, 
	   "gsta", gset->sta, 
	   "gchan", gset->chan,
	   "gsrate", gset->srate,
	   "bnet", bset->net, 
	   "bsta", bset->sta, 
	   "bchan", bset->chan,
	   "bsrate", bset->srate,
	   "lddate", now(), 0);

    return 1 ;

}
Exemple #5
0
void
announce_StachanCalib( void *sccp, char *sta, char *chan ) 
{
	StachanCalib *scc = (StachanCalib *) sccp;
	static Dbptr db = { dbINVALID, dbINVALID, dbINVALID, dbINVALID };

	if( db.database == dbINVALID ) {

		db = dbtmp( "rt1.0" );

		db = dblookup( db, "", "wfoffset", "", "dbSCRATCH" );
	}

	if( abs( scc->offset ) < DBL_MIN ) {
		
		return;
	}

	dbputv( db, 0, "sta", sta, 
		       "chan", chan, 
		       "time", now(), 
		       "endtime", 9999999999.999,
		       "valoffset", scc->offset,
		       0 );

	if( db2orbpkt( db, Orbfd ) < 0 ) {
		
		elog_complain( 0, "Orbput failed for wfoffset packet!\n" );

	} else {
		
		scc->announced++;
	}

	return;
}
int main(int argc, char *argv[])
{
  unsigned int irand;
  int      isamp,wsamp,exists,iret,jdate,nsamp,wfid,itype,i,half;
  long int nw;
  double   samprate,time,endtime,toff,width;
  float    *s,*n,del,nfactor,mean,stdv,dummy,h;
  char     sta[7],chan[9],*database,*type;
  char     dir[65],dfile[33],outfile[100];
  Dbptr    db,dbw;
  FILE     *fp;
 
  database = malloc(80);
  type = malloc(20);

  if (argc < 13) 
  {
    printf("Usage: %s type toff width nfactor sta chan time samprate nsamp database dir filename\n",argv[0]);
    return 1;
  }

  type = argv[1];
  sscanf(argv[2],"%lf",&toff);
  sscanf(argv[3],"%lf",&width);
  sscanf(argv[4],"%f",&nfactor);
  strcpy(sta,argv[5]);
  strcpy(chan,argv[6]);
  sscanf(argv[7],"%lf",&time);
  sscanf(argv[8],"%lf",&samprate);
  sscanf(argv[9],"%d",&nsamp);
  database = argv[10];
  strcpy(dir,argv[11]);
  strcpy(dfile,argv[12]);
  s = malloc(nsamp*sizeof(float));
  n = malloc(nsamp*sizeof(float));

/*Open the output database.*/

  exists = 1;
  if ( (fp = fopen(database,"r")) == NULL)
    exists = 0;
  else
    fclose(fp);

/*It exists, so check if it can be opened and written to.*/

  if (exists)
  {
    if (dbopen(database,"r+",&db) < 0)
    {
      complain(0,"Could not open existing database for writing.\n");
      return 1;
    }
  }
  else
  {
    if (dbcreate(database,"css3.0",0,0,0) != 0)
    {
      complain(0,"Could not create new database.\n");
      return 1;
    }
    else
    {
      if (dbopen(database,"r+",&db) != 0)
      {
        complain(0,"Could not open new database for writing.\n");
        return 1;
      }
    }
  }

  dbw = dblookup(db,0,"wfdisc",0,0);
  iret = dbquery(dbw,dbRECORD_COUNT,&nw);
  printf("nw = %ld\n",nw);
  wfid = dbnextid(db,"wfid");

/*Create the synthetic trace.*/
  if (strcmp(type,"zeros"    ) == 0) itype = 1;
  if (strcmp(type,"delta"    ) == 0) itype = 2;
  if (strcmp(type,"boxcar"   ) == 0) itype = 3;
  if (strcmp(type,"triangle" ) == 0) itype = 4;
  if (strcmp(type,"sine"     ) == 0) itype = 5;
  if (strcmp(type,"impulse"  ) == 0) itype = 6;
  if (strcmp(type,"noise"    ) == 0) itype = 7;

/*Generate a zero-mean, unit rms, random noise series, whether used or not.*/
  irand = now()-1200000000;
  srand(irand);        /* sets the RNG with a random start integer*/
  for (i=0;i<nsamp;i++)
  {
/*    Use a trick to make sure some abnormal number is not generated.*/
      n[i] = 10.0;
      while (fabs(n[i]) > 9.9) n[i] = sqrt(-2.0*log(1.0 - 
        ((float) rand())/RAND_MAX))*cos(6.2832 * ((float) rand())/RAND_MAX);
  }
  del = 1/samprate;
  printf("itype = %d\n",itype);
  switch (itype) 
  {
    case 1:
      /*This creates a series of zeroes.*/
      for (i=0;i<nsamp;i++) s[i] = 0.0;
      break;
    case 2:
      /*This creates a delta function.*/
      for (i=0;i<nsamp;i++) s[i] = 0.0;
      isamp = toff*samprate;
      s[isamp] = 1.0;
      if (nfactor > 0)
      { 
        for (i=0;i<nsamp;i++) s[i] = s[i] + nfactor*n[i];
      }
      break;
    case 3:
      /*This creates a boxcar function.*/
      for (i=0;i<nsamp;i++) s[i] = 0.0;
      wsamp = width*samprate;
      /*Make it odd number of points, with center point splitting the boxcar.*/
      if (wsamp%2 == 0) wsamp = wsamp + 1;
      isamp = toff*samprate;
      for (i=isamp;i<isamp+wsamp;i++) s[i] = 1.0;
      if (nfactor > 0)
      { 
        for (i=0;i<nsamp;i++) s[i] = s[i] + nfactor*n[i];
      }
      break;
    case 4:
      /*This creates a triangle function.*/
      for (i=0;i<nsamp;i++) s[i] = 0.0;
      wsamp = width*samprate;
      /*Make it odd number of points, with peak at center point.*/
      if (wsamp%2 == 0) wsamp = wsamp + 1;
      half = wsamp/2;
      isamp = toff*samprate;
      for (i=isamp;i<isamp+half;i++) s[i] = 1.0*(i-isamp)/(float)half;
      s[isamp+half] = 1.0;
      for (i=isamp+half+1;i<isamp+wsamp;i++) s[i] = 1.0*(isamp+wsamp-i-1)/(float)half;
      if (nfactor > 0)
      { 
        for (i=0;i<nsamp;i++) s[i] = s[i] + nfactor*n[i];
      }
      break;
    case 5:
      /*This creates a 1/width Hz sine wave.*/ 
      for (i=0;i<nsamp;i++) s[i] = sin(2*pi*i*del/width);
      if (nfactor > 0)
      { 
        for (i=0;i<nsamp;i++) s[i] = s[i] + nfactor*n[i];
      }
      break;
    case 6:
      /*This creates an exponentially decaying sine wave, like a seismometer
        delta response (damping = 0.7).*/
      h = 0.7;
      for (i=0;i<nsamp;i++) s[i] = 0.0;
      isamp = toff*samprate;
      for (i=0;i<nsamp-isamp;i++) 
        s[i+isamp] = sin(2*pi*sqrt(1-h*h)*i*del/width)*exp(-0.7*2*pi*i*del/width);
      if (nfactor > 0)
      { 
        for (i=0;i<nsamp;i++) s[i] = s[i] + nfactor*n[i];
      }
      break;
    case 7:
      /*This creates a random white-noise series.*/
      for (i=0;i<nsamp;i++) s[i] = n[i];
      iret = stats(s,nsamp,2,&mean,&stdv,&dummy,&dummy);
      printf("mean,stdv = %f %f\n",mean,stdv);
      break;
    default:
      printf("Input 'type' does not match any options.\n");
      return 1;
  }

/*Write out the new trace.*/
  memcpy(outfile,"\0",1);
  strcat(outfile,dir);
  strcat(outfile,"/");
  strcat(outfile,dfile);
  printf("outfile = %s\n",outfile);
  if((fp=fopen(outfile,"w")) == NULL)
  {
    fprintf(stderr,"Can't open %s\n",outfile);
    return 1;
  }
  fwrite(s,sizeof(float),(unsigned int)nsamp,fp);
  fclose(fp);

/*Add entry to wfdisc. Note that, due to problem with dbaddv, we force the
  adding of the record with dbputv after a null record is created.*/
  dbw.record = dbaddnull(dbw);
  jdate = yearday(time);
  endtime = time + (nsamp - 1)/samprate;
  if (dbputv(dbw,0,
        "sta", sta,
        "chan", chan,
        "time", time,
        "endtime", endtime,
        "jdate", jdate,
        "nsamp", nsamp,
        "samprate", samprate,
        "datatype", "u4",
        "dir", dir,
        "dfile", dfile,
        "foff", 0,
        "wfid",wfid,
        NULL) < 0)
  {
      complain(0,"Could not add record to wfdisc file.\n");
      return 1;
  }

  dbclose(db);

} /*End main routine.*/
int grtr_sc_create(Dbptr dbsc, char *net_expr, char *sta_expr, 
        char *chan_expr, double tstart, double tend, char *gap,
        int calib, int ir, Dbptr *trscgr)
{
	char time_str[100];
	char endtime_str[100];
	int ret, n, n2, i;
	double time, time2, endtime, endtime2;
	char sta[32], chan[32];
	char sta2[32], chan2[32];
	char string[1024];
	char string2[64];
	int new_view = 0;
	int is, crunch;
	Response *resp;
	Dbptr db;

	/* Subset input view */

	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 (string[0]) {
		strcat (string, " )");
		dbsc = dbsubset (dbsc, string, 0);
		new_view = 1;
	}
        dbquery (dbsc, dbRECORD_COUNT, &n);
        if (n < 1) {
		register_error (0, "grtr_sc_create: No data to process.\n");
		if (new_view) dbfree (dbsc);
		return (-1);
        }

	/* Read in data */

	if (tstart == 0.0 && tend == 0.0) {
		dbquery (dbsc, dbRECORD_COUNT, &n);
		for (dbsc.record = 0; dbsc.record < n; dbsc.record++) {
			if (dbgetv (dbsc, 0, "time", &time, "endtime", &endtime, 0) == dbINVALID) {
        			register_error (0, "grtr_sc_create: dbgetv() error.\n");
				if (new_view) dbfree (dbsc);
        			return (-1);
			}
        		if (tstart == 0.0 && tend == 0.0) {
        			tstart = time;
        			tend = endtime;
			} else {
				if (time < tstart) tstart = time;
				if (endtime > tend) tend = endtime;
			}
		}
	}
        sprintf (time_str, "(%.5f)", tstart);
        sprintf (endtime_str, "(%.5f)", tend);
	dbsc.record = dbALL;
        ret = trload_css (dbsc, time_str, endtime_str, trscgr, "wfdisc", 0);

	/* Split, splice, apply calib */

	if (gap == NULL) strcpy (string, "seg");
	else strcpy (string, gap);
	if (!strcmp(string, "leave")) {
	} else if (!strcmp(string, "seg")) {
		trsplit (*trscgr, 0, 0);
		trsplice (*trscgr, 0.5, 0, 0);
	} else if (!strcmp(string, "interp")) {
		register_error (0, "grtr_sc_create: gap value '%s' not implemented yet.\n", string);
		if (new_view) dbfree (dbsc);
		return (-1);
	} else if (!strcmp(string, "zero")) {
		register_error (0, "grtr_sc_create: gap value '%s' not implemented yet.\n", string);
		if (new_view) dbfree (dbsc);
		return (-1);
	} else if (!strcmp(string, "drop")) {
		trsplit (*trscgr, 0, 0);
		trsplice (*trscgr, 0.5, 0, 0);
		crunch = 0;
		dbquery (*trscgr, dbRECORD_COUNT, &n);
		strcpy (sta2, "");
		strcpy (chan2, "");
		n2 = 0;
		db = *trscgr;
		for (trscgr->record=0; trscgr->record<n; (trscgr->record)++) {
			if (dbgetv (*trscgr, 0, "sta", sta, "chan", chan,
					0) == dbINVALID) {
        			register_error (0, "grtr_sc_create: dbgetv() error.\n");
				if (new_view) dbfree (dbsc);
        			return (-1);
			}
			if (strcmp(sta, sta2) || strcmp(chan, chan2)) {
				if (n2 > 1) {
        				for (db.record = is; db.record < is+n2; db.record++) {
        					trfree (db);
        					crunch = 1;
        				}
				}
				n2 = 1;
				is = trscgr->record;
				strcpy (sta2, sta);
				strcpy (chan2, chan);
				continue;
        		}
        		n2++;
		}
		if (n2 > 1) {
       			for (db.record = is; db.record < is+n2; db.record++) {
       				trfree (db);
       				crunch = 1;
       			}
		}
		if (crunch) {
			dbcrunch (db);
		}
	} else {
		register_error (0, "grtr_sc_create: Illegal gap value '%s'.\n", string);
		if (new_view) dbfree (dbsc);
		return (-1);
	}
	if (calib) trapply_calib (*trscgr);

	/* Read in instrument responses. */

	if (ir )
	{
	/* Run this section if instrument response is to be loaded */
	    dbsc.record = 0;
	    if (dbgetv (dbsc, 0, "instrument.inid", &i, 0) != dbINVALID && i >= 0) {
		dbquery (*trscgr, dbRECORD_COUNT, &n);
		dbquery (dbsc, dbRECORD_COUNT, &n2);
		for (trscgr->record=0; trscgr->record<n; (trscgr->record)++) {
			if (dbgetv (*trscgr, 0, "sta", sta, "chan", chan,
					"time", &time, 0) == dbINVALID) {
        			register_error (0, "grtr_sc_create: dbgetv() error.\n");
				if (new_view) dbfree (dbsc);
        			return (-1);
			}
			for (dbsc.record=0; dbsc.record<n2; dbsc.record++) {
				if (dbgetv (dbsc, 0, "sta", sta2, "chan", chan2,
					"time", &time2, "endtime", &endtime2, 0) == dbINVALID) {
        				register_error (0, "grtr_sc_create: dbgetv() error.\n");
					if (new_view) dbfree (dbsc);
        				return (-1);
				}
				if (strcmp(sta, sta2)) continue;
				if (strcmp(chan, chan2)) continue;
				if (time < time2) continue;
				if (time >= endtime2) continue;
				dbextfile (dbsc, "instrument", string);
				resp = (Response *) getarr (resp_arr, string);
				dbputv (*trscgr, 0, "response", resp, 0);
				break;
			}
		}
	    }
	}
	clear_register (0);
	if (new_view) dbfree (dbsc);

	/* Normal exit. */

	return (0);
}
/* Modified Dec. 2006:  added two new Tbls for resid and slowness to
compute residuals only=tapro and tupro. */
int
load_observations ( Pf *pf, Dbptr db, Arr *arr_phase, 
	    Arr **stationsp, Arr **arraysp, Tbl **tap, Tbl **tup ,
		Tbl **tapro, Tbl **tupro) 
{ 
    Station *station ;
    Seismic_Array *array ;
    Arrival *a ;
    Tbl *ta, *tu ,*taro, *turo;
    Dbptr dbarr, dbsite ;
    static Hook *hook = 0 ; 
    static Tbl *matching ;
    Tbl *arrival_tbl ;
    Arr *stations ;
    Arr *arrays ;
    int i, narr ;
    char sta[32], iphase[32], timedef[16], azdef[16], slodef[16] ;
    double time, deltim, azimuth, delaz, slow, delslo ; 
    int arid ;
    Phase_handle *phase ;
    Slowness_vector *u ;
    int nobs = 0 ;

    if ( *stationsp == 0 ) {
	*stationsp = newarr(0) ; 
	*arraysp = newarr(0) ; 
    }
    stations = *stationsp ; 
    arrays = *arraysp ; 

    ta = *tap = newtbl(0) ;
    tu = *tup = newtbl(0) ;
    taro = *tapro = newtbl(0) ;
    turo = *tupro = newtbl(0) ;

    dbarr = dblookup ( db, 0, "arrival", 0, "dbSCRATCH" ) ; 
    dbsite = dblookup ( db, 0, "site", 0, 0 ) ; 

    arrival_tbl = pfget_tbl(pf, "arrival_table");
    narr = maxtbl(arrival_tbl);
    for (i = 0; i < narr; i++) {
	sscanf(gettbl(arrival_tbl, i),
	       "%d %s %s %lf %lf %s %lf %lf %s %lf %lf %s",
	       &arid,
	       sta,
	       iphase,
	       &time,
	       &deltim,
	       timedef,
	       &azimuth,
	       &delaz,
	       azdef,
	       &slow,
	       &delslo,
	       slodef
	    );

	if ( (station = getarr ( stations, sta ) ) == 0 ) {
	    dbputv ( dbarr, 0, "sta", sta, "time", time, NULL ) ; 
	    dbmatches ( dbarr, dbsite, 0, 0, &hook, &matching ) ;
	    if ( maxtbl(matching) < 1 ) {
		char *t ;
		complain ( 0, "No site table record for %s at time %s\n", 
		    sta, t=strtime(time));
		free(t) ;
		continue ;
	    }

	    dbsite.record = (long) gettbl(matching, 0) ;
	    freetbl(matching,0) ;
	    allot ( Station *, station, 1 ) ; 
	    allot ( Seismic_Array *, array, 1 ) ; 
	    dbgetv ( dbsite, 0, 
		"sta", station->name, "lat", &station->lat, "lon", &station->lon, "elev", &station->elev, NULL ) ;
	    dbgetv ( dbsite, 0, 
		"sta", array->name, "lat", &array->lat, "lon", &array->lon, "elev", &array->elev, NULL ) ;
	    setarr (stations, sta, station ) ; 
	    setarr (arrays, sta, array ) ; 
	} else {
Exemple #9
0
save_ms ( Dbptr dborig ) {

     Dbptr db;
     Event *event;
     Tbl  *AllMs;
     double sum, unc;
     char auth[64], net[16], sta[16];
     char magtype[8];
     char *str, orig_str[16];
     int numms, total;
     int smags, nmags;
     int i;
     int arid, orid, evid, msid, magid;



     AllMs = keysarr( AllEv );
     numms = maxtbl( AllMs );
     if( numms <= 0 )  {
         complain (0, "Ther are no MS found for current orid.\n");
         return 0 ;
     }

     unc = 0.0; sum=0.0; total=0;

     for( i = 0; i < numms; i++ )  {
           str = ( char *) gettbl( AllMs, i );
           event = ( Event *) getarr( AllEv, str );
           if( event->ms < 0 )  continue;
           sum += event->ms;
           total ++;
     }
     sum /= total;
     if( total > 1 )  {
        for( i = 0; i < numms; i++ )  {
            str = ( char *) gettbl( AllMs, i );
            event = ( Event *) getarr( AllEv, str );
            if( event->ms < 0 )  continue;
            unc += (event->ms-sum) * (event->ms-sum);
        }
        unc /= (total-1);
        unc = sqrt(unc);
     } else unc = -1.0;


     /*  Fill netmag table  */

     db = dblookup (dborig, 0, "netmag", 0, 0);
     dbquery (db, dbRECORD_COUNT, &nmags);
	  
     magid = -1;
     for ( db.record = 0; db.record < nmags; db.record++) {
	dbgetv (db, 0, 
                "net", net, 
		"orid", &orid, 
                "magtype", magtype, 0);

        sprintf( orig_str, "%d\0", orid);
        if( !regexec( &orig_match, orig_str, (size_t) 0, NULL, 0 ) &&
            /*!regexec( &net_match, net, (size_t) 0, NULL, 0 ) &&  */
            orid == event->orid &&
            !strcmp(magtype, "ms")) break;
    }
   
    if ( db.record < nmags) {
	dbgetv (db, 0, "magid", &magid, 0);
	dbputv (db, 0, 
                "magid", magid, 
		"evid", event->evid,
		"magtype", "ms",
		"nsta", total,
		"magnitude", sum,
		"uncertainty", unc,
		"auth", "dbms", 0);
   } else  if ( sum > 0) {
		magid = dbnextid (db, "magid");
		db.field = dbALL;
		db.record = dbSCRATCH;
		dbputv (db, 0, 
			"net", event->net,
			"orid", event->orid,
			"evid", event->evid,
			"magid", magid, 
			"magtype", "ms",
			"nsta", total,
			"magnitude", sum,
			"uncertainty", unc,
			"auth", "dbms", 0);
		dbadd (db, 0);
   }

   msid = magid;

   /*	Fill origin table with MS  */                           
 
   if( !regexec( &orig_match, orig_str, (size_t) 0, NULL, 0 ) &&
       !regexec( &auth_match, event->auth, (size_t) 0, NULL, 0 ) ) {
	db = dball;
        db.record = Crnt_record;
	dbputv (db, 0, "ms", sum, "msid", msid, 0);
    }

   
    /*	Fill MS into stamag table  */
     

   db = dball;
   db = dblookup (db, 0, "stamag", 0, 0);
   dbquery (db, dbRECORD_COUNT, &smags);

   for( i = 0; i < numms; i ++ )  {
       str = ( char *) gettbl( AllMs, i );
       event = ( Event *) getarr( AllEv, str );
       if( event->ms < 0 )  continue;
       for (db.record=0; db.record<smags; db.record++) {
           dbgetv (db, 0, "sta", sta, "magid", &magid, 0);
           if (magid == msid && !strcmp(event->sta, sta)) break;
       }
       if (db.record<smags) {
 	   dbputv (db, 0, 
		"arid", event->arid,
		"orid", event->orid,
		"evid", event->evid,
		"phase", event->phase,
		"magtype", "ms",
		"magnitude", event->ms,
		"auth", "dbms", 0);
       } else if (event->ms > 0) {
		db.field = dbALL;
		db.record = dbSCRATCH;
		dbputv (db, 0, 
			"sta", event->sta,
			"arid", event->arid,
			"orid", event->orid,
			"evid", event->evid,
			"phase", event->phase,
			"magid", msid, 
			"magtype", "ms",
			"magnitude", event->ms,
			"auth", "dbms", 0);
		dbadd (db, 0);
       }	
       free(event);
       delarr( AllEv, str);
   }
 

    freetbl( AllMs, 0 );
    return (1);
}
void save_assoc(Tbl *ta, Tbl *tu, 
	int orid, char *vmodel, Hypocenter hypo, 
	Dbptr db, int orb)
{
        double delta;
        double seaz;
        double esaz;
        double azres;
        double slores;
        Arr *u_arr;
	char key_arid[20];
	Tbl *udregs; 
        int i,n;
 
        double ux, uy, azimuth;
        double duphi;
	Arrival *a;
	Slowness_vector *u;

	/* We build an associative array keyed to arid for
	all the slowness vector measurements. 
	Then in the loop below we can efficiently find any
	slowness vectors associated with the same arid as
	an Arrival.  The overhead in this is significant, but
	it makes it completely general and open ended.  */
	n = maxtbl(tu);
	u_arr = newarr(0);
	for(i=0;i<n;i++)
	{
		Slowness_vector *utmp;
		utmp = (Slowness_vector *)gettbl(tu,i);
		sprintf(key_arid,"%d",utmp->arid);
		setarr(u_arr,key_arid,utmp);
	}
	db = dblookup(db,0,"assoc",0,0);
	db.record = dbSCRATCH;

	n=maxtbl(ta);
	for(i=0;i<n;i++)
	{
		a=(Arrival*)gettbl(ta,i);
		dist(rad(hypo.lat),rad(hypo.lon),
		  rad(a->sta->lat),rad(a->sta->lon),&delta,&esaz);
		dist(rad(a->sta->lat),rad(a->sta->lon),
		  rad(hypo.lat),rad(hypo.lon),&delta,&seaz);
		sprintf(key_arid,"%d",a->arid);
		u = (Slowness_vector *) getarr(u_arr,key_arid);
		if(u == NULL)
		{
		    if(dbputv(db,0,
			"orid",orid,
			"arid",a->arid,
			"sta",a->sta->name,
			"phase",a->phase->name,
			"delta",deg(delta),
			"seaz",deg(seaz),
			"esaz",deg(esaz),
			"timeres",(double)a->res.raw_residual,
			"timedef","d",
			"vmodel",vmodel,
			"wgt",(double)a->res.residual_weight,
		  	0)<0)
		    {
			  elog_complain(0,
			    "Can't add assoc record for station %s arid = %d orid = %d to working db scratch record\nRecord skipped and not saved anywhere\n",
				a->sta->name,a->arid,orid);
			  continue;
		    }
		}
		else
		{
			slores = deg2km(sqrt(sqr(u->xres.raw_residual) 
				+ sqr(u->yres.raw_residual)));
			azimuth = atan2 ( u->uy, u->ux ) ;
			duphi = (u->ux*cos(azimuth) 
				- u->uy*sin(azimuth)) 
				/ sqrt(sqr(u->ux)+ sqr(u->uy)) ;
			azres = deg(duphi);
			if(dbputv(db,"assoc",
				"orid",orid,
				"arid",a->arid,
				"sta",a->sta->name,
				"phase",a->phase->name,
				"delta",deg(delta),
				"seaz",deg(seaz),
				"esaz",deg(esaz),
				"timeres",(double)a->res.raw_residual,
				"timedef","d",
				"vmodel",vmodel,
				"slores",slores,
				"slodef","d",
				"azres",azres,
				"azdef","d",
				"wgt",(double)a->res.residual_weight,
		  	  0)<0)
			{
			  	elog_complain(0,
				  "Can't add assoc record for station %s arid = %d orid = %d to working db scratch record\nRecord skipped and not saved anywhere\n",
				a->sta->name,a->arid,orid);
				delarr(u_arr,key_arid);
				continue;
			}
			/* We delete this entry from u_arr, then we
			can scan below for the dregs easily */
			delarr(u_arr,key_arid);
		}
		if(save_dbrecord(db,orb))
			elog_complain(0,"Error saving assoc record for arid %d\n",
				a->arid);
	}
	/* Since it is possible that slowness vectors can be measured
	with no arrival time, we need to take care of that possibility.
	We do that by checking for dregs in u_arr not removed with
	delarr calls above */
	udregs = keysarr(u_arr);

	n = maxtbl(udregs);
	for(i=0;i<n;i++)
	{
		char *key;
		key = gettbl(udregs,i);
		u = (Slowness_vector *) getarr(u_arr,key);
                dist(rad(hypo.lat),rad(hypo.lon),
                  rad(u->array->lat),rad(u->array->lon),&delta,&esaz);
                dist(rad(u->array->lat),rad(u->array->lon),
                  rad(hypo.lat),rad(hypo.lon),&delta,&seaz);
                slores = deg2km(sqrt(sqr(u->xres.raw_residual)
                          + sqr(u->yres.raw_residual)));
                azimuth = atan2 ( u->uy, u->ux ) ;
                duphi = (u->ux*cos(azimuth)
                          - u->uy*sin(azimuth))
                          / sqrt(sqr(u->ux)+ sqr(u->uy)) ;
                azres = deg(duphi);
		/* The residual weight extraction from the ux component is 
		not ideal here because it could be wrong.  It is unavoidable
		due to polar-cartesian conversion */
		if(dbputv(db,"assoc",
			"orid",orid,
			"arid",u->arid,
			"sta",u->array->name,
			"phase",u->phase->name,
			"delta",deg(delta),
			"seaz",deg(seaz),
			"esaz",deg(esaz),
			"timedef","n",
			"vmodel",vmodel,
			"slores",slores,
			"slodef","d",
			"azres",azres,
			"azdef","d",
			"wgt",(double)u->xres.residual_weight,
	  	  0)<0)
		{
		  	elog_complain(0,"Can't add assoc record for array slowness vector with %s arid = %d and orid = %d to working db scratch record\nNothing saved\n",
			u->array->name,u->arid,orid);
			continue;
		}
		if(save_dbrecord(db,orb))
			elog_complain(0,"Error saving assoc record for arid %d\n",
				u->arid);		

	}
	/* We must not use regular free here, or later we could try
	to free the same area twice.  That is, u_tmp contains keyed
	version of the pointers stored in tu.  This releases only
	the Arr structures, but leaves the pointers to be freed 
	later.  I've never seen a better example of the need for
	a decent garbage collection system. */
	freetbl(udregs,free_nothing);
	freearr(u_arr,free_nothing);
}
Exemple #11
0
static void
archive_dlsvar( Dbptr db, char *net, char *sta, char *dls_var, char *dsparams, Tbl *rras, double time, double val )
{
	char	key[STRSZ];
	char	*rrd;
	double	start_time;
	Dbptr	dbt;
	char	datasource[STRSZ];
	char	command[STRSZ];
	char	response[STRSZ];
	char	*resp_ptr;
	int	i;

	sprintf( key, "%s:%s:%s", net, sta, dls_var );

	rrd = getarr( Rrd_files, key );

	if( rrd == NULL || ! is_present( rrd ) ) {

		start_time = time - Status_stepsize_sec;

		dbt = db;
		dbt.record = dbaddnull( db );

		dbputv( dbt, 0, "net", net,
				"sta", sta,
				"rrdvar", dls_var,
				"time", start_time,
				0 );

		trwfname( dbt, Rrdfile_pattern, &rrd );

		sprintf( datasource, "DS:%s:%s", dls_var, dsparams );

		if( Verbose ) {

			elog_notify( 0, "Creating rrdfile %s\n", rrd );
		}

		sprintf( command, "create %s -b %d -s %f %s", 
			rrd, (int) floor( start_time ), Status_stepsize_sec, datasource );

		for( i = 0; i < maxtbl( rras ); i++ ) {

			strcat( command, " " );
			strcat( command, (char *) gettbl( rras, i ) );
		}
	
		fprintf( Rrdfp, "%s\n", command );

		if( VeryVerbose ) { 

			resp_ptr = getaline( Rrdfp, response, STRSZ );

			if( resp_ptr == (char *) NULL ) {

				elog_notify( 0, "%s\n", "(null)" );

			} else {

				elog_notify( 0, "%s\n", resp_ptr );
			}
		}

		setarr( Rrd_files, key, rrd );
	}

	if( VeryVerbose ) {

		elog_notify( 0, "Recording time '%f' value '%f' from '%s:%s:%s' in '%s'\n",
			time, val, net, sta, dls_var, rrd );
	}

	sprintf( command, "update %s %d:%f", rrd, (int) floor( time ), val );

	fprintf( Rrdfp, "%s\n", command );

	if( VeryVerbose ) { 

		resp_ptr = getaline( Rrdfp, response, STRSZ );

		if( resp_ptr == (char *) NULL ) {

			elog_notify( 0, "%s\n", "(null)" );

		} else {

			elog_notify( 0, "%s\n", resp_ptr );
		}
	}
}
void mexFunction ( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] )
{
	Dbptr	db;
	Dbvalue	*value;
	char	errmsg[STRSZ];
	char	*field_name;
	int	nfields;
	int	retcode = 0;
	int	rc;
	long	type;
	int	fieldname_index;
	int	fieldval_index;
	int	i;

	if( nrhs < 3 )
	{
		antelope_mexUsageMsgTxt ( USAGE );
		return;
	}
	else if( ( nrhs - 1 ) % 2 != 0 )
	{
		antelope_mexUsageMsgTxt ( USAGE );
		return;
	}
        else if( ! get_dbptr( prhs[0], &db ) )
        {
                antelope_mexUsageMsgTxt ( USAGE );
		return;
        }

	nfields = ( nrhs - 1 ) / 2;

	for( i = 0; i < nfields; i++ )
	{
		fieldname_index = i * 2 + 1;
		if( mxGetClassID( prhs[fieldname_index] ) != mxCHAR_CLASS )
		{
			antelope_mexUsageMsgTxt ( USAGE );
			return;
		}
	}

	for( i=0; i<nfields; i++ )
	{
		fieldname_index = i * 2 + 1;
		fieldval_index = fieldname_index + 1;

		get_malloced_string( prhs[fieldname_index], &field_name );

		db = dblookup ( db, 0, 0, field_name, 0 );
		antelope_mex_clear_register( 1 );

		rc = dbquery ( db, dbFIELD_TYPE, &type );
		antelope_mex_clear_register( 1 );
		if( rc == dbINVALID )
		{
			sprintf( errmsg,
				 "dbputv: dbquery failed for field %s",
				 field_name );
			mxFree( field_name );
			mexErrMsgTxt( errmsg );
		}

		value = mxArray2dbvalue( prhs[fieldval_index], type );
		if( value == (Dbvalue *) NULL )
		{
			sprintf( errmsg,
				 "dbputv: failed to convert field %s",
				 field_name );
			mxFree( field_name );
			mexErrMsgTxt( errmsg );
		}

		switch (type ) {
		case dbDBPTR:
			retcode |= dbputv( db, 0, field_name, value->db, NULL );
			break;
		case dbSTRING:
			retcode |= dbputv( db, 0, field_name, value->s, NULL );
			break;
		case dbBOOLEAN:
		case dbYEARDAY:
		case dbINTEGER:
			retcode |= dbputv( db, 0, field_name, value->i, NULL );
			break;
		case dbREAL:
		case dbTIME:
			retcode |= dbputv( db, 0, field_name, value->d, NULL );
			break;
		default:
			retcode = -1;
			break;
		}
		antelope_mex_clear_register( 1 );

		mxFree( value );
		mxFree( field_name );
	}

	if( retcode != 0 )
	{
		mexErrMsgTxt( "dbputv failed" );
	}
}
Exemple #13
0
static void
archive_dlsvar( Dbptr db, char *net, char *sta, char *dls_var, char *dsparams, Tbl *rras, double time, double val )
{
	char	key[STRSZ];
	char	*rrd;
	double	start_time;
	Dbptr	dbt;
	char	datasource[STRSZ];
	char	command[STRSZ];
	char	cacheopt[FILENAME_MAX];
/* Disable response printing for now (see below)
	char	response[STRSZ];
	char	*resp_ptr;
 */
	int	i;

	sprintf( key, "%s:%s:%s", net, sta, dls_var );

	rrd = getarr( Rrd_files, key );

/*	rrdtool in server-mode apparently does not write files until a request occurs to switch to the next
	file, so the test below doesn't work right. Trust the database to report existing files:
 	if( rrd == NULL || ! is_present( rrd ) ) {
*/
	if( rrd == NULL ) {

		start_time = time - Status_stepsize_sec;

		dbt = db;
		dbt.record = dbaddnull( db );

		dbputv( dbt, 0, "net", net,
				"sta", sta,
				"rrdvar", dls_var,
				"time", start_time,
				NULL );

		trwfname( dbt, Rrdfile_pattern, &rrd );

		sprintf( datasource, "DS:%s:%s", dls_var, dsparams );

		if( Verbose ) {

			elog_notify( 0, "Creating rrdfile %s\n", rrd );
		}

		sprintf( command, "create %s -b %d -s %f %s", 
			rrd, (int) floor( start_time ), Status_stepsize_sec, datasource );

		for( i = 0; i < maxtbl( rras ); i++ ) {

			strcat( command, " " );
			strcat( command, (char *) gettbl( rras, i ) );
		}

		if( VeryVerbose ) {
			
			elog_notify( 0, "Issuing rrdtool command: '%s'\n", command );
		}
	
		fprintf( Rrdfp, "%s\n", command );

		/* Disable response printing for now since popen() bi-directional pipes 
		   are not supported across all platforms: 

		if( VeryVerbose ) { 

			resp_ptr = getaline( Rrdfp, response, STRSZ );

			if( resp_ptr == (char *) NULL ) {

				elog_notify( 0, "%s\n", "(null)" );

			} else {

				elog_notify( 0, "%s\n", resp_ptr );
			}
		}
		*/

		setarr( Rrd_files, key, strdup( rrd ) );
	}

	if( VeryVerbose ) {

		elog_notify( 0, "Recording time '%f' value '%f' from '%s:%s:%s' in '%s'\n",
			time, val, net, sta, dls_var, rrd );
	}

	if( CacheDaemon == NULL ) {

		sprintf( cacheopt, "%s", "" );

	} else {

		sprintf( cacheopt, "--daemon=%s", CacheDaemon );

	}

	sprintf( command, "update %s %s %d:%f", cacheopt, rrd, (int) floor( time ), val );

	if( VeryVerbose ) {
			
		elog_notify( 0, "Issuing rrdtool command: '%s'\n", command );
	}
	
	fprintf( Rrdfp, "%s\n", command );

	/* Disable response printing for now since popen() bi-directional pipes 
	   are not supported across all platforms: 

	if( VeryVerbose ) { 

		resp_ptr = getaline( Rrdfp, response, STRSZ );

		if( resp_ptr == (char *) NULL ) {

			elog_notify( 0, "%s\n", "(null)" );

		} else {

			elog_notify( 0, "%s\n", resp_ptr );
		}
	}
	*/
}
int load_station_geometry(Dbptr db, Arr *a, double time)
{
	Dbptr dbs;
	int i,j,nset;
	Tbl *t;
	char *key;
	int yrday;
	Dbptr dbscr;
	static Hook *hook=NULL;
	Tbl *match_tbl;
	MWstation *s;
	int ondate,offdate;
	char refsta[10];  /*This is used as input buffer that
				is duped to store in each s object*/
	char refsta0[10];  /* Used for comparison to guarantee there
				is no change in refsta */

	yrday = yearday(time);
	t = keysarr(a);
	db = dblookup(db,0,"site",0,0);
	dbs = dblookup(db,0,"site",0,0);
	dbs.record = dbSCRATCH;	
	dbaddnull(dbs);

	for(i=0,nset=0;i<maxtbl(t);i++)
	{
		int nmatch;
		key = gettbl(t,i);
		s = (MWstation *)getarr(a,key);
		dbputv(dbs,0,"sta",s->sta,0);
		nmatch = dbmatches(dbs,db,0,0,&hook,&match_tbl);
		if(nmatch == dbINVALID)
			elog_die(0,"dbmatches error looking for entries for station %s\n",s->sta);
		else if(nmatch < 1)
		{
			elog_notify(0,"load_station_geometry:  cannot find station %s in site table -- deleted from geometry list\n",
				s->sta);
			delarr(a,s->sta);
			free_MWstation(s);
		}
		else
		{
			/* when when there is only one match, we just use it, otherwise
			we have to search for the correct entry based on ondate/offdate */

			if(nmatch == 1)
			{
				db.record = (int )gettbl(match_tbl,0);
			}
			else
			{
				for(j=0;j<maxtbl(match_tbl);j++)
				{
					db.record = (int)gettbl(match_tbl,j);
					if(dbgetv(db,0,"ondate",&ondate,
							"offdate",&offdate,0)
						== dbINVALID)
					{
						elog_notify(0,"load_station_geometry:  dbgetv error while searching for ondate/offdate match for station %s\nBlundering on\n", 
							s->sta);
						continue;
					}
					if((yrday >= ondate) && (yrday <= offdate)) break;
				}
			}
			/* note if the date match fails,we still end up here 
			using the last record in the db */
			freetbl(match_tbl,0);
			if(dbgetv(db,0,
				"lat",&(s->lat),
				"lon",&(s->lon),
				"elev",&(s->elev),
				"dnorth",&(s->dnorth),
				"deast",&(s->deast),
				"refsta",refsta,
				0) == dbINVALID)
			{
				elog_notify(0,"load_station_geometry:  dbgetv error reading record %d for station %s in site table\nStation deleted from list\n",
					db.record,s->sta);
				delarr(a,s->sta);
				free_MWstation(s);
			}
			else
			{
				if(nset==0) strcpy(refsta0,refsta);
				s->refsta = strdup(refsta0);
				if(!strcmp(s->sta,refsta0))
				{
					if(((s->dnorth)!=0.0) 
						|| ((s->deast)!=0.0))
						elog_die(0,"load_station_geometry:  reference station in site table must have dnorth and deast set to 0.0\nFound refstat = %s with (dnorth,deast)=(%lf,%lf)\n",
							s->sta,s->dnorth,
							s->deast);
					++nset;
				}
				else
				/* This deletes stations != refsta with dnorth 
				and deast not set properly.  */
				{
					if(((s->dnorth)==0.0) && ((s->deast)==0.0))
					{
						elog_notify(0,"load_station_geometry:  unset dnorth and deast entries for station %s\nStation deleted from list\n",
							s->sta);
						delarr(a,s->sta);
						free_MWstation(s);
					}
					else if(strcmp(refsta0,refsta))
						elog_die(0,"load_station_geometry:  reference station change not allowed.\nAll stations to be processed must have a common refsta in site table\n");
					else
						++nset;
				}
			}
		}
	}		
	return(nset);
}
long writePolygonData(Dbptr db, Point *poly, long npoints, char *pname, int closed, int level, char *ptype, char *auth, char *dir, char *dfile, int pcode) {
	/* writes poygon data into file
   		if dir and o dfile are NULL, use defaults
		returns record number if successful,dbINVALID else
	 */		
	long i;
	char datafilename[PATH_MAX];
	FILE *dfh;
	int foff;
	char *ftype;
	int int1,int2;
	float float1,float2;
	double north=-360.0,east=-360.0,west=360.0,south=360.0;
	double lat,lon;
	int pid;
	int free_dir=0;
	int free_dfile=0;
	char closed_flag[2];

	if (closed) {
		strcpy(closed_flag,"y");
	} else {
		strcpy(closed_flag,"n");
	}

	pid=dbnextid(db,"pid");
	
	db=dblookup(db, 0, "polygon", 0, 0);
	if ( (db.record=dbaddnull(db) ) ==dbINVALID) {
		elog_log(0,"writePolygonData: problem adding row...");
		return dbINVALID;
	}
	
	if (dir == NULL) {
		dir = strdup(default_dir);
		free_dir=1;
	}
	if (dfile == NULL) {
		dfile = strdup(default_dfile);
		free_dfile=0;
	}

	if (dbputv(db,0,"pid",pid,"dir",dir,"dfile",dfile,NULL ) == dbINVALID) {
		elog_log(0,"writePolygonData: error putting dir %s & dfile %s",dir,dfile);
		if (free_dir) free(dir);
		if (free_dfile) free(dfile);
		return dbINVALID;
	}
	/* some fix needed here when in "relative" directories...*/
	switch (dbfilename(db,datafilename)) {
		case -1:
			if (makedir(dir)<0) {
				elog_log(0,"writePolygonData: dir %s is NOT writable!",dir);
				if (free_dir) free(dir);
				if (free_dfile) free(dfile);
				return dbINVALID;
			}
			if ((dfh= fopen(datafilename,"w"))==NULL) {
				elog_log(0,"writePolygondata: error crating %s/%s",dir,dfile);
				if (free_dir) free(dir);
				if (free_dfile) free(dfile);
				return dbINVALID;
				}
			foff= 0;
			break;
		case 0:
			/*make file*/
			if (makedir(dir)<0) {
				elog_log(0,"problem creating directory %s",dir);
				if (free_dir) free(dir);
				if (free_dfile) free(dfile);
				return dbINVALID;
			}
			if ((dfh= fopen(datafilename,"w"))==NULL) {
				elog_log(0,"problem creating file %s",dir);
				if (free_dir) free(dir);
				if (free_dfile) free(dfile);
				return dbINVALID;
			}
			foff= 0;
			break;
		case 1:
			/*append*/	
			dfh= fopen(datafilename,"a");
			fseek(dfh,0,2);
			foff= ftell(dfh);
			break;
		case 2:
			/*.Z exists....*/
			elog_log(0,"writePolygonData: compression not yet supported...");
			if (free_dir) free(dir);
			if (free_dfile) free(dfile);
			return dbINVALID;
			break;
		default:
			elog_log(0,"writePolygondata: unknown return value from dbfilename, giving up...");
			if (free_dir) free(dir);
			if (free_dfile) free(dfile);
			return dbINVALID;	
			
	}
	ftype = polytype(pcode);
	
	switch (pcode) {
		case polyINT:
			for (i=0;i < npoints;i++) {
				lon=poly[i].lon;
				west = (lon<west) ? lon : west;
				east = (lon>east) ? lon : east;
				int1=lon * 1e6;
				H2N4((char *)(&int2),(char *)(&int1),1);
				fwrite(&int2,sizeof(int),1,dfh);

				lat=poly[i].lat;
				south = (lat < south) ? lat : south;
				north = (lat > north) ? lat : north;
				int1=lat * 1e6;
				H2N4((char *)(&int2),(char *)(&int1),1);
				fwrite(&int2,sizeof(int),1,dfh);
			}
			fclose(dfh);
			break;
		case polyINTELINT:
			for (i=0;i < npoints;i++) {
				lon=poly[i].lon;
				west = (lon<west) ? lon : west;
				east = (lon>east) ? lon : east;
				int1=lon * 1e6;
				#ifdef WORDS_BIGENDIAN
					swap4(&int1,&int2,1);
				#else
					int2=int1;
				#endif
				fwrite(&int2,sizeof(int),1,dfh);

				lat=poly[i].lat;
				south = (lat < south) ? lat : south;
				north = (lat > north) ? lat : north;
				int1=lat * 1e6;
				#ifdef WORDS_BIGENDIAN
					swap4(&int1,&int2,1);
				#else
					int2=int1;
				#endif
				fwrite(&int2,sizeof(int),1,dfh);
			}
			fclose(dfh);
			break;
		case polyFLOAT:
			for (i=0;i < npoints;i++) {
				lon=poly[i].lon;
				west = (lon<west) ? lon : west;
				east = (lon>east) ? lon : east;
				float1=lon;
				H2N4((char *)(&float2),(char *)(&float1),1);
				fwrite(&float2,sizeof(float),1,dfh);

				lat=poly[i].lat;
				south = (lat < south) ? lat : south;
				north = (lat > north) ? lat : north;
				float1=lat;
				H2N4((char *)(&float2),(char *)(&float1),1);
				fwrite(&float2,sizeof(float),1,dfh);
			}
			fclose(dfh);
			break;	
		case polyINTELFLOAT:
			for (i=0;i < npoints;i++) {
				lon= poly[i].lon;
				west= (lon<west) ? lon : west;
				east= (lon>east) ? lon : east;
				float1=lon;
				#ifdef WORDS_BIGENDIAN
					swap4(&float1,&float2,1);
				#else	
					float2= float1;
				#endif
				fwrite(&float2,sizeof(float),1,dfh);
				lat= poly[i].lat;
				south= (lat < south) ? lat : south;
				north= (lat > north) ? lat : north;
				float1=lat;
				#ifdef WORDS_BIGENDIAN
					swap4(&float1,&float2,1);
				#else	
					float2= float1;
				#endif
				fwrite(&float2,sizeof(float),1,dfh);
			}
			fclose(dfh);
			break;	
		case polyGSHHS:
			elog_log(0,"writePolygonData: storage type %s not yet implemented... ",ftype);
			if (free_dir) free(dir);
			if (free_dfile) free(dfile);
			return dbINVALID;
			break;
		default:
			elog_log(0,"writePolygonData: unknown storage type pcode, giving up");
			if (free_dir) free(dir);
			if (free_dfile) free(dfile);
			return dbINVALID;
	}	
	if (dbputv(db,0,"north",north, "east",east, "south",south, "west",west,
			"pname",pname,"closed",closed_flag,"level",level,"ptype",ptype, "auth",auth,"npoints",npoints, "ftype",ftype,"foff",foff,NULL ) == dbINVALID) {
		elog_log(0,"writePolygonData: error putting values!");
		//free (ftype);
		if (free_dir) free(dir);
		if (free_dfile) free(dfile);
		return dbINVALID;
	} else {
		//free (ftype);
		if (free_dir) free(dir);
		if (free_dfile) free(dfile);
		return db.record;
	}
}
int
write_trace (Dbptr db, char *sta, char *chan, char *dir, char *dfile, Trace *trace, double tstart, double tend, int overwrite)

{
    int fd;
    char outdir[1024];
    char outbase[1024];
    char fname[1024];
    int sz, size, ret;
    int is, ie, ns;
    Dbvalue dbv;

    is = (tstart-trace->tstart)/trace->dt + 0.0001;
    ie = (tend-trace->tstart)/trace->dt - 0.0001;
    if (is > trace->nsamps-1) return (1);
    if (ie < 0) return (1);
    if (is < 0) is = 0;
    if (ie > trace->nsamps-1) ie = trace->nsamps-1;
    ns = ie - is + 1;
    if (ns < 1) return (1);
    db = dblookup (db, 0, "wfdisc", 0, 0);
    if (dir[0] == '/') {
        sprintf (fname, "%s/%s", dir, dfile);
    } else {
        dbquery (db, dbTABLE_DIRNAME, &dbv);
        strcpy (outbase, dbv.t);
        sprintf (fname, "%s/%s/%s", outbase, dir, dfile);
    }
    if (!overwrite) {
        if (zaccess(fname, F_OK) != -1) {
            fprintf (stderr, "write_trace: wf file conflict for '%s'.\n",
                     fname);
            return (0);
        }
    }
    dirbase (fname, outdir, outbase);
    if (makedir(outdir) == -1) {
        fprintf (stderr, "write_trace: Unable to create %s\n", outdir);
        return (0);
    }
    fd = open (fname, (O_RDWR|O_CREAT|O_TRUNC), 0666);
    if (fd < 0) {
        fprintf (stderr, "write_trace: Open error on '%s'.\n", fname);
        return (0);
    }
    sz = atoi(&trace->rawdata_format[strlen(trace->rawdata_format)-1]);
    size = sz*ns;
    ret = write (fd, &(((char *)trace->raw_data)[is*sz]), size);
    close (fd);
    if (ret < size) {
        fprintf (stderr, "write_trace: Write error on '%s'.\n", fname);
        return (0);
    }
    db.record = dbNULL;
    db.field = dbALL;
    dbget(db, 0);
    db.record = dbSCRATCH;
    dbputv (db, 0,	"sta", sta,
            "chan", chan,
            "time", trace->tstart+is*trace->dt,
            "wfid", dbnextid(db, "wfid"),
            /*			"chanid", chanid,*/
            "jdate", yearday(trace->tstart),
            "endtime", trace->tstart+trace->dt*(trace->nsamps-1),
            "nsamp", (long)ns,
            "samprate", 1.0/trace->dt,
            "calib", trace->calib,
            "calper", trace->calper,
            "instype", "BEAM",
            "segtype", trace->rawdata_type,
            "datatype", trace->rawdata_format,
            /*			"clip", clip,*/
            "dir", dir,
            "dfile", dfile,
            "foff", (long)0,
            NULL);
    dbadd (db, 0);
    return (1);
}
static int
write_cal2 (Dbptr db, double time, double endtime, double *calperp)
{
    static Dbptr    dbx = INVALID_DBPTR;
    static double   null_endtime = 0.0;
    Dbptr           dbcalibration;
    long            nmatches;
    char            sta[MAX_STA_SIZE],
                    chan[MAX_CHAN_SIZE],
                    units[16],
                    instype[16];
    double          calib,
                    calper=0;
    long            j;
    int             errors = 0;
    Tbl            *tbl;
    static Hook    *hook = 0;
    char           *ontime,
                   *offtime;
    char           *aux = "";
    char           *s,
                   *t;
    char            segtype;
    double          samprate;

    if (dbx.database == dbINVALID) {
	dbx = dblookup (db, 0, "wfdisc", 0, 0);
	dbx.record = dbNULL;
	dbgetv (dbx, 0, "endtime", &null_endtime, NULL);
	dbx.record = dbSCRATCH;
    }
    dbgetv (db, 0, "sta", sta, "chan", chan, NULL);
    dbputv (dbx, 0, "sta", sta, "chan", chan, "time", time, "endtime", endtime, NULL);

    errors += get_instype (dbx, instype, &samprate);

    dbcalibration = dblookup (db, 0, "calibration", 0, 0);
    nmatches = dbmatches (dbx, dbcalibration, 0, 0, &hook, &tbl);
    switch (nmatches) {
      case dbINVALID:
      case 0:
	dbgetv (db, 0, "sta", sta, "chan", chan, "time", &time, NULL);
	complain (0, "no matches in calibration table for %s:%s @ %s",
		  sta, chan, s = strydtime (time));
	free (s);
	break;

      default:
	dbgetv (db, 0, "sta", sta, "chan", chan, "time", &time, NULL);
	complain (0, "too many matches (%ld) in calibration table for %s:%s @ %s - %s",
	nmatches, sta, chan, s = strydtime (time), t = strydtime (endtime));
	free (s);
	free (t);
	errors++;
	/* FALLTHRU */

      case 1:
	dbcalibration.record = (long) gettbl (tbl, 0);
	dbgetv (dbcalibration, 0,
		"sta", sta,
		"chan", chan,
		"calib", &calib,
		"calper", &calper,
		"units", units,
		NULL);
	*calperp = calper;

	for (j = 0; j < strlen (units); j++) {
	    units[j] = tolower (units[j]);
	}
	s = getarr (Segtype, units);
	if (s == 0) {
	    segtype = 'D';
	} else {
	    segtype = *s;
	}
	switch (segtype) {
	  case 'A':
	    calib *= SQR (calper / (2 * M_PI));
	    break;

	  case 'V':
	    calib *= calper / (2 * M_PI);
	    break;

	  default:
	    break;
	}

	ontime = epoch2str (time, "%Y/%m/%d %H:%M");
	if (endtime == null_endtime) {
	    offtime = strdup ("");
	} else {
	    offtime = epoch2str (endtime, "%Y/%m/%d %H:%M");
	}
	fprintf (stdout, "\nCAL2 %-5.5s %-3.3s %4.4s %-6.6s %15.8e %7.3f %11.5f %s %s\n",
	 sta, chan, aux, instype, calib, calper, samprate, ontime, offtime);
	free (ontime);
	free (offtime);
	break;
    }

    freetbl (tbl, 0);
    return errors;
}
double compute_ema (Slowness_vector *u, Slowness_Function_Output *ucalc, 
		Dbptr db, char *vmodel)
{
	Dbptr dbm, dbsv;
	static Tbl *matches;
	static Tbl *kmatch;   /* Used to hold keys for dbmatches.  */
	char *key;
	double velocity;
	static Hook *hook=0;
	long nmatches;
	char cphase;  /* store last char of phase name here */
	int name_len;
	int i; 
	double utotal, ema; 
	
	dbsv = dblookup(db,0,"stavel",0,0);
	dbm = dblookup(db,0,"stavel",0,"dbSCRATCH");
	dbputv(dbm,0,"sta",u->array->name,"phase",u->phase->name,"vmodel",vmodel,NULL );
	/* It seems to be necessary to explicitly define the match keys.  Using natural
	keys defined with null patterns for dbmatches did not work correctly. */
	kmatch = newtbl(0);
	key = strdup("sta");
	pushtbl(kmatch,key);
	key = strdup("phase");
	pushtbl(kmatch,key);
	key = strdup("vmodel");
	pushtbl(kmatch,key);

	dbmatches(dbm,dbsv,&kmatch,&kmatch,&hook,&matches);
	freetbl(kmatch,free);
	nmatches = maxtbl(matches);
	if(nmatches >= 1)
	{
		if(nmatches > 1) elog_log(0,"warning(compute_ema):  multiple records found in stavel table with same primary key\n");  
		dbsv.record = (long) gettbl(matches,0);
		dbgetv(dbsv,0,"velocity",&velocity,NULL );
	}
	else
	{
		/* No matches are found when we end up here.  Revert to default and 
		decide to us P or S velocity by hunting backward from the string
		looking for the first occurence of P or S*/
		if(!strcmp(u->phase->name,"Lg"))
			velocity = DEFAULT_VS;
		else
		{
			name_len = strlen(u->phase->name);
			velocity = DEFAULT_VS;  /* This is the default default */
			for(i=name_len-1;i>=0;i--)
			{
				cphase = u->phase->name[i];
				if(cphase == 'S'){
					velocity = DEFAULT_VS;
					break;
				}
				else if(cphase == 'P'){
					velocity = DEFAULT_VP;
					break;
				}
			}
			elog_log(0,"compute_ema:  no matching entry found in stavel table for station/phase/vmodel = %s/%s/%s\n"
			"Reverting to default surface velocity of %f\n",
				u->array->name,u->phase->name,vmodel,velocity);
		}
		freetbl(matches,0);
	}
	/* now the actual computation is pretty trivial */
	utotal = hypot(ucalc->ux,ucalc->uy);
	ema = asin(utotal*velocity);
	return(deg(ema));
}
int dbpmel_save_results(Dbptr db,
	int nevents,
	long *evid,
	Hypocenter *h,
	Tbl **ta,
	Location_options o,
	Pf *pf)
#endif
{
	Dbptr dbe,dbo,dba,dboe; 
	Dbptr dbes,dbos,dbas;
	Dbptr dbs;  /* subset view created by dblist2subset */
	Tbl *opat,*aspat,*aspat2;
	Tbl *matches=NULL,*match2;  /* output list of matching records */
	/* Dan Q advises it is wise to have a separate hook for each
	table passed through dbmatches */
	Hook *hooke=NULL,*hooko=NULL,*hooka=NULL,*hooka2=NULL;
	long prefor;
	int i,j;
	char *auth;
	Arrival *a;
	long orid;
	int nmatch;
	double **C;
	float emodel[4];
	char *alg=(char *)strdup("dbpmel");
	/* A collection of variables from assoc that have to be 
	copied.  Earlier algorithm using dbget raw on a subset 
	view failed so I have to copy by this mechanism */
	double belief;
	char timedef[2],slodef[2],azdef[2];
	double azres,slores,emares;
	Tbl *utbl;  


	/* This is needed as a stub for the predicted_error function.
	Because we don't support slowness vector data in pmel this 
	has to be an empty (NOT NULL) tbl list */
	utbl=newtbl(0);
	/* All of these are used repeatedly so we do one lookup at the
	top */
	dbe = dblookup(db,0,"event",0,0);
	dbo = dblookup(db,0,"origin",0,0);
	dba = dblookup(db,0,"assoc",0,0);
	dboe = dblookup(db,0,"origerr",0,0);
	dbes = dblookup(db,0,"event",0,0);
	dbos = dblookup(db,0,"origin",0,0);
	dbas = dblookup(db,0,"assoc",0,0);
	dbes.record = dbSCRATCH;
	dbos.record = dbSCRATCH;
	dbas.record = dbSCRATCH;

	opat = strtbl("orid",NULL );
	aspat = strtbl("orid",NULL );
	aspat2 = strtbl("arid","orid","sta",NULL );

	auth = pfget_string(pf,"author");

	C = dmatrix(0,3,0,3);
	/* outer loop over nevents */
	for(i=0;i<nevents;++i)
	{		
    		double conf;
		char *modtype;
		int model;
		double smajax,sminax,strike,sdepth,stime;
		int rc;

		/* Save nothing for events marked no use */
		if(h[i].used==0) continue;  
		/* Start with event table to get prefor */
		dbputv(dbes,0,"evid",evid[i],NULL );
		dbe.record = dbALL;
		if(dbmatches(dbes,dbe,0,0,&hooke,&matches)!=1)
			elog_complain(0,"WARNING:  multiple records in event table have evid=%ld.\nThis is a serious database problem that should be corrected.  Using first one found in table\n",
				evid[i]);
		dbe.record = (long)gettbl(matches,0);
		/* this is excessively paranoid, but better safe than sorry*/
		if(dbe.record<0)
		{
			elog_complain(0,"dbmatches invalid record %ld\nSkip saving evid %ld\n",
				dbe.record,evid[i]);
			continue;
		}
		dbgetv(dbe,0,"prefor",&prefor,NULL );
		freetbl(matches,0);
		matches=NULL;

		dbputv(dbos,0,"orid",prefor,NULL );
		dbo.record = dbALL;
		nmatch=dbmatches(dbos,dbo,&opat,&opat,&hooko,&matches);
		if(nmatch>1)
			elog_complain(0,"WARNING:  multiple records in origin table match orid=%ld.\nThis is a serious database problem that should be corrected.  Using first one found in table\n",
				prefor);
		else if(nmatch<=0)
		{
			elog_complain(0,"Cannot find matching origin\
record for orid %ld prefor of event %ld\n",
				prefor,evid[i]);
		}
		dbo.record = (long)gettbl(matches,0);
		if(dbget(dbo,0)==dbINVALID)
		{
			elog_complain(0,"dbget error on origin table for orid %ld\nData for evid %ld will not be saved\n",
				prefor,evid[i]);
			continue;
		}
		freetbl(matches,0);
		matches=NULL;

		/* origerr code cloned from dbgenloc */
		conf = pfget_double(pf,"confidence");
		modtype = pfget_string(pf,"ellipse_type");
     		if(modtype == NULL)
     		{
        		elog_complain(0,"parameter ellipse_type not defined--default to chi_square");
        		model = CHI_SQUARE;
     		}
     		else if( strcmp( modtype, "chi_square" ) == 0 )
     		{
        		model = CHI_SQUARE;
     		}
     		else if( strcmp( modtype, "F_dist" ) == 0 )
     		{
        		model = F_DIST;
     		}
     		else
     		{
        		elog_complain(0, "parameter ellipse_type %s incorrect (must be F_dist or chi_square)--default to chi_square", modtype );
        		model = CHI_SQUARE;
     		}
		predicted_errors(h[i],ta[i],utbl,o,C,emodel);
    		rc = project_covariance( C, model, &conf,
                             h[i].rms_weighted, h[i].degrees_of_freedom,
                             &smajax, &sminax, &strike, &sdepth, &stime );

    		if( rc != 0 )
    		{
        		elog_complain(0, "project_covariance failed." );
        		smajax = -1;
        		sminax = -1;
        		strike = -1;
        		sdepth = -1;
        		stime = -1;
        		conf = 0.;
    		}
		orid = dbnextid(dbo,"orid");

		if(dbaddv(dboe,0,
                	"orid", orid,
                	"sxx",C[0][0],
                	"syy",C[1][1],
                	"szz",C[2][2],
                	"stt",C[3][3],
                	"sxy",C[0][1],
                	"sxz",C[0][2],
                	"syz",C[1][2],
                	"stx",C[0][3],
                	"sty",C[1][3],
                	"stz",C[2][3],
                	"sdobs", h[i].rms_raw,
                	"smajax", smajax,
                	"sminax", sminax,
                	"strike", strike,
                	"sdepth", sdepth,
                	"stime", stime,
                	"conf", conf,
                		NULL ) < 0 )
		{
			elog_complain(0,"Problem adding origerr record for evid %ld\n",
				evid[i]);
		} 


		/* This edits the scratch record and adds it to the end 
		of the origin table */
		dbputv(dbos,0,"orid",orid,
				"lat",h[i].lat,
				"lon",h[i].lon,
				"depth",h[i].z,
				"time",h[i].time,
				"algorithm",alg,
				"auth",auth,NULL );

/*
		printf("Added to origin table: %8d %9.4lf %9.4lf %9.4lf"
			" %17.5lf %-15s %-15s\n", orid, h[i].lat, 
			h[i].lon, h[i].z, h[i].time, alg, auth);
*/

		if(dbadd(dbo,0)==dbINVALID)
			elog_complain(0,"dbadd error for origin table\
for new orid %ld of evid %ld\n",
				orid,evid[i]);
		/* The assoc tables is much more complex.  Rather than
		do a row for row match against each arrival in ta, I
		use a staged reduction.  Than is I first match the full
		assoc table against orid=prefor only to get a full list
		of records for that event.  We then run matches against
		the smaller table for sta/phase in the arrival list.
		Untested but from previous experience with dbmatches on
		large tables I'm fairly sure this is a necessary 
		complication to keep this from be very slow*/
		dbputv(dbas,0,"orid",prefor,NULL );
		dba.record = dbALL;
		nmatch=dbmatches(dbas,dba,&aspat,&aspat,&hooka,&matches);
		if(nmatch<=0)
		{
			elog_complain(0,"No assoc records for orid %ld\
found\nFail to create new assoc records for orid %ld\n",
				prefor,orid);
			freetbl(matches,0);
			continue;
		}