Example #1
0
int opendb( Dset *dset )
{
 
   char key[256];
   Tbl *sort_sta_ch_tm;
 
   if (dbopen_database ( dset->dbname, "r+", &(dset->db) ) == dbINVALID )
         die (0, "Can't open database %s\n",  dset->dbname );
 
    dset->db = dblookup ( dset->db, 0, "wfdisc", 0, 0);
    if ( dset->db.table == dbINVALID )
       die (0, "Can't open '%s' wfdisc table.\n", dset->dbname );
 
    /* Select specified sta&chan */
 
    sprintf( key,"(chan =~ /%s/ && sta=~ /%s/)\0", dset->chan, dset->sta );
    dset->db = dbsubset(  dset->db, key, 0 );
    sort_sta_ch_tm = strtbl("sta", "chan", "time", 0 ) ;
    dset->db = dbsort ( dset->db, sort_sta_ch_tm, 0, 0 ) ;
 
    dbquery ( dset->db, dbRECORD_COUNT, &(dset->dbrec) );
    if( dset->dbrec <= 0 )
       die( 0, " no record with sta == %s and chan == %s in %s.\n", 
                 dset->sta, dset->chan, dset->dbname );
 
 
    return 1;
 
}  
Example #2
0
void set_shot_variable(Dbptr db, Arr *tables, int evid, SEGYTraceHeader *h)
{
	int *ok;
	char ss_string[30];
	long int ntest;
	double dnorth, deast, elev, edepth;

	ok = getarr(tables,"shot");
	if(ok)
	{
		db = dblookup(db,0,"shot",0,0);
		sprintf(ss_string,"evid == %d",evid);
		db = dbsubset(db,ss_string,0);
		dbquery(db,dbRECORD_COUNT,&ntest);
		if(ntest <= 0)
		{
			elog_complain(0,"evid %d not found in shot table\nShot coordinates will not be saved in segy headers\n",
				evid);
			dbfree(db);
			return;
		}
		else if(ntest > 1)
		{
			elog_notify(0,"multiple rows in shot found for evid %d\n",
				evid);
		}
		db.record = 0;
		if(dbgetv(db,0,
			"dnorth",&dnorth,
			"deast", &deast,
			"elev", &elev,
			"edepth",&edepth,
				NULL) == dbINVALID)
		{
			elog_complain(0,"dbgetv error for evid %d\nShot coordinates will not be saved in segy headers\n",
				evid);
			return;
		}
		/*convert to m from km */
		deast *= 1000.0;
		dnorth *= 1000.0;
		h->sourceLongOrX          = htonl((int32_t) deast);
		h->sourceLatOrY           = htonl((int32_t) dnorth);
		h->sourceSurfaceElevation = htonl((int32_t) elev);
		h->sourceDepth            = htonl((int32_t) edepth);
		/* WARNING:  This assumes receiver coordinates have already been set */
		h->sourceToRecDist = htonl( (int32_t) hypot(
					dnorth - ((double)(ntohl(h->recLatOrY ))),
					deast  - ((double)(ntohl(h->recLongOrX)))
		));
	}
	dbfree(db);
}
Example #3
0
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);
}
Example #4
0
int main(int argc, char **argv)
{
	char *sift_expr, *wfdir, *format, *dbin, *dbout, *chan_maps;
	double calper;
	int overwrite=0;
	int ndec_stages;
	char **dec_stages;
	Tbl *chan_in_tbl, *chan_out_tbl;
	Dbptr dbi, dbo;
	Dbvalue dbv;
	Response *resp;
	Tbl *ncoefs, *coefs, *dec_fac;
	int dec_factor;
	int nwi, n, i, j, nchans;
	char string[512];
	char expr[1024];
	Dbptr dbwfi;
	char dbbase[1024];
	char dir[128];
	char dfile[128];
	char fnamei[1024];
	char fnameo[1024];
	char wfdir1[512];
	char wfdir2[512];
	double time, tref;

	/* Get command line args */

	if (!getargs(argc, argv, &sift_expr, &calper, &wfdir, &format, &dbin,
				&dbout, &chan_maps, &ndec_stages, &dec_stages)) {
		usage();
		exit (1);
	}
	if (calper >= 0.0) {
		fprintf (stderr, "dbdec: -c option not operational.\n");
		usage();
		exit (1);
	}

	/* Parse channel maps and wfdir */

	if (!parse_chan_maps(chan_maps, &chan_in_tbl, &chan_out_tbl)) {
		fprintf (stderr, "dbdec: Unable to parse channel maps, '%s'\n",
						chan_maps);
		usage();
		exit (1);
	}
	if (!parse_wfdir(wfdir, wfdir1, wfdir2)) {
		fprintf (stderr, "dbdec: Unable to parse wfdir, '%s'\n",
						wfdir);
		usage();
		exit (1);
	}

	/* Open and read decimation stage files */

	if (!read_dec_files(ndec_stages, dec_stages, &resp, &dec_factor, &ncoefs, &coefs, &dec_fac)) {
		fprintf (stderr, "dbdec: Unable to read decimation stage(s).\n");
		usage();
		exit (1);
	}
	printf ("Total decimation factor = %d\n", dec_factor);

	/* Open the input database */

        if (dbopen (dbin, "r+", &dbi) == dbINVALID) {
                elog_clear_register(1);
                fprintf (stderr, "dbdec: Unable to open input database '%s'.\n",
									dbin);
                exit (1);
        }
	dbi = dblookup (dbi, 0, "wfdisc", 0, 0);
        dbquery (dbi, dbRECORD_COUNT, &nwi);
        if (nwi < 1) {
        	fprintf (stderr, "dbdec: No wfdisc rows for input database '%s'.\n",
									dbin);
                exit (1);
        }

	/* Compose a subset expression for the input channel mappings */

	nchans = maxtbl (chan_in_tbl);
	for (i=0; i<nchans; i++) {
		sprintf (string, "chan == \"%s\"", gettbl(chan_in_tbl, i));
		if (i == 0) {
			strcpy (expr, "(");
			strcat (expr, string);
		} else {
			strcat (expr, " || ");
			strcat (expr, string);
		}
	}
	strcat (expr, ")");
	if (sift_expr) {
		strcat (expr, " && (");
		strcat (expr, sift_expr);
		strcat (expr, ")");
	}

	/* Subset the input wfdisc table */

	dbwfi = dblookup (dbi, 0, "wfdisc", 0, 0);
	dbwfi = dbsubset (dbwfi, expr, 0);
        dbquery (dbwfi, dbRECORD_COUNT, &n);
        if (n < 1) {
        	fprintf (stderr, "dbdec: No input channels for database '%s'.\n",
									dbin);
                exit (1);
        }
	printf ("Processing %d out of %d waveform segments.\n", n, nwi);

	/* Open the output database */

        if (dbopen (dbout, "r+", &dbo) == dbINVALID) {
                elog_clear_register(1);
                fprintf (stderr, "dbdec: Unable to open output database '%s'.\n",
									dbout);
                exit (1);
        }
	dbo = dblookup (dbo, 0, "wfdisc", 0, 0);
        dbquery (dbo, dbTABLE_DIRNAME, &dbv);
        strcpy (dbbase, dbv.t);

	/* Make a pass through the input wfdiscs to look for wf file conflicts */

	if (!overwrite) {
		printf ("Looking for waveform file conflicts...");
		fflush (stdout);
	}
	tref = 1.e30;
	for (dbwfi.record=0; dbwfi.record<n; dbwfi.record++) {
		if (!overwrite && (!strcmp(wfdir1,wfdir2)) ){
			if (!makeoutfname (dbwfi, wfdir1, wfdir2, dbbase, dir, dfile, fnameo)) {
				fprintf (stderr, "dbdec: makeoutfname() error.\n");
				exit (1);
			}
			if (zaccess(fnameo, F_OK) != -1) {
				fprintf (stderr, "\ndbdec(Warning): wf file conflict for '%s'.\n",
									fnameo);
				fprintf(stderr,"Will append but may waste space\n");
			}
		}
		dbgetv (dbwfi, 0, "time", &time, 0);
		if (time < tref) tref = time;
	}
	if (!overwrite) {
		printf ("OK\n");
	}
	tref = (double)((int)tref);

	/* Loop through and do the decimation */

	for (dbwfi.record=0; dbwfi.record<n; dbwfi.record++) {
		Trace *trace=NULL;

		/* Read in trace and convert to float */

		SCV_free_trace (trace);
		trace = NULL;
		trace = read_trace (dbwfi);
		if (trace == NULL) {
			fprintf (stderr, "dbdec: read_trace() error.\n");
			continue;
		}

		/* Decimate float trace */

		if (!decimate_trace (trace, ncoefs, coefs, dec_fac, tref)) {
			fprintf (stderr, "dbdec: decimate_trace() error.\n");
			exit (1);
		}

		/* Convert trace to output units and put back in data gaps */

		trace = convert_trace (trace, format);
		if (trace == NULL) {
			fprintf (stderr, "dbdec: convert_trace() error.\n");
			exit (1);
		}

		/* Write out decimated trace and wfdisc */

		makeoutfname (dbwfi, wfdir1, wfdir2, dbbase, dir, dfile, fnameo);
		if (!write_trace (dbwfi, dbo, dir, dfile, fnameo, 
					chan_in_tbl, chan_out_tbl, trace, overwrite)) {
			fprintf (stderr, "dbdec: write_trace() error.\n");
			exit (1);
		}
	}

	/* Fix up the output sensor, sitechan, etc. tables */

	if (!fixup_tables (dbi, dbo, chan_in_tbl, chan_out_tbl, calper, resp, dec_factor)) {
		fprintf (stderr, "dbdec: fixup_tables() error.\n");
		exit (1);
	}

	/* Normal exit */

	exit (0);
}
Example #5
0
int main(int argc, char **argv)
{
	SEGYBinaryFileHeader reel;
	SEGYTraceHeader *header;
	char *dbin;
	char *outfile;
	FILE *fp;
	Pf *pf;
	Arr *channels;  /* channel order list */
	Arr *table_list;  /* array of valid tables */
	int nchan;
	char *stest;

	float **traces;
	char text_file_header[SEGY_TEXT_HEADER_SIZE];
	Dbptr db, trdb, dbj;
	Dbptr trdbss;
	int nsamp0;
	double time0, endtime0, samprate0;
	long int nsamp;
	double samprate;
	int i,j;
	char stime[30],etime[30];
	char s[128];
	double tlength;
	double phi, theta;
	char *newchan_standard[3]={"X1","X2","X3"};
	char *trsubset="chan=~/X./";
	char *newchan[3]={"R","T","Z"};
	Tbl *sortkeys=newtbl(0);
	char sta[10],chan[10];
	double lat, lon, elev, dnorth, deast, edepth;
	char segtype;
	char refsta[10];
	int total_traces=0;
	char *time_str;
	long int evid,shotid=1;
	int rotate=0;
	long int ntraces;
        int ichan;
	int map_to_cdp;  /* logical switch to output data like cdp stacked data */
	char *fmt="%Y %j %H %M %S %s";
	char *pfname;
	int Verbose=0;
	/* New features added 2009 */
	/* this is a boolean.  If true (nonzero) it is assumed stdin will
	contain four numbers:  time,lat, lon, elev.  If false, only the
	time field is read and remainder of any input on each line is dropped.*/
	int input_source_coordinates;
	/* scale factor for source coordinates.  Needed because segy uses
	an int to store source coordinates.  Sensible choices are
	3600 for arc seconds and 10000 for a pseudodecimal. Note this
	parameter is ignored unless input_source_coordinates is true.*/
	int coordScale;
	/* If true use passcal 32 bit extension num_samps as record length.
	SEGY standard uses a 16 bit entry that easily overflows with large
	shots at long offset.  In this ase assume the 16 bit quantity is
	meaningless. */
	int use_32bit_nsamp;
	/* This is switched on by argument switch.  When set to a nonzero
	(default) the reel headers are written.  When 0 `
	the reel headers will not be written -- used by seismic unix
	and passcal*/
	int write_reel_headers=1;

	/* SEG-Y version to output. Default is original 1975 spec (rev 0) */
	int16_t segy_format = SEGY_FORMAT_REV_0;

	/* dbsubset query string */
	char *substr=NULL;

	/* text_header_description is a buffer holding a user-supplied description
	 * to be placed in the 3200-byte text header block. It is controlled by
	 * the parameter file value text_header_description or by the -d command
	 * line option, with the latter taking precedence */
	char* text_header_description=NULL;

	if(argc < 3) usage();
	dbin = argv[1];
	outfile = argv[2];
	pfname = NULL;
	for(i=3;i<argc;++i)
	{
		if(!strcmp(argv[i],"-pf"))
		{
			++i;
			pfname = argv[i];
		}
		else if(!strcmp(argv[i],"-SU"))
		{
			write_reel_headers=0;
		}
		else if(!strcmp(argv[i],"-v"))
		{
			Verbose=1;
		}
		else if(!strcmp(argv[i],"-d"))
		{
			++i;
			text_header_description = strdup(argv[i]);
		}
		else if(!strcmp(argv[i],"-ss"))
		{
			++i;
			substr=argv[i];
		}
		else if(!strcmp(argv[i],"-V"))
		{
			++i;
			if     (!strcmp(argv[i],"0")) {segy_format = SEGY_FORMAT_REV_0;}
			else if(!strcmp(argv[i],"1")) {segy_format = SEGY_FORMAT_REV_1_0;}
			else if(!strcmp(argv[i],"SU"))
			{
				segy_format = SEGY_FORMAT_SU;
				write_reel_headers=0;
			}
			else
			{
				elog_complain(0, "SEG-Y Version must be either 1 or 0");
				usage();
			}
		}
		else
		{
			usage();
		}
	}
	/* Command-line parameter sanity checking */
	if (write_reel_headers==0 && segy_format != SEGY_FORMAT_SU){
		complain(0, "The SU option cannot be used with the -V option");
		usage();
	}
	if(pfname == NULL) pfname = strdup("db2segy");

	elog_init(argc, argv);

	if(pfread(pfname,&pf)) {
		elog_die(0,"pfread error for pf file %s.pf\n",argv[0]);
	}

	/* Read the text_header_description if we weren't passed the -d option */
	if (!text_header_description) {
		text_header_description=pfget_string(pf, "text_header_description");
	}

	/* rotation parameters */
	rotate=pfget_boolean(pf,"rotate");
	if(rotate)
	{
		phi = pfget_double(pf,"phi");
		theta = pfget_double(pf,"theta");
	}
	/* This function creates the channel order list keyed by
	station channel names */
	channels = build_stachan_list(pf,&nchan,Verbose);

	map_to_cdp = pfget_boolean(pf,"map_to_cdp");
	if(map_to_cdp && Verbose)
		elog_notify(0,"Casting data as CDP stacked section\n");
	if(dbopen(dbin,"r",&db) == dbINVALID)
	{
		elog_complain(1,"Cannot open db %s\n", dbin);
		usage();
	}
	/* We grab the sample rate and trace length (in seconds) and
	use this to define global sample rates for the data.
	SEG-Y REV0 REQUIRES fixed length records and sample rates, so
	irregular sample rates will cause this program to die.
	One could add a decimate/interpolate function, but this
	is not currently implemented */
	samprate0 = pfget_double(pf,"sample_rate");
	tlength = pfget_double(pf,"trace_length");
	nsamp0 = (int)(tlength*samprate0);
	use_32bit_nsamp=pfget_boolean(pf,"use_32bit_nsamp");
	if (ntohs(segy_format) >= 0x0100 && use_32bit_nsamp) {
		elog_complain(0,"The 32-bit extension field is incompatible with SEG-Y REV 1. Ignoring 'use_32bit_nsamp' from the parameter file");
		use_32bit_nsamp=0;
	}

	/* nsamp in segy is a 16 bit field.  Handling depends on
	setting of use_32bit_nsamp boolean */
	if(nsamp0 > SEGY_MAX_NSAMP)
	{
		if(use_32bit_nsamp)
		{
			elog_notify(0,"Warning:  segy uses a 16 bit entity to store number of samples\nThat field is garbage. Using the 32 bit extension field.");
		}
		else
		{
		elog_complain(0,
		  "Warning:  segy uses a 16 bit entity to store number of samples. Requested %d samples per trace.  Trucated to %d", nsamp0, SEGY_MAX_NSAMP);
		nsamp0 = SEGY_MAX_NSAMP;
		}
	}

	/* boolean.  When nonzero set coordinates as geographic arc seconds values */
	int use_geo_coordinates=pfget_boolean(pf,"use_geo_coordinates");

	/* boolean. When nonzero, output decimal degrees instead of arcseconds if
	 * the requested output format supports it (rev1 only) */
	int prefer_decimal_degrees=pfget_boolean(pf, "prefer_decimal_degrees");

	/* We now have enough information to decide the coordUnits for all traces */
	int coordUnits = 0;
	if (!use_geo_coordinates) {
		coordUnits=SEGY_TRACE_COORDUNITS_LENGTH;
	} else if (ntohs(segy_format) >= 0x0100 && prefer_decimal_degrees) {
		coordUnits=SEGY_TRACE_COORDUNITS_DECIMAL_DEGREES;
	} else {
		coordUnits=SEGY_TRACE_COORDUNITS_ARCSECONDS;
	}
	/* We should have set our coordinate units now */
	assert(coordUnits!=0);

	input_source_coordinates=pfget_boolean(pf,"input_source_coordinates");
	if(input_source_coordinates)
	{
		coordScale=pfget_int(pf,"coordinate_scale_factor");
	}
	else if (coordUnits==SEGY_TRACE_COORDUNITS_DECIMAL_DEGREES)
	{
		/* Use a sane scalar for decimal degrees. 10000 gives four decimal
		 * places of accuracy, which matches the CSS3.0 spec for lat and lon */
		coordScale=10000;
	}
	else
	{
		coordScale=1;
	}

	/* Print a diagnostic message if the user gave a sub-optimal value for the
	 * coordScale */
	if (coordUnits == SEGY_TRACE_COORDUNITS_DECIMAL_DEGREES &&
			coordScale < 10000)
	{
		elog_alert(0,
				"The supplied parameter 'coordinate_scale_factor' value of %d is less than 10000, and will cause loss of precision for decimal degree coordinates.",
				coordScale);
	}
    else if (coordUnits == SEGY_TRACE_COORDUNITS_ARCSECONDS)
    {
        if (coordScale > 1000) {
            elog_alert(0,
                    "The supplied parameter 'coordinate_scale_factor' value of %d is greater than 1000, and will cause loss of precision for arcsecond coordinates.",
                    coordScale);
        }
    }

	/* trace_gain_type: signed int */
	int16_t trace_gain_type = pfget_int(pf,"trace_gain_type");
	if (trace_gain_type < 0)
	{
		die(0, "The trace_gain_type must be zero or greater");
	}
	else
	{
		trace_gain_type=htons(trace_gain_type);
	}


	/* check list of tables defined in pf.  Return array of
	logicals that define which tables are valid and join
	tables. */
	table_list = check_tables(db,pf);
	check_for_required_tables(table_list);
	dbj = join_tables(db,pf,table_list);
	if(dbj.record == dbINVALID) elog_die(0,"dbjoin error\n");
	if(substr!=NULL) dbj=dbsubset(dbj,substr,0);
	long int ndbrows;
	dbquery(dbj,dbRECORD_COUNT,&ndbrows);
	if(ndbrows<=0)
	{
		elog_complain(1,"Working database view is empty\n");
		if(substr!=NULL) elog_complain(0,"Subset condtion =%s a likely problem\n",
				substr);
		usage();
	}

	fp = fopen(outfile,"w");
	if(fp == NULL)
	{
		elog_complain(0,"Cannot open output file %s\n",outfile);
		usage();
	}

	/* These are needed for sort below */
	pushtbl(sortkeys,"sta");
	pushtbl(sortkeys,"chan");

    /* Set up and write the Textual File Header */
	initialize_text_header(text_file_header, segy_format,
			text_header_description);

	if(write_reel_headers){
		if ( fwrite(text_file_header,1,SEGY_TEXT_HEADER_SIZE,fp) \
				!= SEGY_TEXT_HEADER_SIZE ) {
			elog_die(1,"An error occurred writing the textual file header");
		}
	}

	/* memory allocation for trace data.  This is a large matrix
	that is cleared for each event.  This model works because of
	segy's fixed length format.*/
	traces = calloc(nchan, sizeof(float*));
	if(traces == NULL)
		elog_die(1,"out of memory");
	for (int r = 0; r < nchan; r++)
	{
		traces[r] = calloc(nsamp0, sizeof(float));
		if(traces[r] == NULL)
			elog_die(1,"out of memory");
	}
	header = (SEGYTraceHeader *)calloc((size_t)nchan,sizeof(SEGYTraceHeader));
	if(header == NULL)
			elog_die(0,"Cannot alloc memory for %d segy header workspace\n",nchan);
	if(write_reel_headers)
	{
		if (Verbose) {
			elog_debug(0,"Binary Headers - Using segy_format code 0x%04X\n", ntohs(segy_format));
		}
		initialize_binary_file_header(&reel, segy_format);

		/* now fill in the binary reel header and write it */
		reel.kjob   = htonl(1);
		reel.kline  = htonl(1);
		reel.kreel  = htonl(1);
		reel.kntr   = htons((int16_t)nchan);
		reel.knaux  = htons(0);
		reel.sr     = htons((int16_t)(1000000.0/samprate0));
		reel.kfldsr = reel.sr;
		reel.knsamp = htons((int16_t)nsamp0);
		reel.kfsamp = htons((int16_t)nsamp0);
		reel.dsfc   = htons(5);  /* This is ieee floats*/
		reel.kmfold = htons(0);
		if(map_to_cdp)
			reel.ksort = htons(2);
		else
			reel.ksort = htons(1);
		reel.kunits = htons(1);  /* This sets units to always be meters */

		if(fwrite((void *)(&reel),sizeof(SEGYBinaryFileHeader),1,fp) != 1)
		{
			elog_die(1,"Write error for binary reel header");
		}
	}

	/* Now we enter a loop over stdin reading start times.
	Program will blindly ask for data from each start time to
	time+tlength.  The trace buffer will be initialized to
	zeros at the top of the loop always.  If nothing is found
	only zeros will be written to output.
	*/
	while((stest=fgets(s,80,stdin)) != NULL)
	{
		double slat,slon,selev;  /* Used when reading source location*/
		if(Verbose)
			elog_notify(0,"Processing:  %s\n",s);
		for(i=0;i<nchan;++i)
		{
			initialize_trace_header(&(header[i]), segy_format);
			header[i].gainType = trace_gain_type;
			header[i].lineSeq = htonl(total_traces + i + 1);
			header[i].reelSeq = header[i].lineSeq;
			if(map_to_cdp)
			{
				header[i].cdpEns = htonl(i + 1);
				header[i].traceInEnsemble = htonl(1);/* 1 trace per cdp faked */
			}
			else
			{
				header[i].channel_number = htonl(i + 1);
			}
			header[i].event_number   = htonl(shotid);
			header[i].energySourcePt = htonl(shotid);
			for(j=0;j<nsamp0;++j)  traces[i][j] = htonf((Trsample)0.0);
		}
		if(input_source_coordinates)
		{
			char stmp[40];
			sscanf(s,"%s%ld%lf%lf%lf",stmp,&shotid,&slon,&slat,&selev);
			time0=str2epoch(stmp);
			if(coordUnits == SEGY_TRACE_COORDUNITS_ARCSECONDS) {
				slat*=3600.0;
				slon*=3600.0;
			}
			slat *= (double)coordScale;
			slon *= (double)coordScale;
		}
		else
		{
			time0 = str2epoch(s);
		}
		endtime0 = time0 + tlength;
		sprintf(stime,"%20.4f",time0);
		sprintf(etime,"%20.4f",endtime0);
		trdb.database = -1;
		if(trload_css(dbj,stime,etime,&trdb,0, 0) < 0)
		{
			if(Verbose)
			{
			  elog_notify(0,"trload_css failed for shotid=%ld",shotid);
			  elog_notify(0,"  No data in time range %s to %s\n",
			  	strtime(time0),strtime(endtime0) );
			  elog_notify(0,"No data written for this shotid block.");
			  elog_notify(0,"  Handle this carefully in geometry definitions.\n");
			}

			continue;
		}
		/* This does gap processing */
		repair_gaps(trdb);

		trapply_calib(trdb);

		if(rotate)
		{
			if(rotate_to_standard(trdb,newchan_standard))
				elog_notify(0,"Data loss in rotate_to_standard for event %s to %s\n",
					stime, etime);
			/* This is need to prevent collisions of channel names */
			trdbss = dbsubset(trdb,trsubset,0);
			if(trrotate(trdbss,phi,theta,newchan))
				elog_notify(0,"Data loss in trrotate for event %s to %s\n",
					stime, etime);
		}
		if(Verbose)
			elog_notify(0,"Station  chan_name  chan_number seq_number shotid  evid\n");
		trdb = dbsort(trdb,sortkeys,0,0);
		dbquery(trdb,dbRECORD_COUNT,&ntraces);
		if(Verbose) elog_debug(0,"Read %ld traces for event at time%s\n",
			ntraces,strtime(time0));
		for(trdb.record=0;trdb.record<ntraces;++trdb.record)
		{
			Trsample *trdata;
			if(dbgetv(trdb,0,
			    "evid",&evid,
			    "sta",sta,
			    "chan",chan,
			    "nsamp", &nsamp,
			    "samprate",&samprate,
			    "data",&trdata,
			    "lat", &lat,
			    "lon", &lon,
			    "elev",&elev,
			    "refsta",refsta,
			    "dnorth",&dnorth,
			    "deast",&deast,
			    "edepth",&edepth,
			    "segtype",&segtype,
			    NULL) == dbINVALID)
			{
				elog_complain(0," dbgetv error reading record %ld. Trace will be skipped for station %s and channel %s",
				trdb.record,sta,chan);
				continue;
			}
			/* Allow 1 percent samprate error before killing */
			double fsrskew=fabs((samprate-samprate0)/samprate0);
			double frskewcut=0.01;
			if(fsrskew>frskewcut)
			{
				elog_complain(0,"%s:%s sample rate %f is significantly different from base sample rate of %f. Trace skipped -- segy requires fixed sample rates",
					sta,chan,samprate,samprate0);
				continue;
			}
			if(nsamp > nsamp0)
			{
				elog_complain(0,"%s:%s trace has extra samples=%ld. Truncated to length %d",
					sta, chan, nsamp, nsamp0);
				nsamp = nsamp0;
			}
			else if(nsamp < nsamp0)
			{
				elog_complain(0,"%s:%s trace is shorter than expected %d samples. Zero padded after sample %ld",
					sta, chan, nsamp0, nsamp);
			}

			ichan = get_channel_index(channels,sta,chan);
			if(ichan > nchan)
			{
				elog_die(0,"Channel index %d outside limit of %d. Cannot continue",
					ichan, nchan);
			}
			if(ichan >= 0)
			{
				if(Verbose)
					elog_debug(0,"%s:%s\t%-d\t%-d\t%-ld\t%-ld\n",
					sta,chan,ichan+1,
					ntohl(header[ichan].reelSeq),
					shotid, evid);
				header[ichan].traceID = get_trace_id_code_from_segtype(segtype);
				for(j=0;j<nsamp;++j) {
				   traces[ichan][j] = htonf((float)trdata[j]);
				}
				/* header fields coming from trace table */
				header[ichan].samp_rate = htonl(
						(int32_t) (1000000.0/samprate0));
				/* according to the behavior specified in the man page:
				 * if use_geo_coordinates is false:
				 * - coordUnits is length (meters)
				 * - therefore, we use deast for X and dnorth for Y
				 * if use_geo_coordinates is true:
				 * - we're using either arcseconds or decimal degrees
				 * - and therefore, we use lon for X and lat for Y
				 *
				 * coordUnits is based on use_arcseconds and the requested
				 * version of segY */

				/* set the coordinate units in the trace header */
				header[ichan].coordUnits = coordUnits;

				/* Pick the source db fields for our receiver X and Y */
				double recLongOrX = 0;
				double recLatOrY  = 0;
				if (coordUnits == SEGY_TRACE_COORDUNITS_LENGTH) {
					/* Use deast and dnorth
					 * CSS3.0 Schema specifies deast and dnorth are in KM.
					 * SEG-Y specifies easting and northing as meters,
					 * hence the 1000.0 multiplier here. */
					recLongOrX = deast  * 1000.0;
					recLatOrY  = dnorth * 1000.0;
				} else if (coordUnits == SEGY_TRACE_COORDUNITS_ARCSECONDS){
					/* Use lat and lon, converted to arcseconds */
					recLongOrX = lon * 3600.0;
					recLatOrY  = lat * 3600.0;
				} else {
					/* Default case, which covers decimal degrees */
					recLongOrX = lon;
					recLatOrY  = lat;
				}

				/* Apply our coordScale - the user can specify negative numbers,
				 * but they are treated as inverting the value, not as a divisor
				 * as in the SEG-Y field usage. See below where we always treat
				 * the scalar as a divisor in the SEG-Y field */
				recLongOrX *= (double)coordScale;
				recLatOrY  *= (double)coordScale;

				/* Set the coordScale in the header.
				 * Note negative here.  This is a oddity of segy that - means
				 * divide by this to get actual.  Always make this negative in
				 * case user inputs a negative number.
				 * Don't set it -1 for cosmetic reasons */
				if (abs(coordScale) == 1)
				{
					header[ichan].coordScale = htons(1);
				} else
				{
					header[ichan].coordScale = htons(-abs(coordScale));
				}

				/* Finally, write out the X and Y */
				header[ichan].recLongOrX
					= htonl((int32_t)recLongOrX);
				header[ichan].recLatOrY
					= htonl((int32_t)recLatOrY);

				/* CSS3.0 specfies elev as being in km, SEG-Y wants it in m */
				header[ichan].recElevation = htonl((int32_t)(elev*1000.0));

				header[ichan].deltaSample = htons(
						(int16_t) (1000000.0/samprate0));
				header[ichan].sampleLength = htons((int16_t)nsamp0);
				if (ntohs(segy_format)<0x0100)
				{
					header[ichan].num_samps = htonl((int32_t)nsamp0);
				}
				/* This cracks the time fields */
				time_str = epoch2str(time0,fmt);
				int16_t hyear, hday, hhour, hminute, hsecond, hm_secs;
				hyear=hday=hhour=hminute=hsecond=hm_secs=0;
				sscanf(time_str,"%hd %hd %hd %hd %hd %hd",
						&hyear, &hday, &hhour, &hminute, &hsecond, &hm_secs);
				header[ichan].year   = htons(hyear);
				header[ichan].day    = htons(hday);
				header[ichan].hour   = htons(hhour);
				header[ichan].minute = htons(hminute);
				header[ichan].second = htons(hsecond);
				header[ichan].m_secs = htons(hm_secs);
				if (ntohs(segy_format)<0x0100)
				{
					/* These are IRIS-PASSCAL extensions */
					header[ichan].trigyear   = header[ichan].year;
					header[ichan].trigday    = header[ichan].day;
					header[ichan].trighour   = header[ichan].hour;
					header[ichan].trigminute = header[ichan].minute;
					header[ichan].trigsecond = header[ichan].second;
				}
				free(time_str);
				if(input_source_coordinates)
				{
					/* Write out our pre-scaled and optionally
					 * arcsecond-converted source lat/lon plus our elevation */
					header[ichan].sourceLongOrX = htonl((int32_t)slon);
					header[ichan].sourceLatOrY  = htonl((int32_t)slat);
					header[ichan].sourceSurfaceElevation
						= htonl((int32_t)selev);
					/* No easy way to specify both elev and depth*/
					header[ichan].sourceDepth=htonl(0);
				}
				else if(map_to_cdp)
				{
				/* When faking CDP data we make this look
				like a zero offset, single fold data set */
					header[ichan].sourceLongOrX   = header[ichan].recLongOrX;
					header[ichan].sourceLatOrY    = header[ichan].recLatOrY;
					header[ichan].sourceSurfaceElevation
					                              = header[ichan].recElevation;
					header[ichan].sourceDepth     = htonl(0);
					header[ichan].sourceToRecDist = htonl(0);
				}
				else
				{
				/* This is the mechanism for adding other
				information with added tables.  The one
				table currently supported is a "shot" table
				that holds shot coordinates.  If other tables
				were added new functions could be added with
				a similar calling sequence.  This procedure
				silently does nothing if a shot table is not
				present.*/
					set_shot_variable(db,table_list,
						evid,&header[ichan]);
				}
			}
			else
			{
				if(Verbose)
					elog_notify(0,"Station %s and channel %s skipped\n",
						sta,chan);
			}

		}
		/* Now we write the data */
		for(i=0;i<nchan;++i)
		{
			if(fwrite((void *)(&(header[i])),sizeof(SEGYTraceHeader),1,fp) != 1)
				elog_die(0,"Write error on header for trace %d\n",total_traces+i);
			if(fwrite((void *)traces[i],sizeof(float),
					(size_t)nsamp0,fp) != nsamp0)
				elog_die(0,"Write error while writing data for trace %d\n",
					total_traces+i);
		}
		total_traces += nchan;
		trdestroy(&trdb);
		if(!input_source_coordinates) ++shotid;
	}
	return 0 ;
}
int main(int argc, char **argv)
{
	SegyReel reel;
	SegyHead *header;
	char *dbin;
	char *outfile;
	FILE *fp;
	Pf *pf;  
	Arr *channels;  /* channel order list */
	Arr *table_list;  /* array of valid tables */
	int nchan;
	char *stest;

	float **traces;
	char reel1[3200];
	Dbptr db, trdb, dbj;
	Dbptr trdbss;  
	int nsamp0;
	double time0, endtime0, samprate0;
	long int nsamp;
	double samprate;
	int i,j;
	char stime[30],etime[30];
	char s[128];
	double tlength;
	double phi, theta;
	char *newchan_standard[3]={"X1","X2","X3"};
	char *trsubset="chan=~/X./";
	char *newchan[3]={"R","T","Z"};
	Tbl *sortkeys=newtbl(0);
	char sta[10],chan[10];
	double lat, lon, elev, dnorth, deast, edepth;
	char refsta[10];
	int total_traces=0;
	char *time_str;
	long int evid,shotid=1;
	int rotate=0;
	long int ntraces;
        int ichan;
	int map_to_cdp;  /* logical switch to output data like cdp stacked data */
	char *fmt="%Y %j %H %M %S %s";
	char *pfname;
	int Verbose=0;
	/* New features added 2009 */
	/* this is a boolean.  If true (nonzero) it is assumed stdin will
	contain four numbers:  time,lat, lon, elev.  If false, only the
	time field is read and remainder of any input on each line is dropped.*/
	int input_source_coordinates;
	/* scale factor for source coordinates.  Needed because segy uses
	an int to store source coordinates.  Sensible choices are 
	3600 for arc seconds and 10000 for a pseudodecimal. Note this
	parameter is ignored unless input_source_coordinates is true.*/
	int coordScale;
	/* If true use passcal 32 bit extension num_samps as record length. 
	SEGY standard uses a 16 bit entry that easily overflows with large
	shots at long offset.  In this ase assume the 16 bit quantity is
	meaningless. */
	int use_32bit_nsamp;
	/* This is switched on by argument switch.  When set to a nonzero
	(default) the reel headers are written.  When 0 `
	the reel heades will not be written -- used by seismic unix 
r
	and passcal*/
	int write_reel_headers=1;
	char *substr=NULL;

	if(argc < 3) usage();
	dbin = argv[1];
	outfile = argv[2];
	pfname = NULL;
	for(i=3;i<argc;++i)
	{
		if(!strcmp(argv[i],"-pf"))
		{
			++i;
			pfname = argv[i];
		}
		else if(!strcmp(argv[i],"-SU"))
		{
			write_reel_headers=0;
		}
		else if(!strcmp(argv[i],"-v"))
		{
			Verbose=1;
		}
		else if(!strcmp(argv[i],"-ss"))
		{
			++i;
			substr=argv[i];
		}
		else
		{
			usage();
		}
	}
	if(pfname == NULL) pfname = strdup("db2segy");

	elog_init(argc, argv);

	if(pfread(pfname,&pf)) 
		elog_die(0,"pfread error for pf file %s.pf\n",argv[0]);
	/* rotation parameters */
	rotate=pfget_boolean(pf,"rotate");
	if(rotate)
	{
		phi = pfget_double(pf,"phi");
		theta = pfget_double(pf,"theta");
	}
	/* This function creates the channel order list keyed by
	station channel names */
	channels = build_stachan_list(pf,&nchan,Verbose);

	map_to_cdp = pfget_boolean(pf,"map_to_cdp");
	if(map_to_cdp && Verbose) 
		fprintf(stdout,"Casting data as CDP stacked section\n");
	if(dbopen(dbin,"r",&db) == dbINVALID) 
	{
		fprintf(stderr,"Cannot open db %s\n", dbin);
		usage();
	}
	/* We grab the sample rate and trace length (in seconds) and
	use this to define global sample rates for the data.  
	segy REQUIRES fixed length records and sample rates, so
	irregular sample rates will cause this program to die. 
	One could add a decimate/interpolate function, but this 
	is not currently implemented */
	samprate0 = pfget_double(pf,"sample_rate");
	tlength = pfget_double(pf,"trace_length");
	nsamp0 = (int)(tlength*samprate0);
	use_32bit_nsamp=pfget_boolean(pf,"use_32bit_nsamp");

	/* nsamp in segy is a 16 bit field.  Handling depends on
	setting of use_32bit_nsamp boolean */
	if(nsamp0 > 32767) 
	{
	    if(use_32bit_nsamp)
	    {
	    	elog_notify(0,"Warning:  segy ues a 16 bit entity to store number of samples\nThat field is garbage. Using the 32 bit extension field.\n");
	    }
	    else
	    {
		elog_complain(0,
		  "Warning:  segy uses a 16 bit entity to store number of samples\nRequested %d samples per trace.  Trucated to 32767\n",nsamp0);
		nsamp0 = 32767;
	    }
	}
	input_source_coordinates=pfget_boolean(pf,"input_source_coordinates");
	if(input_source_coordinates)
	{
		coordScale=pfget_int(pf,"coordinate_scale_factor");
	}
	else
	{
		coordScale=1;
	}
	/* boolean.  When nonzero set coordinates as geographic arc seconds values */
	int use_geo_coordinates=pfget_boolean(pf,"use_geo_coordinates");
	/* check list of tables defined in pf.  Return array of
	logicals that define which tables are valid and join 
	tables. */
	table_list = check_tables(db,pf);
	check_for_required_tables(table_list);
	dbj = join_tables(db,pf,table_list);
	if(dbj.record == dbINVALID) elog_die(0,"dbjoin error\n");
	if(substr!=NULL) dbj=dbsubset(dbj,substr,0);
	long int ndbrows;
	dbquery(dbj,dbRECORD_COUNT,&ndbrows);
	if(ndbrows<=0)
	{
		fprintf(stderr,"Working database view is empty\n");
		if(substr!=NULL) fprintf(stderr,"Subset condtion =%s a likely problem\n",
				substr);
		usage();
	}

	fp = fopen(outfile,"w");
	if(fp == NULL) 
	{
		fprintf(stderr,"Cannot open output file %s\n",outfile);
		usage();
	}

	/* These are needed for sort below */
	pushtbl(sortkeys,"sta");
	pushtbl(sortkeys,"chan");

	/*The reel1 header in true blue segy is ebcdic.  We are goingto 
	just fill it with nulls and hope for the best */
	for(i=0;i<3200;i++) reel1[i] = '\0';

	/* Just blindly write this turkey. Bad form, but tough*/
	if(write_reel_headers) fwrite(reel1,1,3200,fp);

	/* memory allocation for trace data.  This is a large matrix
	that is cleared for each event.  This model works because of
	segy's fixed length format.  This routine is a descendent of
	numerical recipes routine found in libgenloc.  This is not
	the most efficient way to do this, but it simplifies the
	algorithm a lot. */
	traces = matrix(0,nchan,0,nsamp0);
	if(traces == NULL) 
		elog_die(0,"Cannot alloc trace data matrix work space of size %d by %d\n",
			nchan, nsamp0);
	header = (SegyHead *)calloc((size_t)nchan,sizeof(SegyHead));
	if(header == NULL)
			elog_die(0,"Cannot alloc memory for %d segy header workspace\n",nchan);
	if(write_reel_headers)
	{

		/* now fill in the binary reel header and write it */
		reel.kjob = 1;
		reel.kline = 1;
		reel.kreel = 1;
		reel.kntr = (int16_t)nchan;
		reel.knaux = 0;
		reel.sr = (int16_t)(1000000.0/samprate0);
		reel.kfldsr = reel.sr;
		reel.knsamp = (int16_t)nsamp0;
		reel.kfsamp = (int16_t)nsamp0;
		reel.dsfc=5;  /* This is ieee floats*/
		reel.kmfold = 0;
		if(map_to_cdp)
			reel.ksort = 2;
		else
			reel.ksort = 1;
		reel.kunits = 1;  /* This sets units to always be meters */
		for(i=0;i<344;++i)reel.unused2[i]='\0';
	
		if(fwrite((void *)(&reel),sizeof(SegyReel),1,fp) != 1) 
		{
			fprintf(stderr,"Write error for binary reel header\n");
			exit(-2);
		}
	}

	/* Now we enter a loop over stdin reading start times.  
	Program will blindly ask for data from each start time to 
	time+tlength.  The trace buffer will be initialized to 
	zeros at the top of the loop always.  If nothing is found
	only zeros will be written to output.  
	*/
	while((stest=fgets(s,80,stdin)) != NULL)
	{
		double slat,slon,selev;  /* Used when reading source location*/
		if(Verbose)
			fprintf(stdout,"Processing:  %s\n",s);
		for(i=0;i<nchan;++i)
		{
			initialize_header(&(header[i]));
			header[i].lineSeq = total_traces + i + 1;
			header[i].reelSeq = header[i].lineSeq;
			if(map_to_cdp)
			{
				header[i].cdpEns = i + 1;
				header[i].traceInEnsemble = 1;  /* 1 trace per cdp faked */
			}
			else
			{
				header[i].channel_number = i + 1;
			}
			header[i].event_number = shotid;
			header[i].energySourcePt=shotid;
			for(j=0;j<nsamp0;++j)  traces[i][j] = (Trsample)0.0;
		}
		if(input_source_coordinates)
		{
			char stmp[40];
			sscanf(s,"%s%ld%lf%lf%lf",stmp,&shotid,&slon,&slat,&selev);
			time0=str2epoch(stmp);
		}
		else
		{
			time0 = str2epoch(s);
		}
		endtime0 = time0 + tlength;
		sprintf(stime,"%20.4f",time0);
		sprintf(etime,"%20.4f",endtime0);
		trdb.database = -1;
		if(trload_css(dbj,stime,etime,&trdb,0, 0) < 0)
		{
			if(Verbose) 
			{
			  fprintf(stdout,"trload_css failed for shotid=%ld",shotid);
			  fprintf(stdout,"  No data in time range %s to %s\n",
			  	strtime(time0),strtime(endtime0) );
			  fprintf(stdout,"No data written for this shotid block.");
			  fprintf(stdout,"  Handle this carefully in geometry definitions.\n");
			}

			continue;
		}
		/* This does gap processing */
		repair_gaps(trdb);
		
		trapply_calib(trdb);
			
		if(rotate)
		{
			if(rotate_to_standard(trdb,newchan_standard))
				elog_notify(0,"Data loss in rotate_to_standard for event %s to %s\n",
					stime, etime);
			/* This is need to prevent collisions of channel 
			names */
			trdbss = dbsubset(trdb,trsubset,0);
			if(trrotate(trdbss,phi,theta,newchan))
				elog_notify(0,"Data loss in trrotate for event %s to %s\n",
					stime, etime);
		}
		if(Verbose)
			fprintf(stdout,"Station  chan_name  chan_number seq_number shotid  evid\n");
		trdb = dbsort(trdb,sortkeys,0,0);
		dbquery(trdb,dbRECORD_COUNT,&ntraces);
		if(Verbose) fprintf(stdout,"Read %ld traces for event at time%s\n",
			ntraces,strtime(time0));
		for(trdb.record=0;trdb.record<ntraces;++trdb.record)
		{
			Trsample *trdata;
			if(dbgetv(trdb,0,
			    "evid",&evid,
			    "sta",sta,
			    "chan",chan,
			    "nsamp", &nsamp,
			    "samprate",&samprate,
			    "data",&trdata,
			    "lat", &lat,
			    "lon", &lon,
			    "elev",&elev,
			    "refsta",refsta,
			    "dnorth",&dnorth,
			    "deast",&deast,
			    "edepth",&edepth,
					NULL) == dbINVALID)
			{
				elog_complain(0," dbgetv error reading record %ld\nTrace will be skipped for station %s and channel %s\n",
				trdb.record,sta,chan);
				continue;
			}
			/* Allow 1 percent samprate error before killing */
			double fsrskew=fabs((samprate-samprate0)/samprate0);
			double frskewcut=0.01;
			if(fsrskew>frskewcut) 
			{
				elog_complain(0,"%s:%s sample rate %f is significantly different from base sample rate of %f\nTrace skipped -- segy requires fixed sample rates\n",
					sta,chan,samprate,samprate0);
				continue;
			}
			if(nsamp > nsamp0)
			{
				elog_complain(0,"%s:%s trace has extra samples=%ld\nTruncated to length %d\n",
					sta, chan, nsamp, nsamp0);
				nsamp = nsamp0;
			}
			else if(nsamp < nsamp0)
			{
				elog_complain(0,"%s:%s trace is shorter than expected %d samples\nZero padded after sample %ld\n",
					sta, chan, nsamp0, nsamp);
			}

			ichan = get_channel_index(channels,sta,chan);
			if(ichan > nchan) elog_die(0,"Channel index %d outside limit of %d\nCannot continue\n",
					ichan, nchan);
			if(ichan >= 0)
			{
				if(Verbose) 
				   fprintf(stdout,"%s:%s\t%-d\t%-d\t%-ld\t%-ld\n",
					sta,chan,ichan+1,
                                        header[ichan].reelSeq,
					shotid, evid);
				header[ichan].traceID = 1;
				for(j=0;j<nsamp;++j) 
				   traces[ichan][j] = (float)trdata[j];
				/* header fields coming from trace table */
				header[ichan].samp_rate = (int32_t)
						(1000000.0/samprate0);
				if(!use_geo_coordinates && ( coordScale==1))
				{
				  header[ichan].recLongOrX = (int32_t)(deast*1000.0);
				  header[ichan].recLatOrY = (int32_t)(dnorth*1000.0);
				}
				else
				{
				/* Note negative here.  This is a oddity
				of segy that - means divide by this to
				get actual.  Always make this negative in case 
				user inputs a negative number. */
				  header[ichan].coordScale=-abs(coordScale);
				  /* Force 2 = geographic coordinates.  Standard says when this is
				  so units are arc seconds, hence we multiply deg by 3600*coordScale */
				  if(use_geo_coordinates)
				  {
				    header[ichan].coordUnits=2;
				    header[ichan].recLongOrX
				     =(int32_t)(lon*3600.0*(double)coordScale);
				    header[ichan].recLatOrY
				     =(int32_t)(lat*3600.0*(double)coordScale);
				  }
				  else
				  {
				    header[ichan].recLongOrX
				     =(int32_t)(lon*(double)coordScale);
				    header[ichan].recLatOrY
				     =(int32_t)(lat*(double)coordScale);
				  }
				}
				header[ichan].recElevation = (int32_t)(elev*1000.0);
				header[ichan].deltaSample = (int16_t) 
						(1000000.0/samprate0);
				header[ichan].sampleLength = (int16_t)nsamp0;
				header[ichan].num_samps = (int32_t)nsamp0;
				/* This cracks the time fields */
				time_str = epoch2str(time0,fmt);
				sscanf(time_str,"%hd %hd %hd %hd %hd %hd",
					&header[ichan].year,
					&header[ichan].day,
					&header[ichan].hour,
					&header[ichan].minute,
					&header[ichan].second,
					&header[ichan].m_secs);
				/* These are PASSCAL extensions, but we'll
				go ahead and set them anyway.*/
				header[ichan].trigyear = header[ichan].year;
				header[ichan].trigday = header[ichan].day;
				header[ichan].trighour = header[ichan].hour;
				header[ichan].trigminute = header[ichan].minute;
				header[ichan].trigsecond = header[ichan].second;
				free(time_str);
				if(input_source_coordinates)
				{
				  if(use_geo_coordinates)
				  {
					slat*=3600.0;
					slon*=3600.0;
				  }
				  header[ichan].sourceLongOrX
				    =(int32_t)(slon*(double)coordScale);
				  header[ichan].sourceLatOrY
				    =(int32_t)(slat*(double)coordScale);
				  header[ichan].sourceSurfaceElevation
				             =(int32_t)selev;
				  /* No easy way to specify both elev and depth*/
				  header[ichan].sourceDepth=0;
				}
				else if(map_to_cdp)
				{
				/* When faking CDP data we make this look 
				like a zero offset, single fold data set */
				  header[ichan].sourceLongOrX = header[ichan].recLongOrX;
				  header[ichan].sourceLatOrY = header[ichan].recLatOrY;
				  header[ichan].sourceSurfaceElevation = header[ichan].recElevation;
				  header[ichan].sourceDepth = 0;
				  header[ichan].sourceToRecDist = 0;
				}
				else
				{
				/* This is the mechanism for adding other
				information with added tables.  The one
				table currently supported is a "shot" table 
				that holds shot coordinates.  If other tables
				were added new functions could be added with
				a similar calling sequence.  This procedure
				silently does nothing if a shot table is not
				present.*/
					set_shot_variable(db,table_list,
						evid,&header[ichan]);
				}
			}			
			else
			{
				if(Verbose)
					fprintf(stdout,"Station %s and channel %s skipped\n",
						sta,chan);
			}

		}
		/* Now we write the data */
		for(i=0;i<nchan;++i)
		{
			if(fwrite((void *)(&(header[i])),sizeof(SegyHead),1,fp) != 1)
				elog_die(0,"Write error on header for trace %d\n",total_traces+i);		
			if(fwrite((void *)traces[i],sizeof(float),
					(size_t)nsamp0,fp) != nsamp0)
				elog_die(0,"Write error while writing data for trace %d\n",
					total_traces+i);
		}
		total_traces += nchan;
		trdestroy(&trdb);		
		if(!input_source_coordinates) ++shotid;
	}
	return 0 ;
}
Example #7
0
int main (int argc, char **argv) {
	int             c,
                    errflg = 0;
    Dbptr      db, tr;
    char       *database,*outfile, *pfname=0;
    Flags	   flags ;
    Pf          *pf,*pf_def,*pf_sta=NULL,*pf_stas;
    Tbl		   *input;
    char	   *start, *stop, *triggertimestring=NULL ;
    char	   *subset=0 ;
    long	    nrecords,nsamp1 ;
	int 		duration,nframes,sampsperframe;
	double		tstart, tstop, triggertime=0;
	char 		sta[STA_LEN],sta1[STA_LEN];
	char 		chan[STA_LEN],chan1[STA_LEN];
	double 		samprate,samprate1,t1,t2;
	FILE 			*fout;
	size_t			nw;
	unsigned char *hdrbuf=malloc(2040);
	unsigned char *framebuf=malloc(32);
	unsigned char *tagbuf=malloc(16);
	unsigned short cksum;
	unsigned char wfarr[3 * 12 * 100]; /*1000sps * 0.1 sec * 12 chan * 3bytes*/
	int sampindex=0;

	K2EvtFile *myhdr=malloc(2040);
	K2EvtTag *mytag=malloc(sizeof(K2EvtTag));
	K2EvtFrame *myframe=malloc(sizeof(K2EvtFrame));
	float *data[12] ;
	unsigned short channelBitmap=0;
	int	pf_serialno,pf_sensortype;
	double pf_sensitivity, pf_fullscale, pf_lat, pf_lon, pf_elev;

    memset ( &flags, 0, sizeof(flags)); 
    elog_init ( argc, argv ) ; 


    while ((c = getopt (argc, argv, "do:p:s:t:v")) != -1) {
		switch (c) {

			case 'd':
				flags.display = 1 ; 
				break ; 

			case 'p':
				pfname= optarg ;
				break;

			case 's':
				subset = optarg ; 
				break ;

			case 't':
				triggertimestring = optarg ; 
				break ;

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

			default:
				errflg++;
				break ;
		}
    }

    if (errflg || argc-optind != 4)
		usage ();

	if (pfname==NULL) {
		pfname=Program_Name;
	}
    if (pfread (pfname, &pf) != 0)
		die (0, "Can't read parameter file %s\n",pfname);

	database = argv[optind++];
	outfile = argv[optind++];
	start = argv[optind++];
	stop = argv[optind++];
	tstart=str2epoch(start);
	tstop=str2epoch(stop);
	tstart=ceil(tstart);	/* make sure we have second boundaries, 
							   this also makes sure we have a integer number of frames */
	tstop=floor(tstop);
	duration=tstop - tstart;
    if ( dbopen(database, "r", &db) ) { 
        die ( 0, "Can't open database %s", database ) ;
    }

	input = pfget_tbl (pf, "view" ) ;
  	db = dbprocess ( db, input, 0 ) ;

	if (subset) {
		db=dbsubset(db,subset,0);
	}

    tr = dbinvalid() ;
    if ( trload_css ( db, start, stop, &tr, 0, 0 ) ) { 
		die ( 1, "trload_css failed" ) ; 
    }

    if ( trsplit(tr, 0, 0) ) { 
		complain ( 0, "trsplit failed" ) ; 
    }

    if ( trsplice(tr, 0, 0, 0) ) { 
		complain ( 0, "trsplice failed" ) ; 
    }

    if ( flags.display ) { 
		trdisp (tr, "will try to convert this stuff to evt") ;
    }
	tr.record=0;
	dbgetv(tr,0,"time",&t1,"endtime",&t2,"sta",sta1,"chan",chan1,"samprate",&samprate1,"nsamp",&nsamp1,NULL);
	samprate1=round(samprate1);
	

	dbquery ( tr, dbRECORD_COUNT, &nrecords ) ; 
	if (nrecords > 12) {
		printf("will only use the first 12 channels, consider modifying the subset...");
		nrecords=12;
	}
	for ( tr.record = 0 ; tr.record < nrecords ; tr.record++ ) { 
		double ts,te;
		dbgetv(tr,0,"time",&ts,"endtime",&te,"samprate",&samprate,"sta",sta,"chan",chan,NULL);
		samprate=round(samprate);
		if (t1 != ts || t2 != te) {
			die ( 0, "this simplistic version only works with 101% correct times and/or subsets, sorry..." ) ;
		}	
		if (strcmp(sta,sta1) !=0) {
			die ( 0, "%s <=> %s this simplistic version only works with ONE station, but the subset left more",sta,sta1 ) ;
		}
		if (samprate != samprate1) {
			die ( 0, "all channels in a K2-EVT File MUST have the same samplerate!" );
		}
	}

	newFileHeader(&myhdr, pf, sta);

	if (parse_param (pf, "sta_defaults", P_ARRPF, 1, &pf_def) < 0) {
		elog_die (0, "error parsing array sta_defaults.\n");
	}
	if (parse_param (pf, "sta_params", P_ARRPF, 1, &pf_stas) < 0) {
		elog_die (0, "error parsing array sta_params.\n");
	}
	if (parse_param (pf_stas, sta, P_ARRPF, 0, &pf_sta) < 0) {
		elog_die (0, "error parsing sta_params{%s}\n.",sta);
	}

	if (parse_param(pf_def,"sensortype",P_LINT,1,&pf_sensortype)< 0 ) {
		        elog_die (0, "error parsing default sensortype.\n");
	}
	if (parse_param(pf_def,"serialno",P_LINT,1,&pf_serialno)< 0 ) {
		        elog_die (0, "error parsing default serialno.\n");
	}
	if (parse_param(pf_def,"sensitivity",P_DBL,1,&pf_sensitivity)< 0 ) {
		        elog_die (0, "error parsing default sensitivity.\n");
	}
	if (parse_param(pf_def,"fullscale",P_DBL,1,&pf_fullscale)< 0 ) {
		        elog_die (0, "error parsing default fullscale.\n");
	}
	if (parse_param(pf_def,"lat",P_DBL,1,&pf_lat)< 0 ) {
		        elog_die (0, "error parsing default lat.\n");
	}
	if (parse_param(pf_def,"lon",P_DBL,1,&pf_lon)< 0 ) {
		        elog_die (0, "error parsing default lon.\n");
	}
	if (parse_param(pf_def,"elev",P_DBL,1,&pf_elev)< 0 ) {
		        elog_die (0, "error parsing default elev.\n");
	}
	if (pf_sta==NULL) {
		elog_notify (0, "can't parse array sta_params{%s}, will use defaults\n.",sta);
		pf_sta=pf_def;

	} else {
		if (parse_param(pf_def,"sensortype",P_LINT,0,&pf_sensortype)< 0 ) {
					elog_die (0, "error parsing sensortype.\n");
		}
		if (parse_param(pf_sta,"serialno",P_LINT,0,&pf_serialno)< 0 ) {
					elog_die (0, "error parsing serialno.\n");
		}
		if (parse_param(pf_sta,"sensitivity",P_DBL,0,&pf_sensitivity)< 0 ) {
					elog_die (0, "error parsing sensitivity.\n");
		}
		if (parse_param(pf_sta,"fullscale",P_DBL,0,&pf_fullscale)< 0 ) {
					elog_die (0, "error parsing fullscale.\n");
		}
		if (parse_param(pf_sta,"lat",P_DBL,0,&pf_lat)< 0 ) {
					elog_die (0, "error parsing lat.\n");
		}
		if (parse_param(pf_sta,"lon",P_DBL,0,&pf_lon)< 0 ) {
					elog_die (0, "error parsing lon.\n");
		}
		if (parse_param(pf_sta,"elev",P_DBL,0,&pf_elev)< 0 ) {
					elog_die (0, "error parsing elev.\n");
		}
	}
	myhdr->rw_stream.sps=samprate;		/* sampling rate */
	myhdr->rw_stream.preEvent=1;	/* in seconds */
	myhdr->rw_stream.postEvent=5;	/* in seconds */
	myhdr->rw_stream.minRunTime=6;	/* in seconds */
	myhdr->ro_stream.duration=duration;
	myhdr->ro_stream.nscans=duration* 10;
	myhdr->ro_stream.startTime=epoch2k2time(t1);
	myhdr->ro_stream.startTimeMsec=0;
	int ttms=0;
	if (triggertimestring) {
		triggertime=str2epoch(triggertimestring);
		ttms=remainder(triggertime,1.0 ) * 1000.0; 
		triggertime=epoch2k2time(triggertime);
	} else {
		triggertime=epoch2k2time(t1)+5;
		ttms=0;
	}
	myhdr->ro_stream.triggerTime=triggertime;
	myhdr->ro_stream.triggerTimeMsec=ttms;
	myhdr->rw_misc.nchannels=nrecords;
	for (int channo=0;channo< nrecords;channo++) {
		myhdr->rw_channel[channo].sensitivity=pf_sensitivity;	
		myhdr->rw_channel[channo].sensitivity=pf_fullscale;	
	}
	myhdr->rw_misc.elevation=pf_elev;		/* meters above sea level */
	myhdr->rw_misc.latitude=pf_lat;			/* degrees north */
	myhdr->rw_misc.longitude=pf_lon;		/* degrees east */

	nframes=duration * 10;
	myhdr->ro_stream.duration=nframes;
	myhdr->ro_stream.nscans=duration*samprate;

	channelBitmap=chanbitmap(nrecords);

	for ( tr.record = 0 ; tr.record < nrecords ; tr.record++ ) { 
		unsigned long i ; 
		int nsamp;
		char chan[7];
		unsigned long minoffset=0;
		unsigned long maxoffset=0;
		int	max=INT_MIN;
		int min=INT_MAX;
	    dbgetv(tr, 0, "chan",chan,"data", &data[tr.record], "nsamp", &nsamp, NULL ) ; 
	    for ( i=0 ; i<nsamp ; i++ ) { 
			if (data[tr.record][i] > max) {
				max=data[tr.record][i];
				maxoffset=i;
			}
			if (data[tr.record][i] < min) {
				min=data[tr.record][i];
				minoffset=i;
			}
			
	    }
		myhdr->ro_channel[tr.record].maxPeak=max;
		myhdr->ro_channel[tr.record].maxPeakOffset=maxoffset;
		myhdr->ro_channel[tr.record].minPeak=min;
		myhdr->ro_channel[tr.record].minPeakOffset=minoffset;
		memcpy(myhdr->rw_channel[tr.record].id,chan,K2EVT_CHANNEL_ID_LENGTH);
	}
	for ( tr.record = 0 ; tr.record < nrecords ; tr.record++ ) { 

	}

	newTag(&mytag,0, 2040, 0, 128,1234);
	encodek2header(hdrbuf,myhdr);
	cksum=k2_checksum(hdrbuf,2040);
	
	mytag->length=2040;/*header size*/
	mytag->dataLength=0;
	mytag->checksum=cksum;
	encodek2tag(tagbuf,mytag);
	fout=fopen(outfile,"w+");
	nw=fwrite(tagbuf,16,1,fout);
	nw=fwrite(hdrbuf,2040,1,fout);

	
	double t=t1 ;
	double k2t=round(epoch2k2time(t));
	newFrameHeader(&myframe,128,(sampsperframe*3*nrecords)+32, k2t);
	sampsperframe=TIME2SAMP(0,samprate,0.1);/*samples per frame*/
	
	for (int fn=0;fn < nframes;fn++) {
		cksum=0;
		sampindex=0;
		for (int s=0;s<sampsperframe;s++) {
			long val;
			unsigned char buf[4];
			for ( int channo = 0 ; channo < nrecords ; channo++ ) { 
				int index=((fn*sampsperframe) + s);
				val=round(data[channo][index]);
				/*debugging...*/
				//val=66051;/*0x010203*/
				memcpy(&buf,&val,4);
				val <<=8;
#ifdef WORDS_BIGENDIAN
				cksum+=buf[1];
				cksum+=buf[2];
				cksum+=buf[3];
				wfarr[sampindex++]=buf[1];
				wfarr[sampindex++]=buf[2];
				wfarr[sampindex++]=buf[3];
#else
				cksum+=buf[2];
				cksum+=buf[1];
				cksum+=buf[0];
				wfarr[sampindex++]=buf[2];
				wfarr[sampindex++]=buf[1];
				wfarr[sampindex++]=buf[0];
#endif
			}
		}

		mytag->checksum=cksum;
		mytag->length=32;/*header size*/
		mytag->dataLength=sampsperframe * nrecords * 3;
		myframe->frameSize=(sampsperframe*3*nrecords)+32;
		myframe->blockTime=round(k2t);
		myframe->msec=fmod(k2t,1.0) * 1000;
		myframe->channelBitMap=channelBitmap;
		
		encodek2Frame(framebuf,myframe);
		mytag->checksum+=k2_checksum(framebuf,32);
		encodek2tag(tagbuf,mytag);
		k2t+=0.1;
		//k2t=round((k2t+0.1)*10.0)/10.0;
		nw=fwrite(tagbuf,1,16,fout);
		if (nw!= 16) {
			die(0,"could not write file tag, wrote %d bytes instead of 16",nw);
		}
		nw=fwrite(framebuf,32,1,fout);
		nw=fwrite(&wfarr, 1,sampsperframe * 3 * nrecords, fout);
	}
	
	
	fclose(fout);

    tr.table = dbALL ;
    trfree(tr) ;
    pffree(pf) ; 
    return 0;
}
int main(int argc, char **argv)
{
	char *dbin;  /* Input db name */
	char *dbout;  /* output db name */
	Dbptr db;  /* input db pointer */
	Dbptr dbo;  /* base output db pointer */
	Dbptr dbv;  /* set to view formed by join */
	char *pfin=NULL;  /* input parameter file */
	char *sift_exp;  /* sift expression for subset */
	int sift = 0;  /* default is no sift.  */
	Tbl *sortkeys;
	Tbl *joinkey1, *joinkey2;
	/*Pointers to views returned by dbgroup (keyed to origin and event
	respectively */
	Dbptr dborigin_group;
	Tbl *origin_group;  /* relation keys used in grouping*/
	long nevents;
	/* db row variables */
	long evid;
	long nrows, nrows_raw;

	int useold=0;
	Pf *pf;
	Tbl *ta,*tu;
	Tbl *reason_converged, *residual;
	Location_options o;
	Arr *arr_phase;
	int i;
	Tbl *converge_history;

	Hypocenter h0;
	Hypocenter *hypos;
	long niterations;

	char *vmodel;

	int ret_code;  /* ggnloc return code */
	double **C;   /* covariance matrix*/
	float emodel[4];  

	/* entries for S-P feature */
	long nbcs;
	Arr *badclocks;
	/* need global setting of this to handle fixed depth solutions*/
	int global_fix_depth;

	C=dmatrix(0,3,0,3);

	if(argc < 3) usage();
	dbin = argv[1];
	dbout = argv[2];
	for(i=3;i<argc;++i)
	{
		if(!strcmp(argv[i],"-pf"))
		{
			++i;
			if(i>=argc) usage();
			pfin = argv[i];
		}
		else if(!strcmp(argv[i],"-sift"))
		{
			++i;
			if(i>=argc) usage();
			sift_exp = argv[i];
			sift = 1;
		}
		else if(!strcmp(argv[i],"-useold"))
			useold = 1;
		else
			usage();
	}
	/* set default this way*/
	if(pfin == NULL) pfin = strdup("relocate");


	/* Initialize the error log and write a version notice */
	elog_init (argc, argv) ;
	cbanner("Version $Revision$ $Date$\n",
			"relocate inputdb outputdb [-pf pf -sift expression -useold]\n",
			"Gary Pavlis",
                        "Indiana University",
                        "*****@*****.**");

	/* Alway join assoc, arrival, and site.  We join site 
	to make sure station table is properly dynamic to account for
	time changes.  With this setup, the stations can even move
	around and this should still work.*/


	if(dbopen(dbin,"r",&db) == dbINVALID) 
		elog_die(1,"Unable to open input database %s\n",dbin);
	if(dbopen(dbout,"r+",&dbo) == dbINVALID) 
		elog_die(1,"Unable to open output database %s\n",dbout);

	dbv = dbjoin ( dblookup(db,0,"event",0,0),
		dblookup(db,0,"origin",0,0),
		0,0,0,0,0);
	if(dbv.table == dbINVALID)
		elog_die(1,"event->origin join failed\n");
	dbv = dbjoin ( dbv, dblookup(db,0,"assoc",0,0),
			0,0,0,0,0);
	if(dbv.table == dbINVALID)
		elog_die(1,"event->origin->assoc join failed\n");
	dbv = dbjoin ( dbv, dblookup(db,0,"arrival",0,0),
			0,0,0,0,0);
	if(dbv.table == dbINVALID)
		elog_die(1,"event->origin->assoc->arrival join failed\n");
	/* We will explicitly set the keys for this join because it
	was found to fail sometimes */
	joinkey1 = newtbl(0);
	joinkey2 = newtbl(0);
	pushtbl(joinkey1,"arrival.sta");
	pushtbl(joinkey1,"arrival.time");
	pushtbl(joinkey2,"sta");
	pushtbl(joinkey2,"ondate::offdate");
	dbv = dbjoin ( dbv, dblookup(db,0,"site",0,0),
			&joinkey1,&joinkey2,0,0,0);
	if(dbv.table == dbINVALID)
		elog_die(1,"event->origin->assoc->arrival->site join failed\n");

	/* Subset using sift_key if requested */
	if(sift)
	{
		dbv = dbsubset(dbv,sift_exp,0);
		if(dbv.record == dbINVALID)
			elog_die(1,"dbsubset of %s with expression %s failed\n",
				dbin, sift_exp);
	}
	/* This keeps only the prefered origin records intact */
	dbv = dbsubset(dbv,"orid == prefor", 0);
	if(dbv.record == dbINVALID)
			elog_die(1,"Subset to preferred origin records failed\n");

	/* First we have to run a unique key sort in the following order
	to remove redundant picks made on multiple channels.  We will
	issue a warning if the record count changes. */
	dbquery(dbv, dbRECORD_COUNT, &nrows_raw);
	sortkeys = newtbl(0);
	pushtbl(sortkeys,"evid");
	pushtbl(sortkeys,"sta");
	pushtbl(sortkeys,"phase");
	dbv = dbsort(dbv,sortkeys,UNIQUE,0);
	dbquery(dbv, dbRECORD_COUNT, &nrows);
	if(nrows != nrows_raw)
		elog_complain(0,"Input database has duplicate picks of one or more phases on multiple channels\n\
Which picks will be used here is unpredictable\n\
%ld total picks, %ld unique\nContinuing\n", nrows_raw, nrows);

	/* This sort is the required one for the grouping that follows*/

	sortkeys = newtbl(3);
	pushtbl(sortkeys,"evid");
	pushtbl(sortkeys,"orid");
	pushtbl(sortkeys,"arrival.time");
	dbv = dbsort(dbv,sortkeys,0,0);
	if(dbv.record == dbINVALID)
		elog_die(1,"dbsort on evid,orid,arrival.time failed\n");

	/* Set up grouping by events */
	origin_group = newtbl(0);
	pushtbl(origin_group, "evid");
	dborigin_group = dbgroup(dbv, origin_group, "origin_group",1);
	if(dborigin_group.record == dbINVALID)
		elog_die(1,"dbgroup by origin failed\n");

	dbquery(dborigin_group,dbRECORD_COUNT,&nevents);
	elog_notify(0,"Attempting to relocate %ld events in subsetted database\n",
		nevents);
	

	/* DB is now set up correctly, now we turn to the parameter files */
	i = pfread(pfin,&pf);
	if(i != 0) elog_die(1,"Pfread error\n");

	o = parse_options_pf (pf);
	global_fix_depth=o.fix[2];
 	arr_phase = parse_phase_parameter_file(pf);
	vmodel = pfget_string(pf,"velocity_model_name");

	/* set up minus phase for bad clock problems */
	badclocks = newarr(0);
	if(db_badclock_definition(db,pf,badclocks))
		elog_complain(0,"Warning:  problems in database definitions of bad clock time periods\n");
	pfget_badclocks(pf,badclocks);
	nbcs = cntarr(badclocks);
	if(nbcs>0) fprintf(stdout,"relocate:  bad clock feature enabled\n\n");
        /* Change by JN to output evid and orid. */
        /* fprintf(stdout,"lat lon depth time rms wrms interquartile ndata ndgf iterations\n"); */
	fprintf(stdout,"evid orid lat lon depth time rms wrms interquartile ndata ndgf iterations\n");

	/* Main loop.  We utilize the group views and loop through by 
	events */
	for(dborigin_group.record=0;
		dborigin_group.record< nevents;++dborigin_group.record)
	{
		Dbptr db_bundle;  /* db pointer returned from bundle field 
				of dborigin_group for current event */
		Arr *station_table;
		Arr *array_table;
		long is, ie; 
		long orid;  /* orid assigned relocated event in output db */

		if(dbgetv(dborigin_group,0,"evid", &evid,
			"bundle", &db_bundle,NULL ) == dbINVALID)
			elog_complain(1,"dbgetv error for row %ld of event group\n",
				dborigin_group.record);
		dbget_range(db_bundle,&is,&ie);

		station_table = dbload_station_table(dbv,
						is,ie,pf);
		array_table = dbload_array_table(dbv,
						is,ie,pf);
		ta = dbload_arrival_table(dbv,
				is,ie,station_table, arr_phase);


		tu = dbload_slowness_table(dbv,
				is,ie,array_table, arr_phase);
		/* this actually sets up the minus phase feature for bad clocks*/
		if(nbcs)
		{
			if(minus_phases_arrival_edit(ta,arr_phase,badclocks))
				elog_complain(0,"Warning(relocate):  problems in minus_phase_arrival_edit function\n");
		}
		if(useold)
		{
			char dtype[2];
			h0 = db_load_initial(dbv,is);
			/* keep fixed depth if done before.  
			setting dbv.record here is a bit of
			a potential maintenance problem */
			dbv.record=is;
			dbgetv(dbv,0,"dtype",dtype,NULL );
			if( (!strcmp(dtype,"g")) || (!strcmp(dtype,"r")) )
				o.fix[2]=1;
			
		}
		else
			h0 = initial_locate(ta, tu, o, pf);

		ret_code = ggnloc(h0,ta,tu,o,
			&converge_history,&reason_converged,&residual);
			
		if(ret_code < 0)
		{
			elog_complain(1,"ggnloc failed to produce a solution\n");
		}
		else 
		{
			if(ret_code > 0)
			    elog_complain(1,"%d travel time calculator failures in ggnloc\nSolution ok\n",
				ret_code);
			
			niterations = maxtbl(converge_history);
			hypos = (Hypocenter *)gettbl(converge_history,
								niterations-1);
			predicted_errors(*hypos,ta,tu,o,C,emodel);

                        /* Next 3 calls changed by JN to output evid, orid and number_data */
			orid = save_origin(dbv,is,ie,o.fix[3],*hypos,dbo);
			evid = save_event(dbv,is,ie,orid,dbo);

			fprintf(stdout,"%ld %ld %lf %lf %lf %lf %g %g %g %d %d %ld\n",
					evid,
					orid,
					hypos->lat,hypos->lon,hypos->z,hypos->time,
					hypos->rms_raw, hypos->rms_weighted,
					hypos->interquartile,
					hypos->number_data,
					hypos->degrees_of_freedom,
					niterations);
	
			save_origerr(orid,*hypos,C,dbo);
			save_assoc(dbv,is,ie,orid,vmodel,residual,*hypos,dbo);
			/* These save genloc add on tables */
			save_emodel(orid,emodel,dbo);
			save_predarr(dbo,ta,tu,*hypos,orid,vmodel);
		}
		o.fix[2]=global_fix_depth;
		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(tu, ta);
		destroy_network_geometry_tables(station_table,array_table);
	}
	return(0);
}
Dbptr inWhichPolygons(Dbptr db,Point P) {
	Point *poly;
	long i;
	long nrec;
	Dbptr dbr= dblookup(db,0,"polygon",0,0);
	double lat,lon;
	Dbptr dbs;
	long npoints;
	char expr[STRSZ];
	char temp[STRSZ];
	long pid;
	int first;
	int found=0;
	char name[STRSZ];

	lat= P.lat;
	lon= P.lon;
	
	dbs=dblookup(db,0,"polygon",0,0);
/*
   Nice idea, but breaks too many programs (older versions of the polygon-schema)
   sprintf(expr,"closed=~/y/ && north >= %f && south <= %f && east >= %f && west <= %f",
   */
	sprintf(expr,"north >= %f && south <= %f && east >= %f && west <= %f",
			lat,lat,lon,lon);
	dbs=dbsubset(dbs,expr,0);
	dbquery(dbs, dbRECORD_COUNT,&nrec);
	if (nrec < 1) {
		/*
		elog_log(0,"inWhichPolygons: initial check of Bounding Box returns 0!");
		*/
		dbr=dbinvalid();
		return dbr;
	}
	first=1;
	for (i= 0; i< nrec; i++) {
		dbs.record=i;
		dbgetv(dbs,0,"pname",&name,NULL );

		if ((npoints=readPolygon(dbs,&poly))>0) {
			if (isGeographicallyInside(P,poly,npoints)) {
				found=1;
				dbgetv(dbs,0,"pid",&pid,NULL );
				if (first) {
					sprintf(expr,"pid==%ld",pid);
					first=0;
				} else {
					sprintf(temp,"|| pid==%ld",pid);
					strcat(expr,temp);
				}
			}
			free(poly);
		}
	}
	
	/*dbr=dblist2subset(dbs,list);*/
	if (found) {
		dbr=dbsubset(dbs,expr,0);
	} else {
		dbr=dbinvalid();
	}
	dbfree(dbs);
	return dbr;
}
Example #10
0
int
main(int argc, char **argv)
{
	double          modified_after =now() , last_lddate, last_mtime, mtime;
	char           *orbname = NULL;
	char           *dbname = NULL;
	int             orb;
	int             naptime = -1, check_lddate_interval = -1;
	Dbptr           db, dbt, dbs;
	char           *prefix = NULL;
	struct stat     filestat;
	int             i;
	Tbl            *tablenames, *tables_containing_dfile, *check_tables = NULL,
	               *ignore_tables = NULL;
	long            table_present, recc, is_view;
	char           *tablename, *schemaname;
	char           *filename;
	int             counter = 0, force_check = 0;
	char            expr[512];
	char           *statefilename = NULL, *pfname = "dbnew2orb";
	Pf             *pf = NULL;
	void           *priv_dfile = (void *) NULL;
	void           *private = (void *) NULL;
	int             pmsi;	/* poor man's string index, replacment for
				 * searchtbl... */
	char           *pmsp;
	double          lastburytime;
	Relic           relic;
	char           *s;
	Expression     *expr_lddate;
	double         *mtimes;
	double         *lddates;

	elog_init(argc, argv);

	if (argc < 2) {
		usage();
		exit(1);
	}
	for (argc--, argv++; argc > 0; argc--, argv++) {
		if (!strcmp(*argv, "-modified_after")) {
			argc--;
			argv++;
			if (argc < 1) {
				complain(0, "Need -modified_after argument.\n");
				usage();
				exit(1);
			}
			modified_after = str2epoch(*argv);
		} else if (!strcmp(*argv, "-prefix")) {
			argc--;
			argv++;
			if (argc < 1) {
				complain(0, "Need -prefix argument.\n");
				usage();
				exit(1);
			}
			prefix = *argv;
		} else if (!strcmp(*argv, "-pf")) {
			argc--;
			argv++;
			if (argc < 1) {
				complain(0, "Need -pf argument.\n");
				usage();
				exit(1);
			}
			pfname = *argv;
		} else if (!strcmp(*argv, "-state")) {
			argc--;
			argv++;
			if (argc < 1) {
				complain(0, "Need -state argument.\n");
				usage();
				exit(1);
			}
			statefilename = *argv;
		} else if (!strcmp(*argv, "-sleep")) {
			argc--;
			argv++;
			if (argc < 1) {
				complain(0, "Need -sleep argument.\n");
				usage();
				exit(1);
			}
			naptime = atoi(*argv);
		} else if (!strcmp(*argv, "-check_lddate_interval")) {
			argc--;
			argv++;
			if (argc < 1) {
				complain(0, "Need -check_lddate_interval argument.\n");
				usage();
				exit(1);
			}
			check_lddate_interval = atoi(*argv);
		} else if (!strcmp(*argv, "-v")) {
			verbose++;
		} else if (**argv != '-') {
			break;
		} else {
			complain(0, "Unrecognized argument '%s'.\n", *argv);
			usage();
			exit(1);
		}
	}


	if (pfread(pfname, &pf)) {
		elog_die(0, "parse_pf: pfread('%s') error.\n", pfname);
	}
	if (check_lddate_interval < 1) {
		if (parse_param(pf, "check_lddate_interval", P_LINT, 1, &check_lddate_interval) < 0) {
			elog_die(1, "parse_pf: sleep check_lddate_interval needed!\n");
		} else {
			if (check_lddate_interval < 0) {
				check_lddate_interval = 1;
			}
		}
	}
	if (naptime < 1) {
		if (parse_param(pf, "sleep", P_LINT, 1, &naptime) < 0) {
			elog_die(1, "parse_pf: sleep value needed!\n");
		} else {
			if (naptime < 0) {
				naptime = 1;
			}
		}
	}
	if (!prefix) {
		if (parse_param(pf, "prefix", P_STR, 0, &prefix) < 0) {
			printf("NO PREFIX!\n");
			prefix = NULL;
		}
	}
	parse_param(pf, "check_tables", P_TBL, 0, &check_tables);
	if (check_tables) {
		if (maxtbl(check_tables) < 1) {
			freetbl(check_tables, 0);
			check_tables = NULL;
		}
	}
	parse_param(pf, "ignore_tables", P_TBL, 0, &ignore_tables);
	if (ignore_tables) {
		if (maxtbl(ignore_tables) < 1) {
			freetbl(ignore_tables, 0);
			ignore_tables = NULL;
		}
	}
	/*
	 * no good here, would erase the table above pffree(pf);
	 */

	if (argc < 1) {
		complain(0, "Need db argument.\n");
		usage();
		exit(1);
	}
	dbname = *argv;

	argc--;
	argv++;
	if (argc < 1) {
		complain(0, "Need orb argument.\n");
		usage();
		exit(1);
	}
	orbname = *argv;
	argc--;
	argv++;
	if (argc > 0) {
		complain(0, "Unrecognized argument '%s'.\n", *argv);
		usage();
		exit(1);
	}
	if (dbopen(dbname, "r", &db) < 0) {
		elog_complain(0, "Can't open database");
		exit(1);
	}
	dbquery(db, dbSCHEMA_NAME, &schemaname);
	orb = orbopen(orbname, "w&");
	if (orb < 0) {
		elog_die(0, "orbopen(%s) error\n", orbname);
	}
	/*
	 * prepare for later call to dbquery(dbFIELD_TABLES) to find only
	 * tables containing lddate
	 */

	/*
	 * dbtables is much better, does not require the existence of table
	 * origin dbf = dblookup(db, 0, "origin", "lddate", "dbNULL");
	 * dbquery(dbf, dbFIELD_TABLES, &tablenames);
	 */

	dbex_compile(db, "max(lddate)", &expr_lddate, dbTIME);
	tablenames = dbtables(db, "lddate");
	tables_containing_dfile = dbtables(db, "dfile");

	/* waste a few bytes... */
	ntables = maxtbl(tablenames);
	mtimes = malloc(ntables * sizeof(double));
	lddates = malloc(ntables * sizeof(double));
	bury_times = malloc(ntables * sizeof(double));
	static_flags = malloc(ntables * sizeof(long));
	if (statefilename) {
		if (exhume(statefilename, &Stop, 10, mortician)) {
			elog_notify(0, "read old state file\n");
		} else {
			elog_complain(0, "could not read old statefile\n");
		}
	}
	for (i = 0; i < ntables; i++) {
		/*
		 * mtimes[i] = modified_after; lddates[i] = modified_after;
		 */
		static_flags[i] = NEW_TABLE;
	}
	for (;;) {
		tablenames = dbtables(db, "lddate");

		for (i = 0; i < ntables; i++) {
			tablename = gettbl(tablenames, i);
			if (!tablename) {
				continue;
			}
			dbt = dblookup(db, 0, tablename, 0, 0);
			dbquery(dbt, dbTABLE_PRESENT, &table_present);
			if (!table_present) {
				continue;
			}
			dbquery(dbt, dbTABLE_IS_VIEW, &is_view);
			if (is_view) {
				continue;
			}
			/* lastid is not a good idea (my personal choice)... */
			if (strcmp(tablename, "lastid") == 0) {
				continue;
			}
			/* remove after Dan fixed the bug with remark */
			if (strcmp(tablename, "remark") == 0) {
				continue;
			}
			if (findtbl(tablename, tables_containing_dfile)) {
				continue;
			}
			if (check_tables) {
				if (!findtbl(tablename,check_tables)) {
					if (verbose > 1 && static_flags[i]==NEW_TABLE) elog_notify(0,"ignoring table %s because it's NOT in 'check_tables'\n",tablename);
					continue;
				}
			}
			if (ignore_tables) {
				if (findtbl(tablename,ignore_tables)) {
					if (verbose > 1 && static_flags[i]==NEW_TABLE) elog_notify(0,"ignoring table %s because it's in 'ignore_tables'\n",tablename);
					continue;
				}
			}
			dbquery(dbt, dbRECORD_COUNT, &recc);
			if (recc < 1) {
				continue;
			}
			if (statefilename) {
			if (static_flags[i] == NEW_TABLE) {
				relic.dp = &bury_times[i];
				if (resurrect(tablename, relic, TIME_RELIC) == 0) {
					mtimes[i] = bury_times[i];
					lddates[i] = bury_times[i];
					if (verbose > 1) {
						elog_notify(0, "resurrection successful: check %s after %s\n", tablename, s = strtime(bury_times[i]));
						free(s);
					}
				} else {
					bury_times[i] = modified_after;
					mtimes[i] = modified_after;
					lddates[i] = modified_after;
					if (verbose > 1) {
						elog_notify(0, "resurrection unsuccessful: check %s after %s\n", tablename, s = strtime(modified_after));
						free(s);
					}
				}
				static_flags[i] = TABLE_SEEN;
			}
			} else {
				if (static_flags[i] == NEW_TABLE) {
					bury_times[i] = modified_after;
					mtimes[i] = modified_after;
					lddates[i] = modified_after;
					static_flags[i] = TABLE_SEEN;
				}
			}
			dbquery(dbt, dbTABLE_FILENAME, &filename);
			if (stat(filename, &filestat) < 0) {
				elog_die(1, "stat(%s) error.\n", filename);
			}
			last_mtime = mtimes[i];
			last_lddate = lddates[i];

			mtime = filestat.st_mtime;
			/*
			 * the whole mtime stuff is not soo good: mtime is
			 * typically > lddate, so setting modified_after to
			 * mtime will certainly ignore the last value. To get
			 * everything, I will have to keep 2 arrays: mtimes
			 * to detect file modifications and lddates to get
			 * the actual entries...
			 */
			if (force_check || mtime > last_mtime) {
				sprintf(expr, "lddate > %f", last_lddate);
				dbs = dbsubset(dbt, expr, 0);
				dbquery(dbs, dbRECORD_COUNT, &recc);
				if (recc > 0) {
					if (dbrows2orb(dbs, orb, prefix) == 0) {
						/*
						 * dbex_evalstr(dbs,
						 * "max(lddate)", dbTIME,
						 * &lddates[i]);
						 */
						dbex_eval(dbs, expr_lddate, 0, &lddates[i]);
						mtimes[i] = mtime;
						bury_times[i] = lddates[i];
					}
				}
				dbfree(dbs);
			}
			/*
			 * a call to dbfree(dbt) would remove it from the
			 * list of tablenames, all later calls to tablename
			 * would return NIL...
			 */
			if (Stop) {
				bury();
				return (0);
			}
		}
		sleep(naptime);
		if ((counter + 1) >= check_lddate_interval) {
			counter = 0;
			force_check = 1;
		} else {
			force_check = 0;
			counter++;
		}
		if (statefilename) {
			double          nowtime;

			nowtime = now();
			if (nowtime - lastburytime > 600.0) {
				lastburytime = nowtime;
				bury();
			}
		}
	}
}
Example #11
0
int
main(int argc, char **argv)
{
	int             c, verbose = 0, errflg = 0;


	char           *dbname= NULL;
	Point          *poly;
	long             nvertices;

	Dbptr           db;
	long             i;
	long 		 	nrecs;
	char           *subset_expr=NULL;
	char            pname[STRSZ], closed[STRSZ];

	elog_init(argc, argv);

	for (argc--, argv++; argc > 1; argc--, argv++) {
		if (!strcmp(*argv, "-subset")) {
			argc--;
			argv++;
			if (argc < 1) {
				elog_complain(0, "Need -subset argument.\n");
				usage();
				exit(1);
			}
			subset_expr = *argv;
		} else if (!strcmp(*argv, "-v")) {
			verbose++;
		} else if (**argv != '-') {
			break;
		} else {
			 elog_complain(0, "Unrecognized argument '%s'.\n",
			 *argv); usage(); exit(1);
				usage();
				exit(1);
		}
	}
	if (argc < 1) {
		complain(0, "Need db argument.\n");
		usage();
		exit(1);
	}
	dbname = *argv;
	argc--;
	argv++;

	dbopen_database(dbname, "r", &db);
	if (db.table <0) {
		db=dblookup(db,0,"polygon",0,0);
	}
	if (subset_expr) {
		db=dbsubset(db,subset_expr,0);
	}

	dbquery(db, dbRECORD_COUNT, &nrecs);
	printf("records:%ld \n",nrecs);
	for (db.record = 0; db.record < nrecs; db.record++) {
		nvertices = readPolygon(db, &poly);
		if (nvertices > 0) {
			dbgetv(db, 0, "pname", &pname, "closed", &closed, NULL );
			printf(">\n");
			for (i = 0; i < nvertices; i++) {
				printf("%.4f %.4f\n", poly[i].lon, poly[i].lat);
			}
			if (yesno(closed) == -1 &&
			    ((poly[0].lat != poly[nvertices - 1].lat) ||
			     (poly[0].lon != poly[nvertices - 1].lon))) {
				printf("%.4f %.4f\n", poly[0].lon, poly[0].lat);
			}
		}
	}
	dbclose(db);
	return (0);
}
Example #12
0
MWbasis *load_multiwavelets_db(Dbptr db, Pf *pf,int *nwavelets, int *bankid)
{
	MWbasis *mwb;
	int nw;
	char *select_condition;
	Dbptr dbv;
	int nrecords;
	/* These are the attribute in the mwdisc table minus
	those returned in the argument list */

	int nsamp,foff;
	double f0,fw;
	char datatype[4],mworder[4];
	char fname[128];
	FILE *fp;
	int i,j,jj;
	
	dbv = dblookup(db,0,"mwdisc",0,0);
	if(dbv.record == dbINVALID) elog_die(0,"load_multiwavelets_db:  no mwdisc table in input database\nThese are required for multiwavelet transform\nCheck database descriptor\n");
	select_condition=pfget_string(pf,"multiwavelet_select_condition");
	if(select_condition==NULL)
		elog_die(0,"Missing required parameter string called multiwavelet_select_condition\nThis is required when loading multiwavelets from a database\n");
	dbv=dbsubset(dbv,select_condition,0);
	dbquery(dbv,dbRECORD_COUNT,&nrecords);
	if(nrecords<=0)
		elog_die(0,"load_multiwavelet_db:  no records in mwdisc match condition: %s\n",
			select_condition);
	else if (nrecords>1)
		elog_complain(0,"load_multiwavelet_db:  multiple records in mwdisc match the condition %s\nUsing first record found\n",
			select_condition);
	dbv.record=0;
	dbgetv(dbv,0,"bankid",bankid,
		"nsamp",&nsamp,
		"nwavelets",nwavelets,
		"f0",&f0,
		"fw",&fw,
		"datatype",datatype,
		"foff",&foff,
		"mworder",mworder,0);
	if(strcmp(datatype,"t4"))
		elog_die(0,"multiwavelets must be in t4 binary form\n");
	if(strcmp(mworder,"ti") || strcmp(mworder,"ts") )
	{
		if(dbextfile(dbv,0,fname)<=0)
			elog_die(0,"load_multiwavelet_db: multiwavelet basis file %s not found\n",
				fname);
		fp = fopen(fname,"r");
		if(foff>0) fseek(fp,foff,0);
		allot(MWbasis *,mwb,*nwavelets);
		for(i=0;i<*nwavelets;++i)
		{
			allot(float *,mwb[i].r,nsamp);
			allot(float *,mwb[i].i,nsamp);
			mwb[i].n=nsamp;
			mwb[i].f0=f0;
			mwb[i].fw=fw;
		}
		
		if(!strcmp(mworder,"ti"))
		{
			/* This is case for storage as complex number */
			float *buffer;
			allot(float *,buffer,2*nsamp);
			for(i=0;i<*nwavelets;++i)
			{
				if(fread(buffer,sizeof(float),2*nsamp,fp)
					!= (2*nsamp))
				{
					elog_die(0,"read error on file %s while reading wavelet %d\n",
						fname,i);
				}
				for(j=0,jj=0;j<nsamp;++j,jj+=2)
				{
					mwb[i].r[j]=buffer[jj];
					mwb[i].i[j]=buffer[jj+1];
				}
			
			}
			free(buffer);
		}
		else
		{
			for(i=0;i<*nwavelets;++i)
Example #13
0
/* main for dbpmel*/	
int
main(int argc, char **argv)
{
	char *dbin;  /* Input db name */
	Tbl *gridlist;
	Dbptr db;  /* input db pointer */
	Dbptr dbv;  /* set to view formed by join */
	char *pfin=NULL;  /* input parameter file */
	char *sift_exp;  /* sift expression for subset */
	int sift = 0;  /* default is no sift.  */
	Tbl *sortkeys;
	/* db row variables */
	int nrows, nrows_raw;

	Pf *pf;
	char *version="1.0";
	int i;
	int gmin,gmax;
	char sstring[128];
	char *gridname;
	Tbl *proctbl;


	/* Initialize the error log and write a version notice */
	elog_init (argc, argv) ;
	fprintf (stdout, "%s version %s\n", argv[0], version) ;

	if(argc < 3) usage();
	dbin = argv[1];
	gridlist = parse_gridlist_string(argv[2]);
	get_gridid_range(gridlist,&gmin,&gmax);
	
	for(i=3;i<argc;++i)
	{
		if(!strcmp(argv[i],"-pf"))
		{
			++i;
			if(i>=argc) usage();
			pfin = argv[i];
		}
		else if(!strcmp(argv[i],"-sift"))
		{
			++i;
			if(i>=argc) usage();
			sift_exp = argv[i];
			sift = 1;
		}
		else
			usage();
	}
	/* set default this way*/
	if(pfin == NULL) pfin = (char *)strdup("dbpmel");
	i = pfread(pfin,&pf);
	if(i != 0) die(1,"Pfread error\n");
	check_required_pf(pf);


	/* Set up main database view.  This is a derived from code
	in the related genloc program called relocate.
	Always join assoc, arrival, and site.  We join site 
	to make sure station table is properly dynamic to account for
	time changes.  With this setup, the stations can even move
	around and this should still work.*/
	gridname = pfget_string(pf,"gridname");
	if(dbopen(dbin,"r+",&db) == dbINVALID) 
		elog_die(1,"Unable to open input database %s\n",dbin);
	
	/* We save the pf object into archive files that document the
	complex state of this program.  This small function does this
	and saves the results in a special db table */
	save_run_parameters(db,pf);	
		
	db = dblookup(db,0,"hypocentroid",0,0);
	sprintf(sstring,"gridid>=%d && gridid<=%d && (gridname=~/%s/)",gmin,gmax,gridname);
	db = dbsubset(db,sstring,0);
	dbquery(db, dbRECORD_COUNT, &nrows);
	if(nrows<=0) 
		elog_die(0,"No hypocentroid records in requested gridid range of %d to %d for grid called %s\n",
				gmin,gmax,gridname);
	/* This forms the working view for this program */
	proctbl = strtbl("dbjoin cluster",
		"dbjoin event",
		"dbjoin origin",
		"dbsubset orid==prefor",
		"dbjoin assoc",
		"dbjoin arrival",0);
	dbv = dbprocess(db,proctbl,0);
	dbquery(dbv, dbRECORD_COUNT, &nrows);
	fprintf(stdout,"Raw working database view has %d rows\n",nrows);

	/* Subset using sift_key if requested */
	if(sift)
	{
		dbv = dbsubset(dbv,sift_exp,0);
		if(dbv.record == dbINVALID)
			die(1,"dbsubset of %s with expression %s failed\n",
				dbin, sift_exp);
	}

	/* First we have to run a unique key sort in the following order
	to remove redundant picks made on multiple channels.  We will
	issue a warning if the record count changes.  This was found
	to be a common problem that had to be repaired automatically.*/
	dbquery(dbv, dbRECORD_COUNT, &nrows_raw);
	sortkeys = newtbl(0);
	pushtbl(sortkeys,"gridid");
	pushtbl(sortkeys,"evid");
	pushtbl(sortkeys,"sta");
	pushtbl(sortkeys,"phase");
	dbv = dbsort(dbv,sortkeys,dbSORT_UNIQUE,0);
	dbquery(dbv, dbRECORD_COUNT, &nrows);

	if(nrows != nrows_raw)
		complain(0,"Input database has duplicate picks of one or more phases on multiple channels\n\
Which picks will be used here is unpredictable\n\
%d total picks, %d unique\nContinuing\n", nrows_raw, nrows);

	fprintf(stdout,"Final working view has %d rows\n",nrows);

	if(dbpmel_process(dbv,gridlist,pf))
	{
		elog_complain(0,"Errors in dbpmel_process\n");
		exit(-1);
	}
	exit(0);
}
Example #14
0
int grdb_sc_loadcss (Dbptr dbin, char *net_expr, char *sta_expr,
        char *chan_expr, double tstart, double tend, 
        int coords, int ir, int orient, Dbptr *dbscgr, Dbptr *dbsc)
{
	Dbptr dbout, db, dbout2;
	char string[1024];
	char string2[1024];
	char sta_wfdisc[32], chan_wfdisc[32];
	int i, j, n, sensor=0, ok;
	Tbl *pat1, *pat2;
	Tbl *sortfields, *groupfields;
	FILE *file;
	Response *resp;
	int is_view=0;
	Dbptr db_to_clear;

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

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

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

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

        /* Sort and group the output view. */

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

	/* Normal exit */

	return (0);
}
Example #15
0
int main(int argc, char *argv[])
{
  int    j,nsta,ns,delaytype;
  double lat[MXSTA],lon[MXSTA],rx,ry;
  double reflat,reflon,kx,ky;
  double slow,baz,distance,azimuth,shift,delay[MXSTA];
  char   refsta[7],asta[7],searchExpr[80];
  char   *arrayname,*arrayfile,*dbname,*dfile;
  char   sta[MXSTA][7],chan[MXSTA][9];
  FILE   *fp;
  Dbptr  db,dba,dbs;

  arrayname = malloc(9);
  arrayfile = malloc(13);
  dbname = malloc(80);
  dfile = malloc(80);

  if (argc < 8)
  {
    printf("Usage: %s slow baz delaytype arrayname refsta dbname dfile\n",argv[0]);
    return 1;
  }

  sscanf(argv[1],"%lf",&slow);
  sscanf(argv[2],"%lf",&baz);
  sscanf(argv[3],"%d",&delaytype);
  arrayname = argv[4];
  sscanf(argv[5],"%s",refsta);
  dbname = argv[6];
  dfile = argv[7];

/*Open the array file and get array info.*/
  memcpy(arrayfile,"\0",1);
  strcpy(arrayfile,arrayname);
  strcat(arrayfile,".arr");
  if ( (fp = fopen(arrayfile,"r")) == NULL)
  {
    complain(0,"Could not open array file.\n");
    return 1;
  }

  nsta = 0;
  while(fscanf(fp, "%s %s %lf", sta[nsta],chan[nsta],&delay[nsta]) != EOF)
  {
    nsta = nsta + 1;
  }
  fclose(fp);
  printf("# of stations = %d\n",nsta);

  if (dbopen(dbname,"r",&db) < 0)
  {
    complain(0,"Could not open database.\n");
    return 1;
  }

  dbs  = dblookup(db,0,"site",0,0);

/*Find reference station and put all station coordinates relative to it.*/
  dbquery(dbs,dbRECORD_COUNT,&ns);
  for(dbs.record=0;dbs.record<ns;dbs.record++)
  {
    dbgetv(dbs,NULL,"sta",asta,"lat",&reflat,"lon",&reflon,NULL);
    if (strcmp(refsta,asta) == 0) break;
  }

  kx = slow*cos((90 - baz)/rad2dg);
  ky = slow*sin((90 - baz)/rad2dg);

  printf("computing time delays for a wave at array = %s\n",arrayname);
  printf("refsta,reflat,reflon = %s %f %f\n",refsta,reflat,reflon);
  printf("slowness(s/km), back azimuth(dg cw from north)   = %f %f\n",slow,baz);
  printf("x and y are Cartesian coordinates (+x is east; +y is north)\n");
  printf("positive delay means wave arrives later; negative means sooner\n");
  printf("output file has: station  channel  delay(s)\n");

  if ( (fp = fopen(dfile,"w")) == NULL)
  {
    complain(0,"Could not open output file.\n");
    return 1;
  }

  for (j=0;j<nsta;j++)
  {
    sprintf( searchExpr, "sta =~ /%s/",sta[j]);
    dba = dbsubset(dbs,searchExpr,NULL);
    dba.record = 0;
    dbgetv(dba,NULL,"lat",&lat[j],"lon",&lon[j],NULL);
/*  Note: dist returns distance in radians and azimuth in radians.*/
    dist(reflat/rad2dg,reflon/rad2dg,lat[j]/rad2dg,lon[j]/rad2dg,&distance,&azimuth);
    distance = distance*rad2dg*dg2km;
    rx=distance*cos(pi/2 - azimuth);
    ry=distance*sin(pi/2 - azimuth);
    shift = kx*rx+ky*ry;
    if (delaytype == 1) delay[j] = -shift + delay[j];
    if (delaytype == 0) delay[j] = -shift;
    printf("%3d %-5s %13.3f %7.2f %7.2f\n",j+1,sta[j],delay[j],rx,ry);
    fprintf(fp,"%-5s %-5s %13.3f\n",sta[j],chan[j],delay[j]);
  }

  dbclose(db);
  fclose(fp);

  return 0;
}
Example #16
0
int
main( int argc, char **argv )
{
	int	c;
	int	errflag = 0;
	int	orb;
	int	stop = 0;
	long	nrecs;
	char	*match = ".*/pf/st";
	char	*from = 0;
	char	*statefile = 0;
	char	*pfname = "orb2rrdc";
	char	*orbname;
	char	*dbcache;
	char	*rrdtool;
	char	command[STRSZ];
	char	net[STRSZ];
	char	sta[STRSZ];
	char	rrdvar[STRSZ];
	char	key[STRSZ];
	char	path[FILENAME_MAX];
	Dbptr	db;
	Dbptr	dbt;
	Pf	*pf;
	char	*Default_network;
	Tbl	*dlslines;
	Arr	*Dls_vars_dsparams;
	Arr	*Dls_vars_rras;
	Tbl	*Dls_vars_keys;
	char	*line;
	char	*dls_var;
	char	*dsparams;
	Tbl	*rras;
	int	i;
	int	j;
	OrbreapThr *ort;
	int	pktid;
	char	srcname[ORBSRCNAME_SIZE];
	double	time = 0;
	char	*packet = 0;
	int	nbytes = 0;
	int	bufsize = 0;
	Packet	*pkt = 0;
	int	rc;
	char	*s;
	Pf	*dlspf;
	Tbl	*dlspfkeys;
	char	*element;
	Tbl	*parts;
	double	val;
	Pf	*pfval = 0;

	elog_init( argc, argv );

	while( ( c = getopt( argc, argv, "vVd:s:p:m:f:" ) ) != -1 ) {

		switch( c ) {

		case 'd':
			CacheDaemon = optarg;
			break;

		case 'f':
			from = optarg;
			break;

		case 'm':
			match = optarg;
			break;

		case 'p': 
			pfname = optarg;
			break;

		case 's':
			statefile = optarg;
			break;
			
		case 'v':
			Verbose++;
			break;

		case 'V':
			VeryVerbose++;
			Verbose++;
			break;
		
		default:
			elog_complain( 0, "Unknown option '%c'\n", c );
			errflag++;
			break;
		}
	}

	if( errflag || argc - optind != 2 ) {

		usage();
	}

	if( Verbose ) {

		elog_notify( 0, "Starting at %s (%s $Revision$ $Date$)\n", 
				zepoch2str( str2epoch( "now" ), "%D %T %Z", "" ),
				Program_Name );
	}

	orbname = argv[optind++];
	dbcache = argv[optind++];

	pfread( pfname, &pf );

	rrdtool = pfget_string( pf, "rrdtool" );

	if( rrdtool == NULL || ! strcmp( rrdtool, "" ) ) {

		elog_die( 0, "Error: no rrdtool executable name specified in parameter file\n" );

	} else if( ( rrdtool[0] == '/' && ! is_present( rrdtool ) ) || ( rrdtool[0] != '/' && ! datafile( "PATH", rrdtool ) ) ) {

		elog_die( 0, "Error: can't find rrdtool executable by name of '%s' (check PATH environment " 
			"variable, or absolute path name if given)\n", rrdtool );

	} else if( rrdtool[0] == '/' ) {

		sprintf( command, "%s -", rrdtool );

	} else {

		sprintf( command, "rrdtool -" );
	}

	Suppress_egrep = pfget_string( pf, "suppress_egrep" );

	if( Suppress_egrep != NULL && strcmp( Suppress_egrep, "" ) ) {
		
		if( ! datafile( "PATH", "egrep" ) ) {

			elog_complain( 0, "Ignoring suppress_egrep parameter: can't find egrep on path\n" ); 

		} else {

			sprintf( command, "%s 2>&1 | egrep -v '%s'", command, Suppress_egrep );
		}
	}

	if( VeryVerbose ) {

		elog_notify( 0, "Executing command: %s\n", command );
	}

	Rrdfp = popen( command, "w" );

	if( Rrdfp == (FILE *) NULL ) {

		elog_die( 0, "Failed to open socket to rrdtool command\n" );
	}

	orb = orbopen( orbname, "r&" );

	if( orb < 0 ) {

		elog_die( 0, "Failed to open orb '%s' for reading. Bye.\n", orbname );
	}

	orbselect( orb, match );

	if( from != NULL && statefile == NULL ) {

		pktid = orbposition( orb, from );

		if( Verbose ) {

			elog_notify( 0, "Positioned to packet %d\n", pktid );
		}

	} else if( from != NULL ) {

		elog_complain( 0, "Ignoring -f in favor of existing state file\n" );
	}

	if( statefile != NULL ) {

		stop = 0;

		exhume( statefile, &stop, 15, 0 );

		orbresurrect( orb, &pktid, &time );

		if( Verbose ) {

			elog_notify( 0, "Resurrecting state to pktid %d, time %s\n",
				pktid, s = strtime( time ) );

			free( s );
		}

		orbseek( orb, pktid );
	}

	dbopen( dbcache, "r+", &db );

	if( db.database < 0 ) {
		
		elog_die( 0, "Failed to open cache database '%s'. Bye.\n", dbcache );

	} else {
		
		db = dblookup( db, "", "rrdcache", "", "" );

		if( db.table < 0 ) {

			elog_die( 0, "Failed to lookup 'rrdcache' table in '%s'. Bye.\n", dbcache );
		}
	}

	dbcrunch( db );

	dbt = dbsubset( db, "endtime == NULL", NULL );

	Rrd_files = newarr( 0 );

	dbquery( dbt, dbRECORD_COUNT, &nrecs );

	for( dbt.record = 0; dbt.record < nrecs; dbt.record++ ) {

		dbgetv( dbt, 0, "net", &net, "sta", &sta, "rrdvar", &rrdvar, NULL );

		dbfilename( dbt, (char *) &path );

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

		if( ! is_present( path ) ) {
			
			elog_complain( 0, "WARNING: rrd file '%s', listed in database, does not exist. "
				"Removing database entry.\n", path );

			dbmark( dbt );

		} else {

			setarr( Rrd_files, key, strdup( path ) );

			if( VeryVerbose ) {

				elog_notify( 0, "Re-using rrd file '%s' for '%s'\n", path, key );
			}
		}
	}

	Rrdfile_pattern = pfget_string( pf, "rrdfile_pattern" );
	Status_stepsize_sec = pfget_double( pf, "status_stepsize_sec" );
	Default_network = pfget_string( pf, "default_network" );
	dlslines = pfget_tbl( pf, "dls_vars" );

	Dls_vars_dsparams = newarr( 0 );
	Dls_vars_rras = newarr( 0 );

	for( i = 0; i < maxtbl( dlslines ); i++ ) {
		
		line = gettbl( dlslines, i );
		
		strtr( line, "\t", " " );
		rras = split( line, ' ' );

		dls_var = shifttbl( rras );
		dsparams = shifttbl( rras );

		setarr( Dls_vars_dsparams, dls_var, dsparams );
		setarr( Dls_vars_rras, dls_var, rras );
	}

	ort = orbreapthr_new( orb, -1., 0 );

	for( ; stop == 0; ) {

		orbreapthr_get( ort, &pktid, srcname, &time, &packet, &nbytes, &bufsize );

		if( statefile ) {

			rc = bury();

			if( rc < 0 ) {

				elog_complain( 0, "Unexpected failure of bury command! " 
					"(are there two orb2rrdc's running with the same state" 
					"file?)\n" );

				clear_register( 1 );
			}
		}

		rc = unstuffPkt( srcname, time, packet, nbytes, &pkt );

		if( rc == Pkt_pf ) {

			if( VeryVerbose ) {

				/* Parameter files generally too big for elog */

				fprintf( stderr, "Received a parameter-file '%s' at %s\n%s\n\n", 
						srcname, 
						s = strtime( time ), 
						pf2string( pkt->pf ) );

				free( s );

			} else if( Verbose ) {

				elog_notify( 0, "Received a parameter-file '%s' at %s\n", 
						srcname, s = strtime( time ) );

				free( s );
			}

			pfmorph( pkt->pf );

			if( VeryVerbose ) {

				fprintf( stderr, "Morphed parameter-file '%s' to interpret 'opt':\n%s\n\n", 
						srcname, 
						pf2string( pkt->pf ) );
			}

			pfget( pkt->pf, "dls", (void **) &dlspf );

			dlspfkeys = pfkeys( dlspf );
			Dls_vars_keys = keysarr( Dls_vars_dsparams );

			for( i = 0; i < maxtbl( dlspfkeys ); i++ ) {
			   
			   element = gettbl( dlspfkeys, i );

			   if( strcontains( element, "_", 0, 0, 0 ) ) {

				parts = split( (s = strdup( element )), '_' );

				sprintf( net, "%s", (char *) gettbl( parts, 0 ) );
				sprintf( sta, "%s", (char *) gettbl( parts, 1 ) );

				free( s );
				freetbl( parts, 0 );

			   } else {

				sprintf( net, "%s", Default_network );

				sprintf( sta, "%s", element );
			   }

			   for( j = 0; j < maxtbl( Dls_vars_keys ); j++ ) {

			   	dls_var = gettbl( Dls_vars_keys, j );

				sprintf( key, "%s{%s}", element, dls_var );

				if( pfresolve( dlspf, key, 0, &pfval ) < 0 ) {

					elog_complain( 0, "Unable to extract variable '%s' "
						"(not present or wrong type) from element '%s' "
						"in packet from '%s', timestamped '%s'; Skipping\n",
						key, element, srcname, s = strtime( time ) );

					free( s );

					pfval = 0;

					continue;

				} else if( pfval != (Pf *) NULL &&
					   pfval->value.s != (char *) NULL &&
					   ! strcmp( pfval->value.s, "-" ) ) {

					if( VeryVerbose ) {

						elog_notify( 0, "Non-floating point value '-' in variable '%s', "
							"in packet from '%s', timestamped '%s'; Skipping data point\n",
							key, srcname, s = strtime( time ) );

						free( s );
					}

					continue;

				} else {

					val = pfget_double( dlspf, key );
				}

				archive_dlsvar( db, net, sta, dls_var, 
						(char *) getarr( Dls_vars_dsparams, dls_var ),
						(Tbl *) getarr( Dls_vars_rras, dls_var ),
						time, val );
			   }

			}

			freetbl( dlspfkeys, 0 );
			freetbl( Dls_vars_keys, 0 );

		} else if( rc == Pkt_stash ) {

			; /* Do nothing */

		} else {

			if( Verbose ) {

				elog_notify( 0, "Received a packet that's not a parameter file " 
					"(type '%d' from unstuffPkt); skipping\n", rc );
			}
		}
	}
}
Example #17
0
void main(int argc, char **argv)
{
	Dbptr db, dbv, dbge, dbgg;
	/*ensemble_mode is primary grouping, grouping_on set if secondary on*/
	int ensemble_mode,grouping_on;
	Tbl *ensemble_keys;
	Tbl *group_keys;
	int i;
	char *pfi=NULL;
	Pf *pf,*pfo_head,*pfo_total;
	Tbl *process_list;
	int dryrun=0;
	char *sift_exp=NULL;
	int sift;
/*Attributes listed in require will abort program if missing
passthrough parameters will generate an error message but not
cause the program to abort.  Both contain pointers to Attribute_map*/
	Tbl *require,*passthrough;
	Attribute_map *amap;
	FILE *fp;
	Tbl *error_list;
	char *tag;
	int sleep_time;  

	DB2PFS_verbose=0;

/*crack the command line*/
	if(argc<3) usage();
	elog_init(argc,argv);
	if(dbopen(argv[1],"r",&db)==dbINVALID)
	{
		elog_complain(0,"dbopen failed on database %s\n",argv[1]);
		usage();
	}

	for(i=3;i<argc;++i)
	{
		if(!strcmp(argv[i],"-pf"))
		{
			++i;
			if(i>argc) usage();
			pfi=argv[i];
		}
		else if(!strcmp(argv[i],"-V"))
			usage();
		else if(!strcmp(argv[i],"-v"))
			DB2PFS_verbose=1;
		else if(!strcmp(argv[i],"-n"))
			dryrun=1;
		else if(!strcmp(argv[i],"-sift"))
		{
			++i;
			if(i>argc) usage();
			sift=1;
			sift_exp=argv[i];
		}
		else
			usage();
	}
	if(!dryrun)
	{
		fp=fopen(argv[2],"r+");
		if(fp==NULL) usage();
	}
	
	if(pfi==NULL) pfi=strdup("db2pfstream");
	if(pfread(pfi,&pf))
		elog_die(0,"Error reading parameter file %s.pf\n",pfi);
	sleep_time=pfget_int(pf,"sleep_time");
	/* The output view gets a virtual table name that tags the
	overall collection of stuff.  This comes from the parameter file
	to make this program general, BUT it must be coordinated with
	the reader code. */
	tag = pfget_string(pf,"virtual_table_name");
	if(tag==NULL)elog_die(0,"Required parameter (virtual_table_name) missing from parameter file\n");
	ensemble_mode = pfget_boolean(pf,"ensemble_mode");
	if(ensemble_mode)
	{
		ensemble_keys=pfget_tbl(pf,"ensemble_keys");
		if(ensemble_keys==NULL)
			elog_die(0,
			 "ensemble_mode is on, but no grouping keys defined\nCheck parameter file\n");
		group_keys=pfget_tbl(pf,"group_keys");
		if(group_keys==NULL)
			grouping_on = 0;
		else
		{
			if(maxtbl(group_keys)>0)
				grouping_on = 1;
			else
				grouping_on = 0;
		}
	}
	if(DB2PFS_verbose && ensemble_mode)
	{
		char sm[128];
		char *key;
		strcpy(sm,"Defining ensemble with keys: ");
		for(i=0;i<maxtbl(ensemble_keys);++i)
		{
			key=gettbl(ensemble_keys,i);
			strcat(sm,key);
		}
		elog_log(0,"%s\n",sm);
		if(grouping_on)
		{
			strcpy(sm,"Grouping ensemble with keys:  ");
			for(i=0;i<maxtbl(group_keys);++i)
			{
				key = gettbl(group_keys,i);
				strcat(sm,key);
			}
			elog_log(0,"%s\n",sm);
		}
	}

	
	/*This function calls dbprocess using a tbl from pf*/
	dbv=dbform_working_view(db,pf,"dbprocess_list");
	if(dbv.record==dbINVALID)
		elog_die(0,"dbprocess failed:  check database and parameter file parameter dbprocess_list\n");
	if(sift_exp!=NULL)dbv=dbsubset(dbv,sift_exp,0);
	/*Now we form the groupings if needed */
	if(ensemble_mode)
	{
		dbge = dbgroup(dbv,ensemble_keys,"ensemble",1);
		if(dbge.record == dbINVALID)
			elog_die(0,"dbgroup with ensemble keys failed\n");
		if(grouping_on)
		{
			dbgg = dbgroup(dbv,group_keys,"groups",2);
			if(dbgg.record == dbINVALID)
				elog_die(0,"dbgroup on secondary grouping keys failed\n");
		}
	}

/*This builds the maps of which attributes will be saved */
	require = pfget_Attribute_map(pf,"require");
	if(require==NULL)
		elog_die(0,"Error in parameter file for parameter require\n");
	passthrough = pfget_Attribute_map(pf,"passthrough");
	if(passthrough==NULL)
		elog_die(0,"Error in parameter file for parameter passthrough\n");
	/* Unfortunately, we have two different loops for ensemble mode
	 and single object mode */
	if(ensemble_mode)
	{
		int number_ensembles;
		Dbptr db_bundle_1;
		Dbptr db_bundle_2;
		int is_ensemble, ie_ensemble;
		int isg, ieg;
		int number_groups;

		pfo_head=pfnew(0);
		pfput_tbl(pfo_head,"ensemble_keys",ensemble_keys);
		if(grouping_on) pfput_tbl(pfo_head,"group_keys",group_keys);
	

		dbquery(dbge,dbRECORD_COUNT,&number_ensembles);
		if(DB2PFS_verbose) elog_log(0,"database has %d ensembles\n",
					number_ensembles);
		if(grouping_on) 
		{
			dbgg.record=0;
			dbquery(dbgg,dbRECORD_COUNT,&number_groups);
			if(DB2PFS_verbose)
			  elog_log(0,"database has %d subgroups\n",
				number_groups);
		}
		for(dbge.record=0;dbge.record<number_ensembles;
					++dbge.record)
		{
			Pf_ensemble *pfe;
			int nmembers;
			char *grp_records;
			Tbl *grplist;

			dbgetv(dbge,0,"bundle",&db_bundle_1,0);
			dbget_range(db_bundle_1,&is_ensemble,&ie_ensemble);
			nmembers = ie_ensemble-is_ensemble;
			/* pfe does not need to hold the group records
			for this application so the ngroups variable is 
			passed as 0*/
			pfe=create_Pf_ensemble(nmembers,0);
			/*Now loop through and load the array of pf's
			with parameters defined by the attribute maps*/
			for(i=0,dbv.record=is_ensemble;i<nmembers;
				++i,++dbv.record)
			{
				pfe->pf[i]=pfnew(PFARR);
				error_list=db2pf(dbv,require,pfe->pf[i]);
				if(maxtbl(error_list)>0)
				{
				    if(dryrun)
				    {
					elog_log(0,"Ensemble %d at input database view record %d lacks required attributes\n",
						dbge.record,dbv.record);
					log_error_list(error_list);
				    }
				    else
				    {
					fprintf(fp,"%s\n",END_OF_DATA_SENTINEL);
					fflush(fp);
					elog_log(0,"FATAL ERROR: ensemble %d at input database view record %d lacks required attributes\nOUTPUT DATA STREAM TRUNCATED\n",
						i,dbv.record);
					log_error_list(error_list);
					exit(-1);
				    }
				}
				freetbl(error_list,free);
				error_list=db2pf(dbv,passthrough,pfe->pf[i]);
				if(DB2PFS_verbose)
				{
					elog_log(0,"Warning:  null passthrough attributes for ensemble %d at row %d\n",
						dbge.record,dbv.record);
					log_error_list(error_list);
				}
				freetbl(error_list,free);
				pfput_boolean(pfe->pf[i],"data_valid",1);
			}
			
			if(grouping_on)
			{
				grplist=newtbl(0);
				do {
				     dbgetv(dbgg,0,"bundle",&db_bundle_2,0);
				     dbget_range(db_bundle_2,&isg,&ieg);
				     grp_records=malloc(30);
				     sprintf(grp_records,"%d %d",
					isg-is_ensemble,ieg-is_ensemble-1);
				     pushtbl(grplist,grp_records);
				     ++dbgg.record;
				}
				while (ieg<ie_ensemble);
				pfput_tbl(pfo_head,"group_records",grplist);
			}

			pfo_total=build_ensemble(1,tag,pfo_head,pfe);
			free_Pf_ensemble(pfe);
			if(!dryrun) 
			{
				pfout(fp,pfo_total);
				fprintf(fp,"%s\n",ENDPF_SENTINEL);
				fflush(fp);
			}
			pffree(pfo_total);
			if(grouping_on)freetbl(grplist,free);
		}
	}
	else
	{
	/*This is the simpler, single block mode */
		int nrecords;
		Pf *pfo;

		dbquery(dbv,dbRECORD_COUNT,&nrecords);
		pfo=pfnew(PFARR);
		for(dbv.record=0;dbv.record<nrecords;++dbv.record)
		{
			error_list=db2pf(dbv,require,pfo);
			if(maxtbl(error_list)>0)
			{
			    if(dryrun)
			    {
				elog_log(0,"Input database view at row %d lacks required parameters\n",
					dbv.record);
				log_error_list(error_list);
			    }
			    else
			    {
				fprintf(fp,"%s\n",END_OF_DATA_SENTINEL);
				fflush(fp);
				elog_log(0,"FATAL: input database view at row %d lacks required parameters\n",
					dbv.record);
				log_error_list(error_list);
				exit(-1);
			    }
			}
			freetbl(error_list,free);
			error_list=db2pf(dbv,passthrough,pfo);
			pfput_boolean(pfo,"data_valid",1);
			if(DB2PFS_verbose)
			{
				elog_log(0,"Warning:  null passthrough attributes for row %d of input database view\n",
					dbv.record);
			}
			if(!dryrun)
			{
				pfout(fp,pfo);
				fprintf(fp,"%s\n",ENDPF_SENTINEL);
			}
		}
	}
	if(!dryrun)
	{
		fprintf(fp,"%s\n",END_OF_DATA_SENTINEL);
		fflush(fp);
		sleep(sleep_time);
		fclose(fp);
	}
	exit(0);
}
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;
}
Example #19
0
int main(int argc, char **argv)
 { Pf 		*pf;
   char		*orbname,
		*dbname,
		*expr,
		*table,
		*rowtemp,
                verbose;
   int  	orb,
		totalrecords,
		records,
 		record;
   Dbptr  	db,
		dbinput,
		dbscratch;

  elog_init(argc,argv);		

  /* initialize variables */

  verbose = 0;
  expr = NULL;
  loop = 0;
  record = 0;
  totalrecords = 0;

  rowtemp = malloc(ROW_MAX_LENGTH);
  
  if (rowtemp == NULL) die(1,"malloc() error.\n");

  /* read in command line options */

  { int c;
    unsigned char errflg = 0;

    while (( c = getopt( argc, argv, "vl:s:")) != -1)
        switch (c) {
          case 'l': loop = atoi(optarg);
                    sigset(SIGINT,done);
                    break;
          case 's': expr = optarg;
                    break;
          case 'v': verbose = 1;
                    break;
          case '?': errflg++;
        }

    if ( (argc - optind) != 3 ) errflg++;

    if (errflg) 
       { elog_die(0,"usage: %s [-v] [-s subset] [-l delay] db table orb\n",argv[0]); 
       }
    
    dbname = argv[optind++];
    table  = argv[optind++];
    orbname= argv[optind++];
  }
    
  /* start our work */

  if ( dbopen ( dbname,  "r+",  &dbinput ) == dbINVALID )
     { elog_die(1,"Couldn't open input database, \"%s\".\n",dbname); }

  dbinput   = dblookup( dbinput, 0, table, 0, 0);
  dbscratch = dblookup( dbinput, 0, 0, 0, "dbSCRATCH");

  if ( dbinput.table == dbINVALID )
   { elog_die(1,"Couldn't lookup the table \"%s\" in the database \"%s\".\n",
		table,dbname); }
  if ( dbscratch.record == dbINVALID )
   { elog_die(1,"Couldn't lookup the scratch record in the database \"%s\".\n",
		dbname); }
  
  if ( dbquery( dbinput, dbRECORD_COUNT, &records) < 0 )
   { elog_die(1,"dbquery dbRECORD_COUNT failed.\n"); }

  orb      = orbopen( orbname, "w&" );

  if ( orb == -1 )
   { elog_die(1,"Couldn't open the orb, \"%s\".\n",orbname); }

  if (loop == 0) loop = -1;

  while (loop)
   { db = dbinput;
     
     if ( expr != NULL) db = dbsubset( db, expr, 0 );
     
     db.record = record;

     if ( dbquery( db, dbRECORD_COUNT, &records) < 0 )
   	 elog_die(1,"dbquery dbRECORD_COUNT failed.\n");  
     
     for (;db.record<records;db.record++)
       { if (verbose) printf("writing record %d to orb...\n",db.record); 

         /* copy the row from what could be a view into the scratch record of the
            input database, so as to avoid putting a view on the ORB */
         if ( dbget( db,        rowtemp) == dbINVALID ) die(1,"dbget error.\n");
         if ( dbput( dbscratch, rowtemp) == dbINVALID ) die(1,"dbput error.\n");

         if ( db2orbpkt( dbscratch, orb ) < 0 )
            { complain ( 0, "Couldn't write record #%d to %s.\n",
              	   db.record, orbname); } 
         totalrecords++;
       }

     record = db.record; 

     /* if a subset expression was supplied, then we're working with
        a view, which should be freed. */

     if ( expr != NULL) dbfree(db);
     if ( loop == -1 ) loop = 0;
     sleep(loop);
   } 

  printf("posted %d records from database %s to orb %s.\n",totalrecords,dbname,orbname);
  dbclose(dbinput);
  orbclose(orb); 
  free(rowtemp);
 }