void compute_location(Location_options o,
	RTlocate_Options rtopts,
	Arr *stations, Arr *arrays, Arr *phases, 
	Pf *pf,
	Dbptr master_db, Dbptr dbtmp, ORB_Hypocenter hyp, int orbout)
{
	Tbl *ta,*tu;  /* Arrival and slowness tables respectively */
	Hypocenter h0;
	int ret_code;
	Tbl *converge_history,*reason_converged,*residual;
	Hypocenter *hypo;
	int niterations;
	char *vmodel;
	int i;
	char *s;
	int orid;
	Point origin;
	double delta, seaz;
	double **C;
	float *emodel;
	int nass;

	initialize_hypocenter(&h0);

	/* It is inefficient to reread these from the parameter
	space on each entry, but preferable to a burdensome
	argument list */  
	origin.lat = pfget_double(pf,"center_latitude");
	origin.lon = pfget_double(pf,"center_longitude");
	origin.z = 0.0;

	/* This routine translates hyp structure to return tbl
	of arrival object pointers */
	ta = orbhypo_to_genloc(&hyp,phases,stations);
	/* this is a pure place holder */
	tu = newtbl(0);

	vmodel = pfget_string(pf,"velocity_model_name");

	/* By default we use the location transmitted by orbassoc.
	This can be overriden in the parameter file by using the
	other options allowed in genloc*/
	s=pfget_string(pf,"initial_location_method");
	h0.lat = hyp.lat;
	h0.lon = hyp.lon;
	h0.z = hyp.depth;
	h0.time = hyp.time;
	/* this strange logic is to allow this parameter to be defaulted.
	If the "initial_location_method" is not defined, or set
	to "manual", we use the location given by orbassoc.  Otherwise
	we utilize genlocs suite of initial locate options. */
	if(s != NULL)
		if(strcmp(s,"manual"))
			h0 = initial_locate(ta, tu, o, pf);

	/* Now compute distance from origin, and process only if 
	the event falls in the specified range */
	dist(rad(origin.lat),rad(origin.lon),rad(h0.lat),rad(h0.lon),
			&delta,&seaz);
	delta = deg(delta);
	/* this is the distance sifting test to ignore things outside
	specified distance range */
	if( ((delta>=rtopts.minimum_distance) 
		&& (delta <= rtopts.maximum_distance)) )
	{

	/* Location with Generic Gauss_Newton code */
		orid = -1;
		nass = maxtbl(ta);
		ret_code = ggnloc(h0,ta,tu,o,
				&converge_history,&reason_converged,&residual);
        	if(ret_code < 0)
        	{
                	elog_notify (0,"ggnloc failed to produce a solution for evid %d\n",hyp.evid);
        	}
        	else
		{
			if(ret_code > 0)
				elog_notify(0,"Warning:  %d travel time calculator failures in ggnloc\nSolution ok for evid %d\n",
                                	ret_code,hyp.evid);
			C = dmatrix(0,3,0,3);
			emodel = (float *) calloc(4,sizeof(float));
			if((emodel == NULL) || (*C == NULL) )
				elog_die(0,"Malloc error for error arrays\n");
			niterations = maxtbl(converge_history);
                	hypo = (Hypocenter *)gettbl(converge_history,
							niterations-1);
			predicted_errors(*hypo, ta, tu, o, C, emodel);
               		orid = save_origin(nass,hyp.evid,master_db,
					 dbtmp,*hypo,o,orbout);

                	save_origerr(orid,*hypo,C,dbtmp,orbout);
			save_assoc(ta, tu, orid, vmodel, 
				*hypo, dbtmp,orbout);
			elog_notify(0,"orid %d converged in %d iterations\n",
				orid,niterations);
			elog_notify(0,"Reason(s) for convergence:  \n");
			for(i=0;i<maxtbl(reason_converged);++i)
                        	elog_notify(0,"%s",gettbl(reason_converged,i));
			elog_notify(0,"\n");
			s=format_hypo(hypo);
			elog_notify(0,"%s\n",s);
			free(emodel);
			free_matrix((char **)C,0,3,0);
			free(s);
		}
		write_to_logfile(rtopts, orid, hyp.evid,
			  pf, converge_history, reason_converged,residual);

		if(maxtbl(converge_history)>0)freetbl(converge_history,free);
		if(maxtbl(reason_converged)>0)freetbl(reason_converged,free);
		if(maxtbl(residual)>0)freetbl(residual,free);

	}
	destroy_data_tables(ta, tu);
	return;
}
int dbpmel_process(Dbptr db, Tbl *gridlist,Pf *pf)
{
	Pf *vpf;
	Arr *arr_phase;
	char *vmodel;
	/* Holds indexed list of stations with bad clocks problems 
	that should be used only with S-P type timing */
	Arr *badclocks;
	Location_options o;
	/* Hold station table.   We make the array table empty always. */
	Arr *stations;
	int nbcs;
	int i,j,k;
	Tbl *grptbl;
	Tbl *grdidtbl;
	Dbptr dbevid_grp;  /* dbgroup pointers */
	/* Used by dbmatches */
	static Hook *hook=NULL;
	Tbl *reclist;
	Dbptr dbgs;
	Dbptr dbbundle;
	Dbptr dbcs;
	Tbl **ta;  /* We use an array of Tbls for arrival times to 
			allow a simple loop through an event group.*/
	Hypocenter *h0;  
	int *evid;  /* parallel array to h0 of event ids for each h0[i]*/
	Hypocenter hypocentroid;
	/* The associative array here is loaded from the pf and contains
	information on which events are to be treated as calibration events.
	The fixlist array of character strings is passed to pmel as a 
	parallel of vectors defining events with fixed coordinates */
	Arr *events_to_fix;
	/* This is the structure that encapsulates all the station
	correction elements.  WARNING: it is built up in pieces below,
	and later modifications most handle this carefully.*/
	SCMatrix *smatrix;
	Tbl *converge=NULL,*pmelhistory=NULL;
	Arr *arr_phase_3D;
	/* needed for output db tables */
	char *runname, *gridname;
	int pmelfail;
	Tbl *phaselist;


	initialize_hypocenter(&hypocentroid);
	runname = pfget_string(pf,"pmel_run_name");
	gridname = pfget_string(pf,"gridname");

	/* This genloc routine defines location parameters.  These
	are set globally here for the entire run.*/
	o = parse_options_pf(pf);
	/* Pmel is know to fail if this option is turned on */
	if(((o.generalized_inverse)==PSEUDO_RECENTERED)
		|| ((o.generalized_inverse)==DAMPED_RECENTERED) )
	{
		elog_notify(0,"parameter file specifies recenter\
option which is know to cause problems\nrecenter set off\n");
		if((o.generalized_inverse)==PSEUDO_RECENTERED)
			o.generalized_inverse = PSEUDOINVERSE;
		if((o.generalized_inverse)==DAMPED_RECENTERED)
			o.generalized_inverse = DAMPED_INVERSE;
	}