예제 #1
0
/* This routines cautiously saves the emodel vector.  It is cautious
because the emodel table is not part of the css3.0 schema.  If it
cannot find info on the emodel table, it issues an error and returns.
Otherwise, it will save the emodel vector to this special table.
Author:  Gary L. Pavlis
Written: June 29, 1998 */
int save_emodel(int orid, float *emodel, Dbptr db)
{
	Dbptr dbemod;  

	dbemod = dblookup(db, 0,"emodel",0,0);
	if(dbemod.table == dbINVALID)
	{
		elog_log(0,"emodel table not defined for output database\nAdd genloc mods\n");
		return(1);
	}
	else
	{
		if(dbaddv(dbemod,0,
			"orid",orid,
			"emodelx",emodel[0],
			"emodely",emodel[1],
			"emodelz",emodel[2],
			"emodelt",emodel[3],
				NULL ) == dbINVALID)
		{
			elog_log(0,"dbaddv error for emodel table\n");
			return(-1);
		}
	}
	return(0);
}
/*This function adds a single row to the origerr table for this event.

arguments:
	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(long orid, Hypocenter h, double **C, Dbptr dbo)
{
	double sdobs; 
	double lddate;
	/* Intentionally ignored: smajax,sminax,strike,sdepth,stime,
					conf,commid */

	dbo = dblookup(dbo,0,"origerr",0,0);

	/* 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;
	lddate = std_now();
	if(dbaddv(dbo,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,
                "lddate",lddate,
			NULL) == dbINVALID)
	{
		elog_die(1,"save_origerr: dbaddv error writing origerr record for orid %ld\n",
				orid);
	}
}
예제 #3
0
void save_run_parameters(Dbptr db,Pf *pf)
{
	char *dir,*dfile;
	char filename[512];
	char *vm,*vm3d;
	int ierr;
	
	dir = pfget_string(pf,"pmelrun_archive_directory");
	if(dir==NULL)elog_die(0,"Parameter pmelrun_archive_directory not in parameter file\n");
	if(makedir(dir))
		elog_die(0,"makedir failed on directory %s\n",dir);
	dfile = pfget_string(pf,"pmel_run_name");

	
	vm = pfget_string(pf,"travel_time_model");
	vm3d=pfget_string(pf,"3Dreference_model");
	if( (vm==NULL) || (vm3d==NULL) )
		elog_die(0,"Missing required velocity model definitions\nCheck parameters travel_time model and 3Dreference_model\n");
	db = dblookup(db,0,"pmelruns",0,0);
	ierr=dbaddv(db,0,"pmelrun",dfile,
		"vmodel",vm,
		"vmodel3d",vm3d,
		"dir",dir,
		"dfile",dfile,0);
	if(ierr < 0) elog_die(0,
		   "dbaddv error on pmelrun table\nVerify schema extensions for dbpmel and that the pmel_run_name parameter is unique\n");

	strcpy(filename,dir);
	strcat(filename,"/");
	strcat(filename,dfile);
	if(pfwrite(filename,pf))
		elog_die(0,"pfwrite error for file %s\n",filename);
}
/* Changed to int from void by JN in order to return evid. */
long save_event(Dbptr dbi, long is, long ie, long orid, Dbptr dbo)

{
	/* these are variables in dbi copied to dbo */
	long evid;
	char evname[16];
	
	/*altered in output by this program */
	long prefor;
	char auth[20];
	double lddate;

	/* intentionally ignored:  commid */

	dbo = dblookup(dbo,0,"event",0,0);
	dbi.record = is;
	if( dbgetv(dbi,0,
		"event.evid",&evid,
		"event.evname",evname,	
				NULL) == dbINVALID)
	{
		elog_die(1,"save_event: dbgetv error reading event fields of input view at record %ld\n",
				is);
	}
	prefor = orid;
	my_username(auth);
	lddate = std_now();
	if(dbaddv(dbo,0,
                "evid",evid,
		"evname",evname,
		"prefor",prefor,
                "auth",auth,
                "lddate",lddate,
			NULL ) == dbINVALID)
	{
		elog_die(1,"save_event: dbaddv error writing event record for orid %ld\n",
				orid);
	}
        /* Added by JN */
	return(evid);
}
예제 #5
0
/* This routine saves array average amplitude estimates in a table
called mwavgamp.  This routine always adds one and only one record.

arguments:

array - array name assigned to the group of stations used to produce
	this set of averages
evid - css3.0 event id
bankid - multiwavelet group id 
phase - phase name as in css3.0
fc - center frequency (in Hz) of the wavelets used
t0 - start time at reference station
twin - length of analysis time window relative to t0
mwamp - computed array average amplitude
erramp - estimate of error in mwamp 
	Note: both mwap and erramp are log10 values derived from nm/s
	converted trace data (assumed).
ndgf - degrees of freedom in estimate of mwamp
db - pointer to output database 

Author:  G Pavlis
Written:  March 2000
*/
int MWdb_save_avgamp(char *array,
	int evid, 
	int bankid,
	char *phase,
	double fc,
	double t0,
	double twin,
	double mwamp,
	double erramp,
	int ndgf,
	Dbptr db)
{

	db = dblookup(db,0,"mwavgamp",0,0);

	/* Note algorithm and ampcomp are frozen here.   */

	if( dbaddv(db,0,"sta",array,
		"evid",evid,
		"bankid",bankid,
		"phase", phase,
		"fc",fc,
		"ampcomp",AMPCOMP,
		"time",t0,
		"twin",twin,
		"mwamp",mwamp,
		"erramp",erramp,
		"ndgf",ndgf,
		"algorithm","mwap",0) < 0) 
	{
		elog_notify(0,
			"dbaddv error for mwavgamp table on evid %d with  fc=%lf\n",
				evid,fc);
		return(-1);
	}
	else
		return(0);
}
/* This function computes the attributes of the predarr table.  
This is seriously complicated by the fact that the timedef and 
slowdef attributes in the css3.0 schema allow independently turning
off time and slowness residuals.  The way we solve this here is to
first save results for all the entries in the Arrival tbl keeping
a temporary list of all the arid values found in the Arrival tbl.  
We then use a stupid linear search algorithm against each arid found
in the Slowness_vector table and only compute a new predarr row if
the arid found for that Slowness vector did not match any found in arid.
The linear search is acceptable here under an assumption that arrival
data will outnumber slowness vector measurements in most locations. 

This algorithm looks for the stavel table that is also defined in the
takeoff schema extensions.  This table defines surface velocities to 
use in computing emergence angles (ema).  If an entry is not found
for a given phase in stavel, the program tries to decide if this is a
P or S phase (by looking at the last character in the phase name) and 
using a default (hardwired below).  This will generate a complain error
because the values in predarr are not necessarily consistent with vmodel
in this situation.

arguments:
	db - database to save results to
	atbl - Tbl of Arrival structures used in genloc
	utbl - Tbl of Slowness_vector structures comparable to a
	h - hypocenter estimate to be used to compute predarr rows
	orid - orid database id assigned to this solution.
	vmodel - name of velocity model being used (key of stavel)

Returns 0 for success, anything else indicates and error.  A positive
return indicates the number of warning messages issued.  A negative
return indicates nothing was written because the predarr table could
not be written due to either:  (1) undefined in the schema or (2) 
table is not writeable. 
Author:  G Pavlis
*/
int save_predarr( Dbptr db,  Tbl *atbl, Tbl *utbl, 
	Hypocenter h, int orid, char *vmodel)
{
	int natimes;
	int nslow;
	long *allarids;
	int errors=0;

	Arrival *atimes;
	Arrival a;
	Station station;
	Slowness_vector *slow;
	Slowness_vector u;
	Seismic_Array sta_array;
	
	Travel_Time_Function_Output tto;
	Slowness_Function_Output u_calc;
	/* These are the fields computed here and saved in predarr */
	double time, utotal, seaz, esaz, ema, dip;

	int stavel_ok;  /* set to 1 if stavel is found valid.  Function
		returns immediately if the predarr table is not defined */

	double ema_null=-1.0;
	int i,k;

	if(dbtable_invalid(db,"predarr"))
	{
		elog_log(0,"predarr table not defined in schema for this database\n");
		return(-1);
	}
	if(dbtable_invalid(db,"stavel"))
	{
		elog_log(0,"stavel table is not defined.  Using defaults for all stations and phases\n");
		stavel_ok = 0;
	}
	else if(dbtable_empty(db,"stavel"))
	{
		stavel_ok=0;  /* do this silently */
	}
	else 
	{
		stavel_ok = 1;
		/* This is the correct way to find the null value for a field*/
		db = dblookup(db,0,"predarr",0,0);
		db.record = dbNULL;
		dbgetv(db,0,"ema",&ema_null,NULL );
	}

	natimes = maxtbl(atbl);
	nslow = maxtbl(utbl);
	if(natimes > 0)
	{
		allarids = (long *)calloc(natimes,sizeof(long));
		if(allarids == NULL) elog_die(0,"save_predarr cannot alloc %d long integers\n",
					natimes);
	}
	/* These quantities need to be explicitly initialized at the top
	of this loop.  They stay fixed for the whole loop.  Only the
	sta_array set really matters. */
	u.ux = 0.0;
	u.uy = 0.0;
	u.array = &sta_array;
	db = dblookup(db,0,"predarr",0,0);

	for(i=0;i<natimes;++i)
	{
		atimes = (Arrival *) gettbl(atbl,i);
		/* discard - phases as predarr makes no sense for them */
		if(strstr(atimes->phase->name,"-")!=NULL) continue;
		allarids[i] = atimes->arid;
		tto = calculate_travel_time(*atimes,h,ALL);
		if(tto.time == TIME_INVALID)
		{
			elog_log(0,"save_predarr failed to compute predicted arrival times for station %s and phase %s\n", 
				atimes->sta->name, atimes->phase->name);
			++errors;
			continue;
		}
		time = h.time + tto.time;
		dip = compute_dip(tto);
		esaz = compute_esaz(tto);

		/* This loads a fake slowness vector for each station.
		Note this is different from the location code and could
		fail in some situations when the location computation 
		did not.   In those situations, slow, ema, and esaz
		cannot be computed.  */
		u.arid = atimes->arid;
		strcpy(u.array->name,atimes->sta->name);
		u.array->lat = atimes->sta->lat;
		u.array->lon = atimes->sta->lon;
		u.array->elev = atimes->sta->elev;
		u.phase = atimes->phase;
		
		u_calc = calculate_slowness_vector(u,h,RESIDUALS_ONLY);
		if(u_calc.ux == SLOWNESS_INVALID)
		{
			elog_log(0,"predarr failed to compute slowness vector for station %s and phase %s\n",
				atimes->sta->name, atimes->phase->name);
			++errors;
			if(dbaddv(db,0,
				"arid",atimes->arid,
				"orid",orid,
				"time",time,
				"esaz",esaz,
				"dip",dip,
				NULL ) == dbINVALID)
			{
				elog_log(0,"dbaddv on predarr table for station %s and phase %s\n",
					atimes->sta->name, atimes->phase->name);
				++errors;
			}
				
		}
		else
		{
			utotal = hypot(u_calc.ux,u_calc.uy);
			/* css3.0 stores slowness is s/deg so we have
			to convert */
			utotal *= KMPERDEG;
			seaz = compute_seaz(u_calc);
			if(stavel_ok) ema = compute_ema(&u,&u_calc,db,vmodel);
			if(ema < 0.0) ema = ema_null;
			if(dbaddv(db,0,
				"arid",atimes->arid,
				"orid",orid,
				"time",time,
				"slow",utotal,
				"seaz",seaz,
				"ema", ema,
				"esaz",esaz,
				"dip",dip,
				NULL ) == dbINVALID)
			{
				elog_log(0,"dbaddv on predarr table for station %s and phase %s\n",
					atimes->sta->name, atimes->phase->name);
				++errors;
			}
		}

	}
	/* Nww we have to hunt for slowness measurements that have not
	travel time computed above.  Here we used a dumb linear search
	against arid for reasons give above.  The rest of the algorithm
	closely parallels the above loop, except the role of arrival 
	and slowness are reversed.  */
	a.time = 0.0;
	a.sta = &station;
	for(i=0;i<nslow;i++)
	{
		slow = (Slowness_vector *) gettbl(utbl,i);
		for(k=0;k<natimes;k++) 
			if(allarids[k] == slow->arid) break;
		if(k>=natimes)
		{
		/* Only when the above search fails will we actually do anything 
		in this loop */
			a.arid = slow->arid;
			strcpy(a.sta->name,slow->array->name);
			a.sta->lat = slow->array->lat;
			a.sta->lon = slow->array->lon;
			a.sta->elev = slow->array->elev;
			a.phase = slow->phase;
			tto = calculate_travel_time(a,h,ALL);
			if(tto.time == TIME_INVALID)
			{
				elog_log(0,"save_predarr failed to compute predicted arrival times for station %s and phase %s\n", 
					atimes->sta->name, atimes->phase->name);
				++errors;
				continue;
			}
			time = h.time + tto.time;
			dip = compute_dip(tto);
					
			u_calc = calculate_slowness_vector(*slow,h,RESIDUALS_ONLY);
			if(u_calc.ux == SLOWNESS_INVALID)
			{
				elog_log(0,"predarr failed to compute slowness vector for station %s and phase %s\n",
					atimes->sta->name, atimes->phase->name);
				++errors;
				if(dbaddv(db,0,
					"arid",atimes->arid,
					"orid",orid,
					"time",time,
					"esaz",esaz,
					"dip",dip,
					NULL ) == dbINVALID)
				{
				    elog_log(0,"dbaddv on predarr table for station %s and phase %s\n",
					atimes->sta->name, atimes->phase->name);
				    ++errors;
				}
				
			}
			else
			{
				utotal = hypot(u_calc.ux,u_calc.uy);
				utotal *= KMPERDEG;
				seaz = compute_seaz(u_calc);
				if(stavel_ok) ema = compute_ema(&u,&u_calc,db,vmodel);
				if(ema < 0.0) ema = ema_null;
				if(dbaddv(db,0,
					"arid",atimes->arid,
					"orid",orid,
					"time",time,
					"slow",utotal,
					"seaz",seaz,
					"ema", ema,
					"esaz",esaz,
					"dip",dip,
					NULL ) == dbINVALID)
				{
				    elog_log(0,"dbaddv on predarr table for station %s and phase %s\n",
					atimes->sta->name, atimes->phase->name);
				    ++errors;
				}
			}
		}
	}
	free(allarids);
	return(errors);
}
int
main (int argc, char **argv)
{
    int             c,
                    verbose = 0,
		    errflg = 0;


	char *dbinname=malloc(1024);
	char *dboutname=malloc(1024);
	Point *poly;
	double lat,lon;
	char *subset_expr=NULL;
	char *name=malloc(100);
	long nregions, nvertices;
	Tbl *sortkeys;
			
	Dbptr dbin,dbout,dbi,dbo,dbs;
	long i,from,to,nv;
	long vertex;
	
    elog_init ( argc, argv ) ; 
    while ((c = getopt (argc, argv, "s:vV")) != -1) {
	switch (c) {

	case 's':
	    subset_expr=optarg;
	    break;
	case 'v':
	    verbose++ ;
	    break;

	case 'V':
	    usage ();
	    break;

	case '?':
	    errflg++;
	    break ;
	}
    }

    if ((errflg) || argc < 3)
	usage ();

	dbinname = argv[optind++];
	dboutname= argv[optind++];

	if (dbopen(dbinname,"r",&dbin)) {
		elog_die(1,"cannot open database %s",dbinname);
	}
	dbi=dblookup(dbin,0,"polygon",0,0);
	if (subset_expr) {
		dbi=dbsubset(dbi,subset_expr,NULL);
	}

	

	sortkeys=newtbl(1);
	pushtbl(sortkeys,"pname");
	
	dbs=dbsort(dbi,sortkeys,0,"sorted");
	dbquery(dbs,dbRECORD_COUNT,&nregions);
	if (nregions <1) {
		elog_die(0,"table regions seems to be empty (or not present)");
	}
	
	if (verbose) elog_notify(0,"creating database descriptor %s",dboutname);
	
	if (dbcreate(dboutname,"places1.2",0,0,0)) {
		elog_die(1,"cannot create database %s",dboutname);
	}
	dbopen(dboutname,"r+",&dbout);
	dbo=dblookup(dbout,0,"regions",0,0);
	
	for (i=0; i< nregions; i++) {
		dbs.record=i;
		dbgetv(dbs,0,"pname",name,NULL );
		nvertices=readPolygon(dbs,&poly);
		for (nv=0;nv < nvertices;nv++) {
			lat=poly[nv].lat;
			lon=poly[nv].lon;
			dbaddv(dbo,0,
					"regname",name,
					"vertex",nv,
					"lat",lat,"lon",lon,
					NULL );
		}
		free(poly);
	}
	dbclose(dbo);
	/*
				*/
    return 0;
}
long save_origin(Dbptr dbi, long is, long ie, int depth_fixed,
	Hypocenter h, Dbptr dbo)
{
	long orid;

	/* These are parameters copied from input db -- names = css names */
	long evid;
	long jdate;
	long grn;
	long srn;
	char etype[8];
	double mb;
	long mbid;
	double ms;
	long msid;
	double ml;
	long mlid;
	/* These obtained from this solution */

	long nass;
	long ndef;
	char dtype[2];
	char algorithm[16]="genloc-nlls";
	char auth[20];
	double lddate;
	

	/* these are intentionally left null: ndp,depdp,commid*/


	/* set but obtained directly from hypo structure 
	lat, lon, depth, time */

	dbo = dblookup(dbo,0,"origin",0,0);
	
	/* Grab what we need from the input db for copying.  Note
	that because the joins used here, each of the input db
	records have the same origin entries.  Thus, we just fetch
	stuff from row is.  */
	dbi.record = is;
	if( dbgetv(dbi,0,
		"origin.evid", &evid,
		"origin.jdate", &jdate,
		"origin.grn", &grn,
		"origin.srn", &srn,
		"origin.etype", etype,
		"origin.mb", &mb,
		"origin.mbid", &mbid,
		"origin.ms", &ms,
		"origin.msid", &msid,
		"origin.ml", &ml,
		"origin.mlid", &mlid,
				NULL) == dbINVALID)
	{
		elog_die(1,"save_origin: dbgetv error reading origin fields of input view at record %ld\n",
				is);
	}
	nass = ie - is;
	/* ndef is potentially wrong by this calculation.  We set ndef 
	from the number of degrees of freedom in the solution + npar
	where npar is 3 when depth is fixed and 4 otherwise.  This does
	not match the real definition of ndef, especially when array 
	data are used because each arrival then then has 3 data points
	used to constrain the solution.  These is either an error in 
	my (glp) understanding of the css3.0 schema or a flaw in its 
	design.*/
	if(depth_fixed)
	{
		ndef = h.degrees_of_freedom + 3;
		strcpy(dtype,"r");
	}
	else
	{
		ndef = h.degrees_of_freedom + 4;
		strcpy(dtype,"f");
	}
	my_username(auth);
	lddate = std_now();
	orid = dbnextid(dbo,"orid");
	if(dbaddv(dbo,0,
                "lat",h.lat,
                "lon",h.lon,
                "depth",h.z,
                "time",h.time,
                "orid",orid,
                "evid",evid,
                "jdate",jdate,
                "nass",nass,
                "ndef",ndef,
                "grn",grn,
                "srn",srn,
                "etype",etype,
                "dtype",dtype,
                "mb",mb,
                "mbid",mbid,
                "ms",ms,
                "msid",msid,
                "ml",ml,
                "mlid",mlid,
                "algorithm",algorithm,
                "auth",auth,
                "lddate",lddate,
			NULL) == dbINVALID)
	{
		elog_die(1,"save_origin: dbaddv error writing orid %ld\n",
				orid);
	}
	return(orid);
}
void save_assoc(Dbptr dbi, long is, long ie, long orid, char *vmodel,
	Tbl *residual,Hypocenter h, Dbptr dbo)
{
	/* These fields are copied from input assoc table */
	long arid;
	char sta[8];
	char phase[10];
	double belief;
	/* These fields are set here */
	double delta;
	double seaz;
	double esaz;
	double timeres;
	double azres;
	double slores;
	double lddate;
	double wgt;
	char timedef[2],slodef[2], azdef[2];
	
	/* intentionally ignored:  emares, commid */


	/* passed through arg list;  orid*/

	/* We use this to produce a keyed arr list of the residual 
	list passed into here as a Tbl */

	Arr *residual_array;
	long i;
	char key[40]; 

	double r, w, reswt,uxresid, uyresid;
	double stalat, stalon; 
	double ux, uy, azimuth;
	double u,phi;  /* polar form of measured slowness vector */
	double duphi;

	dbo = dblookup(dbo,0,"assoc",0,0);
	lddate = std_now();

	/* We build an associate array for the residual tbl keying
	each entry with a sta/phase/type key  where type is 
	set in ggnloc as time, ux, or uy.  This complication is
	needed to sort out array residuals. */
	residual_array = newarr(0);
	for(i=0;i<maxtbl(residual);++i)
	{
		char *s;
		char keysta[10], keyphase[10], keytype[5];
		s = (char *)gettbl(residual,i);
		sscanf(s,"%s %s %s",keysta,keyphase,keytype);
		/* handle S-P case by having the same residual mapped
		to each half of - phase pair */
		if(strchr(keyphase,'-'))
		{
			char *phase1,*phase2;
			/* algorithm to split phase names cloned from dbgenloc */
			phase1 = strdup(keyphase);
			phase2= strchr(phase1,'-');
			*phase2 = '\0';
			++phase2;
			sprintf(key,"%s %s %s",keysta,phase1,keytype);
			setarr(residual_array,key,s);
                        sprintf(key,"%s %s %s",keysta,phase2,keytype);
                        setarr(residual_array,key,s);
			free(phase1);
		}
		else
		{
			/* normal phases are one to one */
			sprintf(key,"%s %s %s",keysta,keyphase,keytype);
			setarr(residual_array,key,s);
		}
	}
		

	for(dbi.record=is;dbi.record < ie;++dbi.record)
	{
		char *time_residual_record;
		char *ux_residual_record,*uy_residual_record;
		if( dbgetv(dbi,0,
      	    		"assoc.arid",&arid,
          		"assoc.sta",sta,
          		"assoc.phase",phase,
          		"assoc.belief",&belief,
				NULL) == dbINVALID)
		{
		  elog_die(1,"save_assoc: dbgetv error reading assoc fields of input view at record %ld\n",
				dbi.record);
		}
		if( dbgetv(dbi,0,
			"site.lat",&stalat,
			"site.lon",&stalon,
				NULL) == dbINVALID)
		{
		  elog_die(1,"save_assoc: dbgetv error reading site fields of input view at record %ld\n",
				dbi.record);
		}
		/* Find the time residual record for this arrival */
		sprintf(key,"%s %s time",sta,phase);
		time_residual_record = (char *)getarr(residual_array,key);
		if(time_residual_record == NULL)
		{
			elog_complain(1,"save_assoc:  getarr mismatch for key %s\nCannot set residual\n",key);
			timeres = TIMENULL;
			wgt = 0.0;
			strcpy(timedef,"n");
		}
		else
		{
                        /* Changed by JN to avoid gcc warning */
			/* sscanf(time_residual_record,"%*s%*s%*s%*lg%lg%lg%lg", */
			sscanf(time_residual_record,"%*s%*s%*s%*g%lg%lg%lg",
				&r,&w,&reswt);
			timeres = r;
			wgt = w*reswt;
			strcpy(timedef,"d");
		}

		sprintf(key,"%s %s ux",sta,phase);		
		ux_residual_record = (char *)getarr(residual_array,key);
		sprintf(key,"%s %s uy",sta,phase);
		uy_residual_record = (char *)getarr(residual_array,key);
                /* Corrected by JN
		if( (ux_residual_record == NULL) 
			|| (ux_residual_record == NULL))
                */
		if( (ux_residual_record == NULL) 
			|| (uy_residual_record == NULL))
		{
			/* This trick is not documented.  By setting 
			the record filed to dbNULL, and then calling dbgetv
			each of the fields will be set to their NULL value */
			dbo.record = dbNULL;
			dbgetv(dbo,0,"azres",&azres,"slores",&slores,NULL );
			strcpy(azdef,"n");
			strcpy(slodef,"n");
		}
		else
		{
		/* This gets nasty because we have to convert to polar 
		coordinates from ux, uy components */
			sscanf(ux_residual_record,"%*s%*s%*s%*g%lg",&uxresid);

			sscanf(uy_residual_record,"%*s%*s%*s%*g%lg",&uyresid);
		/* We fetch the measured slowness vector to convert */
			if( dbgetv(dbi,0,
				"arrival.slow",&u,
				"arrival.azimuth",&phi,
					NULL) == dbINVALID)
			{
		  	  elog_die(1,"save_assoc: dbgetv error reading arrival fields of input view at record %ld\n",
				dbi.record);
			}
			/* css stores slowness in s/deg, but we use
			s/km internally here so we have to convert */

			slores = sqrt(uxresid*uxresid+uyresid*uyresid);
			slores *= KMPERDEG;

			/* this is the azimuth term */
			u /= KMPERDEG;
			duphi = ux*cos(rad(azimuth)) - uy*sin(rad(azimuth));
			duphi /= u;
			azres = deg(duphi);
			strcpy(azdef,"d");
			strcpy(slodef,"d");

		}
		dist(rad(h.lat),rad(h.lon),rad(stalat),rad(stalon),
				&delta,&esaz);
		dist(rad(stalat),rad(stalon),rad(h.lat),rad(h.lon),
				&delta,&seaz);
		delta = deg(delta);
		seaz = deg(seaz);
		esaz = deg(esaz);
			
		if(dbaddv(dbo,0,
                        "arid",arid,
                        "orid",orid,
                        "sta",sta,
                        "phase",phase,
                        "belief",belief,
                        "delta",delta,
                        "seaz",seaz,
                        "esaz",esaz,
                        "timeres",timeres,
                        "timedef",timedef,
                        "azres",azres,
                        "azdef",azdef,
                        "slores",slores,
                        "slodef",slodef,
                        "wgt",wgt,
                        "vmodel",vmodel,
                        "lddate",lddate,
			NULL ) == dbINVALID)
		{
			elog_die(1,"save_assoc: dbaddv error writing assoc record for arid %ld\n",
				arid);
		}
	}
	freearr(residual_array,0);
}
예제 #10
0
int main(int argc, char **argv)
{
	Dbptr db;
	char *dbname;
	Pf *pf;
	char *progname="Xphase2db";
	char line[1024];
	int year,jday,hour,min;
	double sec;
	double twin,deltim;
	int other1,other2,pol;
	char fname[512];
	char tstring[100];
	double time;
	char *seperators;  /* holds seperators passed to strtok*/
	int ista,ichan;  /* token positions of station and channel 
			strings */
	char *phase;
	char *fm,*up="uc",*down="dr";
	char *token;
	char *sta,*chan;
	int i,j;


	if(argc < 2) die(0,"usage:  %s dbout [-phase x]\n",progname);
	if(argc == 4)
	{
		if(!strcmp(argv[2],"-phase"))
			die(0,"usage:  %s dbout [-phase x]\n",progname);
		phase = argv[3];
	}
	else
		phase = strdup("P");
	dbname = argv[1];
	if(pfread(progname,&pf))
		die(0,"Failure reading parameter file %s.pf\n",
				progname);
	if(dbopen(dbname,"r+",&db) == dbINVALID)
		die(0,"dbopen failure for database %s\n",dbname);
	db = dblookup(db,0,"arrival",0,0);
	seperators = pfget_string(pf,"seperators");
	if(seperators == NULL) die(0,"required parameter separators no in parameter file\n");
	ista = pfget_int(pf,"station_token_number");
	ichan = pfget_int(pf,"chan_token_number");

	while( fgets(line,1024,stdin) != NULL)
	{
		sscanf(line,"%d%d%d%d%lf%d%lf%lf%d%d%s",
			&year,&jday,&hour,&min,
			&sec,&other1,&twin,&deltim,&other2,&pol,fname);

		if(pol<0)
			fm = down;
		else
			fm = up;
		sprintf(tstring,"%4d%3d:%2d:%2d:%7.4lf",year,jday,hour,min,sec);
		/* There is a way to avoid this in formats for sprintf, but
		I'll be damned if I can find it.  Easier to do by brute force*/
		for(j=0;j<strlen(tstring);++j) 
			if(tstring[j]==' ')tstring[j]='0';
		time = str2epoch(tstring);
		token = strtok(fname,seperators);
		i=1;
		while(token != NULL)
		{
			if(i == ista)  sta = token;
			if(i == ichan) chan = token;
			++i;
			token = strtok(NULL,seperators);
		}
		dbaddv(db,0,
			"sta",sta,
			"chan",chan,
			"time",time,
			"deltim",deltim,
			"iphase",phase,
			"fm",fm,
			"auth","Xphase",
			0);
	}
}
예제 #11
0
/* This function saves particle motion parameter estimates to a extension
table called mwpm.  Individual station estimates and an array average
estimate are all saved in the same table.  they can be sorted out through
the key field pmtype set to "ss" for single station and "aa" for array average.

Arguments:

array - array name used as tag on the array average row
evid - css3.0 event id
bankid - multiwavelet bank id tag
phase - seismic phase name as in css3.0
fc - center frequency of band in hz.
t0 - start time at reference station for particle motion analysis
twin - length of analysis time window relative to t0
g - MWgather structure for this band.  The routine loops through
	the list defined by this complicated structure.
moveout - moveout vector.  Elements of moveout are a parallel array
	to g->sta and related quanties in the gather structure.
pmarr - particle motion structures array indexed by station name
pmerrarr - particle motion error structure array indexed by station name
pmavg - particle motion ellipse parameters for array average
pmaerr - error parameters associated with pmavg
db - output database

Author:  G Pavlis
Written:  march 2000
*/
int MWdb_save_pm(
	char *array,
	int evid, 
	int bankid,
	char *phase,
	double fc,
	double t0,
	double twin,
	MWgather *g,
	double *moveout,
	Arr *pmarr,
	Arr *pmerrarr,
	Particle_Motion_Ellipse *pmavg,
	Particle_Motion_Error *pmaerr,
	Dbptr db)
{

	char *sta;
	int i;
	Particle_Motion_Ellipse *pm;
	Particle_Motion_Error *pmerr;
	int errcount=0;
	double time;
	int nsta;
	Spherical_Coordinate scoor;
	double majaz, majema, minaz, minema;

	db = dblookup(db,0,"mwpm",0,0);

	nsta = g->nsta;

	/* We look through the whole gather quietly skipping entries
	flagged bad with a null pointer */
	for(i=0;i<nsta;++i)
	{
                pm = (Particle_Motion_Ellipse *)getarr(pmarr,g->sta[i]->sta);
		pmerr = (Particle_Motion_Error *)getarr(pmerrarr,g->sta[i]->sta);
		/* Silently skip null entries because autoediting makes
		this happen often.  We could trap the condition where
		one of these pointers is null and the other is not, but
		this should not happen so I skip it.*/
		if( (pm != NULL) && (pmerr != NULL) )
                {
			/* We have to correct the start time for moveout.
			This asssumes the moveout vector has the current 
			best estimate */
			time = t0 + moveout[i];
			/* The pm structure stores the major and minor axes
			as unit vectors.  It is more compact and more 
			intuitive to store these quantities in spherical coord
			form (az and ema) in the database so we have to convert
			them.  NOte also all angles are stored internally
			in radians and need to be converted to degrees with
			the deg for external consumption. */
			scoor = unit_vector_to_spherical(pm->major);
			/* Note azimuth in geographical coordinates is
			not the same as the phi angle in spherical coordinates
			used here.  It is 90 - phi */
			majaz = 90.0 - deg(scoor.phi);
			majema = deg(scoor.theta);
			scoor = unit_vector_to_spherical(pm->minor);
			minaz = 90.0 - deg(scoor.phi);
			minema = deg(scoor.theta);
			if( dbaddv(db,0,
				"sta",g->sta[i]->sta,
				"bankid",bankid,
				"fc",fc,
				"phase",phase,
				"evid",evid,
				"time",time,
				"twin",twin,
				"pmtype","ss",
				"majoraz",majaz,
				"majorema",majema,
				"minoraz",minaz,
				"minorema",minema,
				"rect",pm->rectilinearity,
				"errmajaz",deg(pmerr->dphi_major),
				"errmajema",deg(pmerr->dtheta_major),
				"errminaz",deg(pmerr->dphi_minor),
				"errminema",deg(pmerr->dtheta_minor),
				"errrect",pmerr->delta_rect,
				"majndgf",pmerr->ndgf_major,
				"minndgf",pmerr->ndgf_minor,
				"rectndgf",pmerr->ndgf_rect,
				"algorithm","mwap",0) < 0) 
			{
				elog_notify(0,"dbaddv error in mwpm table for station %s\n",sta);

				++errcount;
			}
		}
	}
	/* now we add a row for the array average.  This is flagged only
	by the pmtype field.  */
	scoor = unit_vector_to_spherical(pmavg->major);
	majaz = 90.0 - deg(scoor.phi);
	majema = deg(scoor.theta);
	scoor = unit_vector_to_spherical(pmavg->minor);
	minaz = 90.0 - deg(scoor.phi);
	minema = deg(scoor.theta);
	if( dbaddv(db,0,
		"sta",array,
		"bankid",bankid,
		"fc",fc,
		"phase",phase,
		"evid",evid,
		"time",time,
		"twin",twin,
		"pmtype","aa",
		"majoraz",majaz,
		"majorema",majema,
		"minoraz",minaz,
		"minorema",minema,
		"rect",pmavg->rectilinearity,
		"errmajaz",deg(pmaerr->dphi_major),
		"errmajema",deg(pmaerr->dtheta_major),
		"errminaz",deg(pmaerr->dphi_minor),
		"errminema",deg(pmaerr->dtheta_minor),
		"errrect",pmaerr->delta_rect,
		"majndgf",pmaerr->ndgf_major,
		"minndgf",pmaerr->ndgf_minor,
		"rectndgf",pmaerr->ndgf_rect,
	   "algorithm","mwap",0) < 0) 
	{
		elog_notify(0,"dbaddv error saving array average particle motion parameters in mwpm table for evid %d\n",
			evid);
		++errcount;
	}
	return(errcount);
}
예제 #12
0
/* This function creates the mwslow table output of mwap.
This table hold slowness vector estimates.

arguments:
	phase - name of seismic phase
	u - estimated slowness vector
	t0 - start time at reference station
	twin - length of analysis time window relative to t0
	array - array name to use in table for station key field
	evid - css3.0 evid of parent data
	bankid - defines unique multiwavelet bank (could be 
		extracted from traces of gather, but it is
		so deep in indirection it gets ridiculous)
	fc - center frequency (in Hz) of this wavelet bank.	
	fwin - bandwidth (in Hz) of this wavelet
	C - 3x3 covariance matrix estimate for this slowness vector
		(ux,uy, t order assumed )
	cohtype - type of coherence measure used (mapped in multiwavelet.h)
	peakcm - value of coherence measure for this fc and evid. 
	db - output database
Returns 0 if dbaddv was successful, -1 if dbaddv fails.

Author:  G Pavlis
Written:  March 2000
*/
int MWdb_save_slowness_vector(char *phase, 
	MWSlowness_vector *u,
	double t0,
	double twin,
	char *array,
	int evid,
	int bankid,
	double fc,
	double fwin,
	double *C,
	int nsta,
	int ncomp,
	int cohtype,
	double peakcm,
	Dbptr db)
{
	double slo, azimuth, cxx, cyy, cxy;
	char cmeasure[2];

	slo = hypot(u->ux,u->uy);
	azimuth = atan2(u->ux,u->uy);
	azimuth = deg(azimuth);
	db = dblookup(db,0,"mwslow",0,0);

	switch(cohtype)
	{
	case(USE_COHERENCE):
		strcpy(cmeasure,"c");
		break;
	case(USE_SEMBLANCE):
	default:
		strcpy(cmeasure,"s");
	}

	if( dbaddv(db,0,"sta",array,
		"evid",evid,
		"bankid",bankid,
		"phase", phase,
		"fc",fc,
		"fwin",fwin,
		"time",t0,
		"twin",twin,
		"slo",slo,
		"azimuth",azimuth,
		"cxx",C[0],
		"cyy",C[4],
		"cxy",C[1],
		"nsta",nsta,
		"ncomp",ncomp,
		"cohtype",cmeasure,
		"cohmeas",peakcm,
		"algorithm","mwap",0) < 0) 
	{
		elog_notify(0,
			"dbaddv error for mwslow table on evid %d fc=%lf\n",
				evid,fc);
		return(-1);
	}
	else
		return(0);
}
예제 #13
0
int MWdb_save_statics(
	int evid, 
	int bankid,
	char *phase,
	double fc,
	double t0,
	double twin,
	double refelev,
	MWgather *g,
	double *moveout,
	Arr *statics,
	Arr *stations,
	Arr *snrarr,
	Arr *arrivals,
	Arr *model_times,
	Dbptr db)
{
	char *sta;
	int i;
        MWstatic *mws;
	MWstation *s;
	Signal_to_Noise *snr;
	int errcount=0;
	double time;
	int nsta;
	Dbptr dbt, dba, dbsnr;
	double ampdb, aerrdb;  
	double *atime,*modtime,resid;
	int ierr;

	dbt = dblookup(db,0,"mwtstatic",0,0);
	dba = dblookup(db,0,"mwastatic",0,0);
	dbsnr = dblookup(db,0,"mwsnr",0,0);

	nsta = g->nsta;

	for(i=0;i<nsta;++i)
	{
		/* We keep all snr estimates that can be found in the snarr
		array.  Station with low signal to noise ratio are automatically
		deleted in processing so it is useful to record this fact in
		the database in the mwsnr table.  Note we silently skip stations
		not found in the array for snr */
		sta = g->sta[i]->sta;
 		snr = (Signal_to_Noise *)getarr(snrarr,sta);
		if(snr != NULL)
		{
		/* negative snr values are used to flag null entries
		that are still processed.  We don't want these store
		here though so we skip them.*/
		  if (((snr->ratio_z) > 0.0)
			&& ((snr->ratio_n) > 0.0)
			&& ((snr->ratio_e) > 0.0)
			&& ((snr->ratio_3c) > 0.0)  )
		  {
		    if( dbaddv(dbsnr,0,
			"sta",sta,
			"fc",fc,
			"bankid",bankid,
			"phase",phase,
			"evid",evid,
			"nstime",snr->nstime,
			"netime",snr->netime,
			"sstime",snr->sstime,
			"setime",snr->setime,
			"snrz",snr->ratio_z,
			"snrn",snr->ratio_n,
			"snre",snr->ratio_e,
			"snr3c",snr->ratio_3c,
			"algorithm","mwap",0) < 0) 
		    {
			elog_notify(0,"mwtstatic dbaddv error for station %s\n",sta);

			++errcount;
		    }
		  }
		}
		mws = (MWstatic *)getarr(statics,sta);

   		/* Again we silently skip stations without an entry in
		this array because they can auto-edited in processing
		so this is not an error. */
		if(mws != NULL)
                {
			s = (MWstation *)getarr(stations,sta);
			if(s == NULL)
			{
				elog_complain(0,"MWdb_save_time_statics cannot find entry for station %s\nThis should NOT happen--program may have ovewritten itself!\n",
					sta);
				continue;
			}
			/* We have to correct the start time for moveout.
			This asssumes the moveout vector has the current 
			best estimate */
			time = t0 + moveout[i];
			/* We store the residual relative to a model time.
			There may be a more elegant way to skip saving resid
			in the conditional below with dbNULL, but I couldn't
			figure out that process. */
			atime = (double *)getarr(arrivals,sta);
		    	modtime = (double *)getarr(model_times,sta);
		    	if((atime==NULL) || (modtime == NULL) )
			{
				ierr = dbaddv(dbt,0,
					"sta",sta,
					"fc",fc,
					"bankid",bankid,
					"phase",phase,
					"evid",evid,
					"time",time,
					"twin",twin,
					"wgt",s->current_weight_base,
					"estatic",s->elevation_static,
					"pwstatic",s->plane_wave_static,
					"rstatic",s->residual_static,
					"errstatic",mws->sigma_t,
					"ndgf",mws->ndgf,
					"datum",refelev,
					"algorithm","mwap",0);
			}
		    	else
			{
				resid = (*atime) - (*modtime);
				ierr = dbaddv(dbt,0,
					"sta",sta,
					"fc",fc,
					"bankid",bankid,
					"phase",phase,
					"evid",evid,
					"time",time,
					"twin",twin,
					"wgt",s->current_weight_base,
					"estatic",s->elevation_static,
					"pwstatic",s->plane_wave_static,
					"rstatic",s->residual_static,
					"errstatic",mws->sigma_t,
					"ndgf",mws->ndgf,
					"datum",refelev,
					"timeres",resid,
					"algorithm","mwap",0);
			}
			if(ierr<0)
			{
				elog_notify(0,"mwtstatic dbaddv error for station %s\n",sta);

				++errcount;
			}
			/* zero weight stations will have a static 
			time shift computed, but the amplitude will
			be meaningless.  Thus, we skip stations with 
			a zero weight */
			if((s->current_weight_base)>0.0)
			{
			/* output amplitude statics are converted to db */
			    ampdb = 20.0*(mws->log10amp);
			    aerrdb = 20.0*(mws->sigma_log10amp);
			    if( dbaddv(dba,0,
				"sta",sta,
				"ampcomp",AMPCOMP,
				"fc",fc,
				"bankid",bankid,
				"phase",phase,
				"evid",evid,
				"time",time,
				"twin",twin,
				"wgt",s->current_weight_base,
				"ndgf",mws->ndgf,
				"ampstatic",ampdb,
				"erramp",aerrdb,
				"algorithm","mwap",0) < 0) 
			    {
				elog_notify(0,"mwtstatic dbaddv error for station %s\n",sta);

				++errcount;
			    }
			}
			
		}
	}
	return(errcount);
}
/* This is the main processing function for this program.  

Arguments:
	dbv - db pointer to a complex view of the database to be 
		processed.  That is, it has these properties:
		1.  It is a join of:
			event->origin->assoc->arrival
		2.  subset to single arrival name AND orid==prefor
		3.  sorted by evid/sta

	pf - input parameter space

The main processing loop here keys on the grouping defined in the view
passed as dbgrp.  That is, seismograms for each event group are processed
as a complete gather.  After that, are nested loops to do the multiwavelet
processing as described in Bear and Pavlis (1999a,b).  

Author:  Gary Pavlis
Date:  March 1999+
*/
#define LAG_ERROR -100000 /* Computed lags smaller than this returned
			by compute_optimal_lag are treated as an error
			condition.  Should probably be in an include file*/
void mwap_process(Dbptr dbv,char *phase,  Pf *pf) 
{
	int nevents;  /* number of events=number of groups in dbgrp */
	MWbasis *mw;  /* Multiwavelet basis functions */
	Tbl **decimators;  /* List of loaded decimators used to construct
				multiwavelet transforms in lower bands */
        Tbl **dec_objects;  /*Actual decimation filter objects */
	/* Note:  mw and dec_objects define the multiwavelet transform */
	int nwavelets,nbands;

	/* sets coherence mode used to determine optimal lag */
	int coherence_type;
	
	Arr *stations;  /* This associative array holds MWstation objects
			that contain header like data that is station 
			dependent */
	Arr *badclocks;  /* associative array keyed by sta name holding
			list of time intervals with bad timing */
	char *refsta;  /* Name of reference station */
	double refelev;  /* reference elevation from parameter file */
	int nsta;  /* number of stations */
	int ntest;
	Dbptr db;  /* generic db lookup parameter */
	Dbptr dbgrp;  /* evid group db pointer */
	Dbptr tr;  /* trace database */
	Dbptr dbmps;  /* mwpredslow table */
	Tbl *sortkeys,*sortkeys2;  /* used because different tr routines require
				different sort orders */

	int *pad;  /* vector of length nbands holding computed time padding
			lengths for each band in samples */
	int tpad;  /*time pad actually used  (max of *pad) */
	Time_Window *swin, *nwin;  /* arrays defining time windows
		for signal and noise respectively (relative to arrival)*/
	Time_Window swinall, nwinall;  /*define read time intervals (extracted
			from swin and nwin arrays */
	int *decfac;  /* array of decimation factors needed at times */
	Arr *mwarr;  /* Holds indexed multiwavelet transformed trace objects*/
	/* We keep three copies of arrival time information.  
		arrival0 = original times read from db (never altered)
		arrivals = current working copy
		arrival_new = new estimate obtained from "arrivals" 
	*/
	Arr *arrival0,*arrivals,*arrival_new;
	Arr *static_result;  /* Holds error statistics for static estimates */
	MWSlowness_vector u0,u;
	int i,j;
	double avgamp, amperr;
	int ampndgf;
	int iterations;
	double ucovariance[9];
	char *array_name;
	int accumulate;

	/* These are channel code names used in trace library rotation
	functions rotate_to_standard and trrotate.  */
	char *stdchans[3]={ EW, NS , VERTICAL };
	char *pcchans[3]={"R","T","ZL"};

	Arr *mwsig_arr,*mwnoise_arr;  /* these index pointers to mw transformed
			signal and noise series */
	Arr **sn_ratios;  /* vector of Arr pointers of length nbands indexing
		signal to noise ratio estimates (stored in a structure) for
		every station */
	Spherical_Coordinate polarization0,polarization;
	Spherical_Coordinate polarz={1.0,0.0,0.0};
	Arr *model_times=NULL;
	MWSlowness_vector model_slow;
	double rctm[9];  /*ray coordinate transformation matrix*/
	double timeref;  /* time reference at reference station */
	double time;
	double t0,twin;
	double si;
	double fc,fwin;
	int evid;
	int lag;  /* optimal lab computed by coherence measure */
	double peakcm;  /*Peak value of coherence measure */
	/* For a given gather we set moveout computed moveout time in
	seconds relative to the reference station.  This time includes
	the combined current static estimates.  This is a vector workspace
	that is recycled for every gather.  It is alloced soon as we
	know the number of stations in the site table.  */
	double *moveout;
	MWgather **gathers;
	Particle_Motion_Ellipse *avgpm;
	Particle_Motion_Error *avgerr;
	char *pmtype_to_use;  /* type of particle motion estimate to use
				for polarization */
	Arr *pm_arr,*pmerr_arr;
	Arr *pmarray,*errarray;
	/* This vector defines the "up" direction.  For P waves this
	initialization is correct.  For S it may not be appropriate, but
	this is something to repair later */
	double up[3]={0.0,0.0,1.0};
	int bankid;  /* mutliwavelet group id */
	int band_exit = 0;
	/* name of parameter file produced by GUI to control this program */
	char *guipf;
	int stack_alignment;
	Pf *pfcontrol;
	int loopback;
	int numberpasses=0;
	/* These define the relative time window used for stack and
	particle motion.  s denotes stack, ts0 etc are pm */
	double sts0,ste0;  /* we don't need the equivalent of ts1 and te1 */
	double ts0,ts1,te1,te0;

	/* This is essential or copy_arrival_array can produce garbage */
	arrival0=NULL;
	arrivals = NULL;
	arrival_new=NULL;
	pm_arr = NULL;
	pmerr_arr = NULL;
	pmarray = NULL;
	errarray = NULL;
	si = pfget_double(pf,"sample_interval");
	/* First we need to load the multiwavelet functions and the 
	associated decimators for the transform.  Each of these
	routines will die if serious problems occur and have no
	error returns.  Wavelet functions can be loaded from a parameter
	file or a db.  */
	if(pfget_boolean(pf,"get_wavelets_from_database"))
	{	
		mw = load_multiwavelets_db(dbv,pf,&nwavelets,&bankid);
	}
	else
	{
        	mw = load_multiwavelets_pf(pf,&nwavelets);
		bankid = pfget_int(pf,"bankid");
	}
        decimators = define_decimation(pf,&nbands);
	allot(int *,decfac,nbands);
        dec_objects = build_decimation_objects(decimators,nbands,decfac);

	print_band_info(mw,decfac,pf);

	/* This creates the station objects.  The time extracted here
	is needed to sort out the ontime:endtime key in the site table.
	This is done is a less than bombproof fashion by randomly 
	grabbing the time in the first record view.
	Because of the way the site table works this will always work
	in some fashion.  It will only matter if a station ever moves
	and then we have a bad problem anyway.  */
	dbv.record = 0;
	dbgetv(dbv,0,"time",&time,0);
	stations = build_station_objects(dbv,pf,time);
	refsta = get_refsta(stations);
	array_name = pfget_string(pf,"array_name");
	if(array_name == NULL)
	{
		elog_complain(0,"WARNING:  array_name not defined in parameter file.  Set to default of ARRAY\n");
		array_name = strdup("ARRAY");

	}
	refelev = pfget_double(pf,"reference_elevation");
	/* This loads a definition of bad clocks from an extension
	table called timing.  This comes from libgenloc where it
	is used to handle automatic switching to S-P times. */
	badclocks=newarr(0);
	if(db_badclock_definition(dbv,pf,badclocks))
	{
		elog_notify(0,"Problems in setting up table of stations with timing problems\n");
	}
	/* This function can define stations as always having bad timing
	based on a parameter Tbl list of station names keyed by bad_clock.*/
	pfget_badclocks(pf,badclocks);

	pmtype_to_use = pfget_string(pf,"array_particle_motion_to_use");
	if(pmtype_to_use==NULL) pmtype_to_use=strdup(PMOTION_BEAM);
	/* this used to be a variable, but we no longer have a choice.*/
	coherence_type=USE_COHERENCE;
	
	/* This variable sets if we should reset the arrival estimates
	to starting values for each band.  When true the results accumulate
	from band to band.  That is we keep adding corrections from previous
	band to progressively higher frequency.*/
	accumulate = pfget_boolean(pf,"accumulate_statics");
	/* compute time pad lengths for each band of the mw transforms */
	pad = compute_tpad(dec_objects, mw, stations,pf);

	/* These routine parses the parameter file for noise and
	analysis time window information respectively returning
	arrays of Time_Window structures of length nbands*/
	decfac = get_decimation_factors(dec_objects, pf);
	swin = get_signal_windows(decfac,pad,pf);
	nwin = get_noise_windows(decfac,pad,pf);
	print_window_data(decfac,nbands,swin,nwin,pf);	

	/* This gets time windows for signal and noise needed for
	reading data (i.e. largest time ranges needed) */
	swinall = compute_time_window(swin,decfac,nbands);
	nwinall = compute_time_window(nwin,decfac,nbands);

	guipf = pfget_string(pf,"mwapcontrol");
	/* better safe than sorry */
	if(guipf==NULL)
	{
		elog_die(0,"Missing required parameter mwapcontrol");
	}

	/* We can create these works spaces now for efficiency so 
	we don't have to constantly recreate them dynamically below */
	allot(double *,moveout,cntarr(stations));
	allot(MWgather **,gathers,nwavelets);

	/* This associative array holds indexed pointers to multiwavelet
	transformed traces.  We create it here, but it is repeatedly
	freed and cleared below */
	mwarr = newarr(0);
	/* This one has to be initialized*/
	static_result=newarr(0);

	/* We need this table repeatedly below so we avoid constant 
	lookups */
	dbmps = dblookup(dbv,0,"mwpredslow",0,0);
	if(dbmps.record == dbINVALID)
		elog_die(0,"db lookup failed for mwpredslow table\nMWavelet schema extensions are required\n");

	/* Now we loop through the outer loop event by event.  
	This is structured here by using a dbgroup defined db pointer
	that is passed through the argument list.  The db pointer 
	is incremented and then the bundle is taken apart to crack
	apart each group of traces (the gather).  Note we use
	a defined name to look up the evid grouped table. */
	dbgrp = dblookup(dbv,0,EVIDBDLNAME,0,0);
	if (dbgrp.record == dbINVALID)
		elog_die(0,"Error in dblookup for named evid group table = %s\n",
			EVIDBDLNAME);
        dbquery(dbgrp,dbRECORD_COUNT,&nevents);
        fprintf(stdout,"Processing begins for %d events\n",nevents);

	sortkeys = newtbl(0);
	pushtbl(sortkeys,"sta");
	pushtbl(sortkeys,"chan");
	pushtbl(sortkeys,"time");
	sortkeys2 = newtbl(0);
	pushtbl(sortkeys2,"time");
	pushtbl(sortkeys2,"sta");
	pushtbl(sortkeys2,"chan");

	for(dbgrp.record=0;dbgrp.record<nevents;++dbgrp.record)
	{
		Dbptr db_bundle;
		int evid; 
		int is, ie; 
		int ierr;
		double modaz;

		if(dbgetv(dbgrp,0,"evid", &evid,
                        "bundle", &db_bundle,0) == dbINVALID)
		{
                        elog_complain(1,"dbgetv error for row %d of event group\nAttempting to continue by skipping to next event\n",
                                dbgrp.record);
			continue;
		}

                dbget_range(db_bundle,&is,&ie);

		if(ie-is<3)
		{
			elog_complain(0,"Insufficient data to process for evid %d\nNeed at least three station -- found only %d\n",
				evid,ie-is);
			continue;
		}
		/* We utilize what we call plane wave statics here
		to approximately correct for wavefront curvature.
		We set the record number to is so we can access 
		the correct origin information from the db.  Because
		we used a join allrows of this group should have the
		same origin data.  */
		ierr = set_pwstatics(stations,refsta,phase,db_bundle,pf);
		if(ierr)elog_complain(0,"%d errors computing %d plane wave statics for evid %d\n",
			ierr,ie-is,evid);

		/* This routine loads an Arr of arrival times from 
		the input db to be used to compute initial slowness
		vector and initial statics.  */
		arrival0 = get_arrivals(db_bundle);

		/* We edit the MWstation array to flag stations
		with bad timing in this function */
		MWcheck_timing(arrival0,stations,badclocks);

		/* Save these times */
		copy_arrival_array(arrival0,&arrivals);


		/* Initialize slowness vector to 0 and then estimate
		it from data using current arrival times */
		u0.ux = 0.0;  u0.uy = 0.0;  u0.refsta = refsta;
		timeref = compute_time_reference(stations,arrivals,refsta,u0);
		/* for the first pass we use weights defined for the 
		lowest frequency band.  This is done because it asssumed
		that if frequency dependent weighting is actually used
		the lowest band would have the widest effective aperture. */
		ierr = estimate_slowness_vector(u0,arrivals,stations,
			refsta, refelev, timeref, phase, nbands-1,&u);
		/* It is necessary to reset the time reference to handle 
		the case correctly when the reference station does not
		actually record this event.  This function uses a moveout
		correction that depends upon the slowness vector, so it can
		float about a bit in that situation */
		if(ierr>0)
			elog_notify(0,"%d nonfatal errors in estimate_slowness_vetor for evid %d\n",ierr,evid);
		else if(ierr < 0)
		{
			elog_complain(0,"estimate_slowness_vector failed for initial slowness estimate for evid %d\nData for this event will be skipped\n",
				evid);
			continue;
		}
		/* This routine returns the slowness vector and an arr of 
		estimated arrival times.  The slowness vector is saved
		in the mwpredslow table immediately below.  Arrival times
		are used to compute residuals later. */
		ierr = MWget_model_tt_slow(stations, refsta, phase,
			db_bundle, pf, &model_times, &model_slow);

		timeref = compute_time_reference(stations,arrivals,refsta,u);
		polarization0=estimate_initial_polarization(model_slow,stations,
			refsta,phase);

		modaz = atan2(model_slow.ux,model_slow.uy);

		if(dbaddv(dbmps,0,"sta",array_name,
			"evid",evid,
			"phase",phase,
			"time",timeref,
			"slo",hypot(model_slow.ux,model_slow.uy),
			"azimuth",deg(modaz),
			"majoraz",deg(polarization0.phi),
			"majorema",deg(polarization0.theta),
			"vmodel",pfget_string(pf,"TTmodel"),0) == dbINVALID)
		{
			elog_complain(0,"dbaddv error for evid %d on mwpredslow table\n",
				evid);
		}

		/* This function reads in the trace data for this event
		using time windows defined above */
		tr = mwap_readdata(dbgrp,arrivals,swinall, nwinall);
		if(tr.record == dbINVALID)
		{
			elog_complain(0,"Serious problems reading data for evid %d -- no data processed for this event\n",evid);
			continue;
		}
		tr = dblookup(tr,0,"trace",0,0);
		/* We first glue together any possible recording break
		generated entries -- common with continuous data.
		This also seems to require a resort because of the
		way data was read in.   */
/*
		tr = dbsort(tr,sortkeys,0,0);
*/
		trsplice(tr,0.1,0,0);

		/* We run trsplit to break up waveform segments at real gaps.
		I'm not sure later code will work correctly if it isn't an 
		all or nothing situations (e.g. gap in Z component, but 
		not in N or E).  In any case, we have to deal with 
		potential multiple segments later.  */
		trsplit(tr,0,0);

		trapply_calib(tr);
		trdemean_seg(tr);
		/* Now we have reorder the traces or this will not work
		correctly*/
		tr = dbsort(tr,sortkeys2,0,0);
		ierr = rotate_to_standard(tr,stdchans);
		if(ierr<0)
		{
			elog_complain(0,"rotate_to_standard failed processing evid %d -- no data processed for this event\n",
				evid);
			continue;
		}
		if(ierr>0)elog_complain(0,"rotate_to_standard failed for %d stations\n",
				ierr);

		/* This releases the space held by the raw data traces
		keeping only the rotate_to_standard outputs */
		free_noncardinal_traces(tr);

		elog_log(0,"Computing multiwavelet transform:  be\
 patient as this can take a while with many channels\n");
		/* This function computes the multiwavelet transform
		of all traces currently in tr for signals around arrival*/
		mwsig_arr = tr_mwtransform(tr,arrivals,swin,decfac,dec_objects,
				nbands,mw,nwavelets);

		/* We repeat the same thing for noise windows */
		mwnoise_arr = tr_mwtransform(tr,arrivals,nwin,decfac,
				dec_objects,nbands,mw,nwavelets);
		/* Now compute signal to noise ratio figures for all
		nbands storing the structures that define the results
		in an Arr keyed by station. Note this is actually 
		a vector of Arr pointers of length nbands.  Further
		note the following function creates this complicated
		object, and it must be freed after each event is 
		processed. */
		sn_ratios=compute_signal_to_noise(mwsig_arr,mwnoise_arr,
					stations,arrivals,swin,nwin,
					nbands,nwavelets);

		/* Now we get to the heart of this program.  This is
		the outer loop over frequency.  Note the loop goes
		backward because the lowest frequencies are the final
		row of the mw transform matrices of pointers */

		copy_MWslowness_vector(&u,&u0);
		if(numberpasses>0)
		{
			fprintf(MWpout,"NEWEVENT %d\n",evid);
		}
		for(i=nbands-1;i>=0;--i)
		{
			if(!accumulate)
				copy_arrival_array(arrival0,&arrivals);

			copy_arrival_array(arrivals,&arrival_new);
			fc = (mw[i].f0)/(2.0*si*decfac[i]);
			fwin = (mw[i].fw)/(2.0*si*decfac[i]);

			fprintf(stdout,"Processing begins on band %d with center frequency %lf\nWait for -Hit Accept button when ready- prompt\n",
				i,fc);

			/* This builds the basic working gathers for
			each wavelet and builds a shortcut of pointers
			to MWtraces that are related */
			for(j=0;j<nwavelets;++j)
			{
				gathers[j] = build_MWgather(i,j,
						mwsig_arr,stations,
						sn_ratios[i],pf);
			}
			fprintf(stdout,"Working gather for this band has %d stations\n",
				gathers[0]->nsta);
			/* Testing band 0 should be sufficient.  The
			signal-to-noise is averaged overall wavelets so
			the same stations should be deleted in all
			wavelet of the group */
			if(gathers[0]->nsta < 3)
			{
				elog_notify(0,"Insufficient data in band %d to passed signal-to-noise cutoff defined for this band for evid %d\nSkipping to next frequency band\n",
					i,evid);
				continue;
			}
			/* This may not be necessary, but it is certainly 
			important for debugging.  We check that all
			the gathers in the group have the same length.  
			If they aren't, we are in trouble because we use
			a single vector to hold moveout information */
			check_gather_consistency(gathers,nwavelets);

			/* Now we compute the moveout information assuming
			stations are in the same order in the gather for
			each wavelet */
			if(compute_total_moveout(*gathers,stations,refsta,
				u,refelev,phase,moveout))
			{
				elog_die(0,"Cannot find reference station to compute moveout:  Should not happen unless program overwrites itself\n");
			}

			if(numberpasses>0)
			{
				fprintf(MWpout,"NEWBAND %d\n",i);
				fflush(MWpout);
			}
			else
			{
				char ctmp[40];
				fprintf(stdout,"Starting processing of first event\nSelect and options and press the Start button when ready\n");
				fprintf(MWpout,"STARTUP %d %d\n", 
					evid,i);
				fflush(MWpout);
				fgets(ctmp,40,MWpin);
			}
			++numberpasses;

			/* This is placed here to allow changing the
			alignment options on the fly.  Choice may
			depend on data. */
			pfread(guipf,&pfcontrol);
			stack_alignment=get_stack_align_mode(pfcontrol);
			pffree(pfcontrol);
			
			/* kind of a odd loop construct here made 
			necessary by differences in stackalignment
			options.  If we align with theoretical value
			or use the vertical we do not need to repeat
			this loop and we fall out the bottom.  If we
			use the pm estimate, however, we have to 
			realign the stack rotated to the new major
			ellipse estimate.  In that case we have to
			repeat the whole procedure.*/
			loopback=2;
			do {
				MWstack *stack;
				switch(stack_alignment)
				{
				case PMTHEORY:
					copy_polarization(&polarization0,&polarization);
					loopback=0;
					break;
				case PMZ:
					copy_polarization(&polarz,&polarization);
					loopback=0;
					break;
				case PMESTIMATE:
				default:
				/* This uses theoretical version for the
				first pass then the estimate on the 
				second */
					if(loopback==2)
					  copy_polarization(&polarization0,
						&polarization);
				}
				stack=MWcompute_arrival_times(gathers,
    					   nwavelets,timeref,moveout,
    					   polarization,swin[i],
					   sn_ratios[i],guipf,
    					   &arrival_new,&static_result,
                                            &avgamp, &amperr, &ampndgf);
				if(stack==NULL)
				{
					/* I use a flag to avoid an
					evil goto here */
					band_exit = 1;
					/* This is strange but necessary
					to stop string of bogus errors from
					copy_arrival_array function when
					this loops back */
					if(arrival_new!=NULL)
						freearr(arrival_new,free);
					arrival_new = NULL;

					break;
				}
					
					
				/* Note this routine updates residual
				static values to new values relative to
				the new slowness vector estimate */
	                	ierr = estimate_slowness_vector(u0,
					arrival_new,stations,
                        		refsta, refelev, timeref, 
					phase, i, &u);
				/* We need to recompute the moveout to 
				now be relative to the new slowness vector
				estimate.  We then use this for particle 
				motion analysis which can change the 
				polarization vector */
				compute_total_moveout(*gathers,stations,refsta,
				u,refelev,phase,moveout);
				/* This segment converts particle motions
				for 3-c arrays.  */
				if(gathers[0]->ncomponents==3)
				{
					MWstack *spm; 
					Time_Window pmtwindow;
					double *timeweight;
					
					/* We extract the time window
					from a control parameter file which
					is assumed to be created by a GUI
					with tcl/tk */
					pfread(guipf,&pfcontrol);
					ts0=pfget_double(pfcontrol,"pm_ts0");
					ts1=pfget_double(pfcontrol,"pm_ts1");
					te1=pfget_double(pfcontrol,"pm_te1");
					te0=pfget_double(pfcontrol,"pm_te0");
					/* we need these below, not here */
					sts0=pfget_double(pfcontrol,"stack_ts0");
					ste0=pfget_double(pfcontrol,"stack_te0");
					twin = ste0-sts0;
					pffree(pfcontrol);
					pmtwindow.tstart = nint(ts0/(stack->dt));
					pmtwindow.tend = nint(te0/(stack->dt));

					spm = MWextract_stack_window(stack,
						&pmtwindow);
					if(spm==NULL)
						elog_die(0,
						  "Fatal error in MWextract_stack_window\n");
					/* Sets time weight function for 
					a trapezoidal window */
					timeweight=MWstack_set_trapezoidal_window(spm->tstart,
						spm->dt,spm->nt,
						ts0,ts1,te1,te0);
					dcopy(spm->nt,timeweight,1,spm->timeweight,1);
					free(timeweight);
					MWstack_apply_timeweight(spm);

					if(MWcompute_array_particle_motion(gathers,
					  nwavelets,spm,timeref,moveout,
					  up,&pmarray,&errarray, &pm_arr,&pmerr_arr) )
					{
					  elog_complain(0,"Errors in MWcompute_array_particle_motion\n");
					}
					avgpm = (Particle_Motion_Ellipse *)getarr(pmarray,pmtype_to_use);
					avgerr = (Particle_Motion_Error *)getarr(pmarray,pmtype_to_use);

					polarization
					  =unit_vector_to_spherical(avgpm->major);
					destroy_MWstack(spm);
				}
				peakcm=stack->coherence[idamax(
					stack->nt,
					stack->coherence,1)];
				copy_arrival_array(arrival_new,&arrivals);
				freearr(arrival_new,free);
				arrival_new = NULL;
				destroy_MWstack(stack);
				if(stack_alignment==PMESTIMATE)
						--loopback;
			}while(loopback>0);
			if(band_exit)
			{
				band_exit = 0;
				continue;
			}

			/* This routine computes the covariance of
			the estimated slowness vector */
			if(compute_slowness_covariance(stations,static_result,
				ucovariance) )
				elog_complain(0,"Problems computing slowness vector covariance estimate for evid %d and band %d\n",
					evid, i);
			/* routines below save a time window.  We compute
			the lag corrected start time at the reference station
			here as t0 to simplify this in functions that
			need this.*/
			t0 = timeref + sts0;
			/* This series of functions save results in a set
			of css3.0 extension tables.  */

			/* ampndgf+1 here is a cheap solution to the
			number of stations used in a solution.  This 
			confusion is necessary because autoediting reduces
			the data set.  Poor planning caused me to not
			force this to be saved explicitly, but ampndgf is
			an exact surrogate.  The +1 is needed because the
			calculation uses number_used - 1 since the average
			amplitude is extracted as a free parameter.
			*/
			if(MWdb_save_slowness_vector(phase,&u,t0,twin,
				array_name,evid,bankid,fc,fwin,
				ucovariance,ampndgf+1,3,
				coherence_type,peakcm,dbv))
					dbsave_error("mwslow",evid,i);
			if(MWdb_save_avgamp(array_name, evid, bankid, phase,
				fc, t0, twin, avgamp,amperr,ampndgf,
				dbv) )
					dbsave_error("mwavgamp",evid,i);
			if(MWdb_save_statics(evid, bankid, phase, fc, t0,
				twin,refelev,*gathers,moveout,static_result,
				stations,sn_ratios[i],
				arrivals, model_times,dbv))
					dbsave_error("mwtstatic:mwastatic:mwsnr",evid,i);
			t0=timeref+ts0;
			twin = te0-ts0;
			if(MWdb_save_pm(array_name,evid,bankid,phase,fc,t0,
				twin,*gathers,moveout,pm_arr,pmerr_arr,
				avgpm,avgerr,dbv)  )
					dbsave_error("mwpm",evid,i);
			/* We have to release the memory held in these
			associative arrays.  In the earlier loop the 
			function that creates them always clears them
			before continuing when they are not null.  
			The explicit NULL set after the free is done
			to make sure in looping back the particle
			motion routine clears these correctly.  */
			freearr(pm_arr,free);
			pm_arr = NULL;
			freearr(pmerr_arr,free);
			pmerr_arr = NULL;
			/* same for static arr */
			freearr(static_result,free);
			static_result = NULL;
		}
		/*release main work spaces with this series of complicated free routines.
		Here is where you really wish C had garbage collection */
		free_sn_ratios_arr(sn_ratios,nbands);
		free_MWtransform_arr(mwsig_arr,nbands,nwavelets);
		free_MWtransform_arr(mwnoise_arr,nbands,nwavelets);
		trdestroy(&tr);
		freearr(arrival0,free);
		freearr(arrivals,free);
		/* This may not be necessary, but better safe than sorry */
		arrivals = NULL;   arrival0 = NULL;   arrival_new = NULL;
	}
	free(moveout);
	free(swin);
	free(nwin);
	free(refsta);
}
예제 #15
0
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;
		}