コード例 #1
1
int
main (int argc, char **argv)
{

    int             c,
                    errflg = 0;

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

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

	


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

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

	  case 'r':
	    reject = optarg;
	    break;

	  case 'S':
	    statefile = optarg;
	    break;

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

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

	  case '?':
	    errflg++;
	}
    }

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

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

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

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

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

	db = dbtmp("rt1.0");

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

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

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

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

					}
				}
			}
			
	    }

	    last_pktid = pktid;
	    last_pkttime = pkttime;
	}

    }

    if (statefile != 0)
	bury ();

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

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

    if (orbclose (orbin)) {
	elog_complain (1, "error closing read orb\n");
    }
    if (orbclose (orbout)) {
	elog_complain (1, "error closing write orb\n");
    }
    return 0;
}
コード例 #2
0
/* Implements error ellipses from input covariance matrix assuming 
particular error model defined by "model".  
(inputs)
C - 4x4 covariance matrix in order x,y,z,t.  If depth is fixed it is assumd
	all the z terms have been zeroed.  Use of an eigenvector routine 
	assures it will still be stable and algorithms used should still
	all be stable.  
model - error model (CHI_SQUARE or F_DIST defined in location.h) 
conf - confidence level (this function will complain if not 0.683 or 0.9
	and round to closest)  Must be 0<conf<1.0  This value is altered
	to one of these values if necessary.
rms - residual norm used to scale error ellipse in F distribution model 
	(ignored with chisquare model)
dgf - number of degrees of freedom (enters only in F_DIST case, ignored
	for chi-square error model)
(outputs)
smajax, sminax, strike - horizontal error ellipse as defined in css3.0
sdepth, stime - depth and time error attributes in css3.0

Normal return is 0.  Returns -1 if computation totally fails.  Calling
function should trap this condition results are all set 0 in that 
situation.
Written:  November 2000
Authors:  G Pavlis and Kent Lindquist
*/
int project_covariance(double **C, int model, double *conf, double rms, int dgf,
		double *smajax, double *sminax, double *strike,
		double *sdepth, double *stime)
{
	int i ;
	double cwork[16];  /* covariance subset work space in FORTRAN order*/
	/* These are chisquare critical values.  First index is critical
	level and second is degrees of freedom.  e.g. 
	chisq_crit[1][2] is 90% level for 3 dgf*/
	double chisq_crit[2][3]={{1.001284,2.297707,3.529159},
               {2.705543, 4.60517, 6.251389}};
	double evals[4];
	double vwork[16];
	int info,ecount=0;
	int iconf;

	if((*conf<=0.0) || (*conf>=1.0))
	{
		elog_complain(0,"project_confidence passed illegal confidence level.  Default to 68.3 percent\n");
		iconf = 0;
	}
	if(fabs(*conf-0.683)<0.001)
		iconf = 0;
	else if(fabs(*conf-0.9)<0.001)
		iconf = 1;
	else
	{
		elog_complain(0,"Confidence level %f not implemented--default to 68%%\n",*conf);
		iconf = 0;
	}
	/* first compute the horizontal error ellipse, unscaled.
	This uses the packed storage mode of lapack */
	cwork[0] = C[0][0];
	cwork[1] = C[1][0];
	cwork[2] = C[1][1];
	/* this is CLAPACK/sunperf routine to compute eigenvalues and
	eigenvectors for a positive definite matrix */
	dspev('v','l',2,cwork,evals,vwork,2,&info);
	if(info<0)
	{
		elog_complain(0,"dspev illegal value\n");
		return(-1);
	}
	else if(info>0) 
	{
		elog_notify(0,"dspev convergence failure.  Error ellipse esults may be unreliable\n");
		++ecount;
	}
	/* dspev returns eigenvalues in ascending order of size */
	switch(model)
	{
	case(F_DIST):
		elog_complain(0,"F distribution not yet implemented--default to chi-square\n");
	case(CHI_SQUARE):
	default:
		*smajax = chisq_crit[iconf][1]*sqrt(evals[1]);  /*2 dgf */
		*sminax = chisq_crit[iconf][1]*sqrt(evals[0]);
		*strike= 90.0 - deg(atan2(vwork[3],vwork[2]));
		/* phase-wrap so the principal value of the arctangent 
		   maps to the valid range of the CSS origerr.strike field */
		if( *strike < 0 ) *strike += 360.;
	}
	/* Now we have to do the full covariance to properly compute
	the depth and time uncertainties*/
	cwork[0] = C[0][0];
	cwork[1] = C[1][0];
	cwork[2] = C[2][0];
	cwork[3] = C[3][0];
	cwork[4] = C[1][1];
	cwork[5] = C[2][1];
	cwork[6] = C[3][1];
	cwork[7] = C[2][2];
	cwork[8] = C[3][2];
	cwork[9] = C[3][3];
	dspev('v','l',4,cwork,evals,vwork,4,&info);	
	if(info<0)
	{
		elog_complain(0,"dspev illegal value\n");
		return(-1);
	}
	else if(info>0) 
	{
		elog_notify(0,"dspev convergence failure.  Error ellipse esults may be unreliable\n");
		++ecount;
	}

	/* We scale each eigenvector by the eigenvalue and find
	the largest z and t components to compute errors in z and t*/
	for(i=0;i<4;++i)dscal(4,sqrt(evals[i]),vwork+4*i,1);
	i = idamax(4,vwork+2,4);
	/* Note sunperf implementation of blas returns an index based
	from 0 ala C while the FORTRAN version uses 1.  Dangerous
	inconsistency to watch out for. */
        /* This is the sunperf version 
	*sdepth = fabs(vwork[2+i*4]); 
        This is the correct version for perf which returns 1-4 */
        *sdepth =fabs(vwork[2+(i-1)*4]);
	i = idamax(4,vwork+3,4);
        /* other old sunperf version 
	*stime = fabs(vwork[3+i*4]); */
        *stime = fabs(vwork[3+(i-1)*4]);
	switch(model)
	{
	case(F_DIST):
	case(CHI_SQUARE):
	default:
		*sdepth *= chisq_crit[iconf][0];
		*stime *= chisq_crit[iconf][0];
	}
	return(ecount);
}
コード例 #3
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;
}
コード例 #4
0
ファイル: orb2rrdc.c プロジェクト: battistuz/antelope_contrib
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 );
			}
		}
	}
}
コード例 #5
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 ;
}
コード例 #6
0
ファイル: decimate.c プロジェクト: nimanshr/antelope_contrib
int read_dec_files (Tbl *decdef, int *dec_fac, Tbl **decimators)

{
    int i, j, n;
    Response *rsp;
    char string[512];
    FILE *file;

    FIR_decimation *decptr;
    Response *resp;

    resp = (Response *) new_response ();

    if(*decimators == NULL) *decimators = newtbl(0);
    if (resp == NULL) {
        elog_die(0, "read_dec_files: Malloc error on decimation response structure.\n");
        return (0);
    }
    for (i=0,(*dec_fac)=1; i<maxtbl(decdef); i++) {
        int ok;
        char *decfile;
        decfile = gettbl(decdef,i);
        if(!strcmp(decfile,"none") )
        {
            *dec_fac = 1.0;
            decptr = (FIR_decimation *) malloc(sizeof(FIR_decimation));
            if(decptr == NULL)
            {
                elog_notify(0,"Cannot malloc decimation structure for stage %d\n",
                            i);
                return(0);
            }
            decptr->decfac = 1.0;
            decptr->ncoefs = 0;
            decptr->coefs=NULL;
            pushtbl(*decimators,decptr);
            return(2);
        }

        file = fopen(decfile, "r");
        if (file == NULL) {
            elog_notify(0, "read_dec_files: Unable to open response stage file '%s'.\n",
                        decfile);
            return (0);
        }
        if (read_response (file, &rsp)) {
            elog_clear_register(1);
            elog_notify(0, "read_dec_files: read_response() error on stage file '%s'.\n",
                        decfile);
            return (0);
        }
        fclose (file);
        get_response_nstages (rsp, &n);
        for (j=0,ok=0; j<n; j++) {
            int dec_factor, nnum, nden;
            double srate;

            get_response_stage_type (rsp, j, string);
            if (strcmp(string, "fir")) continue;
            get_response_stage_fir_ncoefs (rsp, j, &srate, &dec_factor, &nnum, &nden);
            if (nden > 1) {
                elog_notify(0, "read_dec_files: Dont know how to do IIR filters (%s).\n",
                            decfile);
                return (0);
            }
            if (nnum < 1) {
                elog_notify(0, "read_dec_files: No numerator terms (%s).\n",
                            decfile);
                return (0);
            }
            ok=1;
            (*dec_fac) *= dec_factor;
        }
        if (!ok) {
            elog_notify(0, "read_dec_files: no fir stage on file '%s'.\n",
                        decfile);
            return (0);
        }
        for (j=0; j<n; j++) {
            Response_group *gpi;

            get_response_stage_type (rsp, j, string);
            if (strcmp(string, "fir")) continue;
            gpi = rsp->groups + j;
            if (copy_response_group (gpi, (resp), -1) < 0) {
                elog_notify(0, "read_dec_files: copy_response_group() error.\n");
                return (0);
            }
        }
        free_response (rsp);
    }
    get_response_nstages ((resp), &n);

    for (i=0; i<n; i++) {
        Response_group *gpi;
        int dec_factor, nnum, nden;
        double srate;
        double *coefsi, *coefs_err;
        double *coefdi, *coefd_err;

        decptr = (FIR_decimation *) malloc(sizeof(FIR_decimation));
        if(decptr == NULL)
        {
            elog_notify(0,"Cannot malloc decimation structure for stage %d\n",
                        i);
            return(0);
        }

        gpi = (resp)->groups + i;
        get_response_stage_fir_ncoefs ((resp), i, &srate, &dec_factor, &nnum, &nden);
        get_response_stage_fir_coefs ((resp), i, &nnum, &coefsi, &coefs_err,
                                      &nden, &coefdi, &coefd_err);
        for (j=0; j<nnum/2; j++) if (coefsi[j] != coefsi[nnum-j-1]) break;
        if (j < nnum/2) {
            elog_notify(0, "read_dec_files: Can only do symetrical FIR filters.\n");
            return (0);
        }

        decptr->ncoefs = nnum;
        decptr->decfac = dec_factor;
        decptr->coefs = calloc(nnum,sizeof(float));
        if((decptr->coefs) == NULL)
            elog_die(0,"read_dec_files:  can't alloc filter coef array of length %d\n",nnum);
        for(j=0; j<nnum; j++) decptr->coefs[j] = coefsi[j];
        pushtbl(*decimators,decptr);
    }
    return (1);
}
コード例 #7
0
void compute_location(Location_options o,
	RTlocate_Options rtopts,
	Arr *stations, Arr *arrays, Arr *phases, 
	Pf *pf,
	Dbptr master_db, Dbptr dbtmp, ORB_Hypocenter hyp, int orbout)
{
	Tbl *ta,*tu;  /* Arrival and slowness tables respectively */
	Hypocenter h0;
	int ret_code;
	Tbl *converge_history,*reason_converged,*residual;
	Hypocenter *hypo;
	int niterations;
	char *vmodel;
	int i;
	char *s;
	int orid;
	Point origin;
	double delta, seaz;
	double **C;
	float *emodel;
	int nass;

	initialize_hypocenter(&h0);

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

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

	vmodel = pfget_string(pf,"velocity_model_name");

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

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

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

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

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

	}
	destroy_data_tables(ta, tu);
	return;
}
コード例 #8
0
int
main(int argc, char **argv)
{
	int             verbose = 0;


	char           *dbname = malloc(STRSZ);
	char           *datafilename = malloc(STRSZ);
	char           *name = malloc(STRSZ);
	char           *line = malloc(STRSZ);
	char            str1[20], str2[20], *str3 = malloc(1024);
	int             level = 0;
	int             closed = 0, close = 0;
	int             maxpoints = 5000;
	Point          *poly = malloc(maxpoints * sizeof(double));
	double          lat, lon;

	long             npoints;
	char           *auth = malloc(STRSZ);
	char            ptype[STRSZ];
	char           *dir = malloc(STRSZ), *dfile = malloc(STRSZ), *tname = malloc(STRSZ),
	                numstr[10];
	int             ftype = polyFLOAT;
	Dbptr           db;
	FILE           *fh;
	int             putit;
	int             polycounter = 0;

	elog_init(argc, argv);


	my_username(auth);
	strcat(auth, ":gmt");
	strcpy(name, "-");
	strcpy(dir, "-");
	strcpy(dfile, "gmt.bin");
	strcpy(ptype, "-");
	for (argc--, argv++; argc > 0; argc--, argv++) {
		if (!strcmp(*argv, "-auth")) {
			argc--;
			argv++;
			if (argc < 3) {
				elog_complain(0, "Need -auth argument.\n");
				usage();
				exit(1);
			}
			auth = *argv;
		} else if (!strcmp(*argv, "-dir")) {
			argc--;
			argv++;
			if (argc < 3) {
				elog_complain(0, "Need -dir argument.\n");
				usage();
				exit(1);
			}
			dir = *argv;
		} else if (!strcmp(*argv, "-dfile")) {
			argc--;
			argv++;
			if (argc < 3) {
				elog_complain(0, "Need -dfile argument.\n");
				usage();
				exit(1);
			}
			dfile = *argv;
		} else if (!strcmp(*argv, "-pname")) {
			argc--;
			argv++;
			if (argc < 3) {
				elog_complain(0, "Need -pname argument.\n");
				usage();
				exit(1);
			}
			name = *argv;
		} else if (!strcmp(*argv, "-ptype")) {
			argc--;
			argv++;
			if (argc < 3) {
				elog_complain(0, "Need -ptype argument.\n");
				usage();
				exit(1);
			}
			strncpy(ptype, *argv, 2);
		} else if (!strcmp(*argv, "-level")) {
			argc--;
			argv++;
			if (argc < 3) {
				elog_complain(0, "Need -level argument.\n");
				usage();
				exit(1);
			}
			level = atoi(*argv);
		} else if (!strcmp(*argv, "-close_polygons")) {
			close = 1;
		} else if (!strcmp(*argv, "-v")) {
			verbose++;
		} else if (**argv != '-') {
			break;
		} else {
			elog_complain(0, "unrecognized argument '%s'\n", *argv);
			usage();
			exit(1);
		}
	}
	if (argc < 2) {
		elog_complain(0, "Need datfile and db arguments.\n");
		usage();
		exit(1);
	}
	datafilename = *argv;
	argc--;
	argv++;
	dbname = *argv;
	if (access(datafilename, 4)) {
		elog_die(0, "datafile %s should be READABLE!\n", datafilename);
	}
	if (dbcreate(dbname, "polygon1.2", 0, 0, 0)) {
		elog_die(1, "can't create database %s\n", dbname);
	}
	if (!strcmp(name, "-")) {
		strcpy(name, datafilename);
	}
	dbopen(dbname, "r+", &db);
	db = dblookup(db, 0, "polygon", 0, 0);
	fh = fopen(datafilename, "r");
	putit = 0;
	npoints = 0;
	polycounter = 0;
	while (fgets(line, 80, fh) != 0) {
		if (line[0] == '>') {
			if (putit) {
				strcpy(tname, name);
				if (polycounter > 0) {
					sprintf(numstr, ".%d", polycounter);
					tname = strcat(tname, numstr);
				}
				if (verbose) {
					elog_notify(0, "%s: (%ld points n file %s/%s)\n", tname, npoints, dir, dfile);
				}
				if (npoints > 2 && (close || (
				 (poly[0].lat == poly[npoints - 1].lat) &&
				(poly[0].lon == poly[npoints - 1].lon)))) {
					closed = 1;
				}
				writePolygonData(db, poly, npoints, tname, closed, level, ptype, auth, dir, dfile, ftype);
				closed = 0;
				polycounter++;
			}
			strtrim(line);
			npoints = 0;
			putit = 1;
		} else {
			sscanf(line, "%s %s %s", str1, str2, str3);
			lon = atof(str1);
			lat = atof(str2);
			if (npoints > maxpoints - 2) {
				maxpoints += 5000;
				poly = realloc(poly, maxpoints);
			}
			poly[npoints].lat = lat;
			poly[npoints].lon = lon;
			npoints++;
		}
	}
	if (npoints > 0) {
		strcpy(tname, name);
		if (polycounter > 0) {
			sprintf(numstr, ".%d", polycounter);
			strcat(tname, numstr);
		}
		if (verbose) {
			elog_notify(0, "%s: (%ld points n file %s/%s)\n", tname, npoints, dir, dfile);
		}
		if (npoints > 2 && (close || (
				 (poly[0].lat == poly[npoints - 1].lat) &&
			       (poly[0].lon == poly[npoints - 1].lon)))) {
			closed = 1;
		}
		writePolygonData(db, poly, npoints, tname, closed, level, ptype, auth, dir, dfile, ftype);
		closed = 0;
	}
	fclose(fh);
	elog_print(0, 0);
	return 0;
}
コード例 #9
0
ファイル: svdcmp.c プロジェクト: battistuz/antelope_contrib
int svdcmp (float **A, int m, int n, float *s, float **V)
{
	float *afort, *vfort;  /*Vector format work spaces */
	int i;
	int info=0;
#ifndef SUNPERF
	int one=1;
	float *swork;
	int ldwork;
#endif

	/*Alloc work spaces and copy from numerical recipes matrix
	form to the form sunperf wants */

	afort = (float *) calloc(m*MAX(m,n),sizeof(float));
	vfort = (float *) calloc(n*n,sizeof(float));
	if( (afort == NULL) || (vfort == NULL))
		die(0,"svdcmp could not alloc work arrays\n");
#ifdef SUNPERF
	for(i=0;i<m;++i)
		scopy(n,A[i],1,(afort+i),m);
#else
        for(i=0;i<m;++i)
                scopy_(&n,A[i],&one,(afort+i),&m);
#endif
	/* old rule:  always initialize things like this */
	for(i=0;i<n*n;++i) vfort[i] = 0.0;

#ifdef SUNPERF
	sgesvd('o','s',m,n,afort,m,s,NULL,m,vfort,n,&info);
#else
	ldwork = 12+2*n;  /* This is slightly larger than the minimum
			required for safety.  Space required is never
			large by modern standards  */
	swork = calloc(ldwork,sizeof(float));
	if(n == NULL) die(0,"Cannot alloc work space for SVD routine\n");
	sgesvd_("o","s",&m,&n,afort,&m,s,NULL,&m,vfort,&n,
		swork, &ldwork,
		&info);
	free(swork);
#endif
	if(info!=0)
	{
		if(info > 0)
                	elog_notify(0,"Convergence failure in svd routine\n");
		else
			elog_notify(0,"Illegal value for argument %d passed to sgesvd\nNo solution possible\n",
			-info);
		free(afort);
		free(vfort);
		return(info);
	}
#ifdef SUNPERF
	/* note we do return something even when convergence failed.
	Must handle negative return as junk is returned then. */
	for(i=0;i<m;++i)
		scopy(n,(afort+i),m,A[i],1);
	/* Note this copies V transpose in vfort to V in the matrix V.  
	Tricky BLAS code I know*/
	for(i=0;i<n;++i)
		scopy(n,(vfort+i*n),1,V[i],1);
#else
	for(i=0;i<m;++i)
                scopy_(&n,(afort+i),&m,A[i],&one);
        for(i=0;i<n;++i)
                scopy_(&n,(vfort+i*n),&one,V[i],&one);
#endif


	free(afort);
	free(vfort);
	return(0);
}
コード例 #10
0
/* This function creates the mwslow table output of mwap.
This table hold slowness vector estimates.

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

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

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

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

	if( dbaddv(db,0,"sta",array,
		"evid",evid,
		"bankid",bankid,
		"phase", phase,
		"fc",fc,
		"fwin",fwin,
		"time",t0,
		"twin",twin,
		"slo",slo,
		"azimuth",azimuth,
		"cxx",C[0],
		"cyy",C[4],
		"cxy",C[1],
		"nsta",nsta,
		"ncomp",ncomp,
		"cohtype",cmeasure,
		"cohmeas",peakcm,
		"algorithm","mwap",0) < 0) 
	{
		elog_notify(0,
			"dbaddv error for mwslow table on evid %d fc=%lf\n",
				evid,fc);
		return(-1);
	}
	else
		return(0);
}
コード例 #11
0
/* This function saves particle motion parameter estimates to a extension
table called mwpm.  Individual station estimates and an array average
estimate are all saved in the same table.  they can be sorted out through
the key field pmtype set to "ss" for single station and "aa" for array average.

Arguments:

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

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

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

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

	nsta = g->nsta;

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

				++errcount;
			}
		}
	}
	/* now we add a row for the array average.  This is flagged only
	by the pmtype field.  */
	scoor = unit_vector_to_spherical(pmavg->major);
	majaz = 90.0 - deg(scoor.phi);
	majema = deg(scoor.theta);
	scoor = unit_vector_to_spherical(pmavg->minor);
	minaz = 90.0 - deg(scoor.phi);
	minema = deg(scoor.theta);
	if( dbaddv(db,0,
		"sta",array,
		"bankid",bankid,
		"fc",fc,
		"phase",phase,
		"evid",evid,
		"time",time,
		"twin",twin,
		"pmtype","aa",
		"majoraz",majaz,
		"majorema",majema,
		"minoraz",minaz,
		"minorema",minema,
		"rect",pmavg->rectilinearity,
		"errmajaz",deg(pmaerr->dphi_major),
		"errmajema",deg(pmaerr->dtheta_major),
		"errminaz",deg(pmaerr->dphi_minor),
		"errminema",deg(pmaerr->dtheta_minor),
		"errrect",pmaerr->delta_rect,
		"majndgf",pmaerr->ndgf_major,
		"minndgf",pmaerr->ndgf_minor,
		"rectndgf",pmaerr->ndgf_rect,
	   "algorithm","mwap",0) < 0) 
	{
		elog_notify(0,"dbaddv error saving array average particle motion parameters in mwpm table for evid %d\n",
			evid);
		++errcount;
	}
	return(errcount);
}
コード例 #12
0
int MWdb_save_statics(
	int evid, 
	int bankid,
	char *phase,
	double fc,
	double t0,
	double twin,
	double refelev,
	MWgather *g,
	double *moveout,
	Arr *statics,
	Arr *stations,
	Arr *snrarr,
	Arr *arrivals,
	Arr *model_times,
	Dbptr db)
{
	char *sta;
	int i;
        MWstatic *mws;
	MWstation *s;
	Signal_to_Noise *snr;
	int errcount=0;
	double time;
	int nsta;
	Dbptr dbt, dba, dbsnr;
	double ampdb, aerrdb;  
	double *atime,*modtime,resid;
	int ierr;

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

	nsta = g->nsta;

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

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

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

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

				++errcount;
			    }
			}
			
		}
	}
	return(errcount);
}
コード例 #13
0
int
main (int argc, char **argv)
{
    int		   c ;
    char           *liss_server ;
    int            timeout = 10;
    int		   verbose = 0 ;
    int		   defaultport = 4000 ;
    unsigned char *seed ;
    int 	   fd = -1 ;
    Bns 	   *bns=0 ;

    elog_init (argc, argv);
    announce(0,0) ;

    while ((c = getopt (argc, argv, "v")) != -1) {
	switch (c) {

	  case 'v':
	    verbose++ ;
	    break;

	  default:
	    usage ();
	}
    }
    if (argc - optind < 1)
	usage ();

    allot(unsigned char *, seed, SIZE) ; 
    for(;optind < argc;optind++) { 
	liss_server = argv[optind] ;
	elog_notify(0, "opening %s\n", liss_server) ; 
	fd = open_socket ( liss_server, defaultport ) ; 
	if ( fd < 0 ) { 
	    elog_complain ( 1, "Can't open liss server %s", liss_server ) ;
	} else { 
	    int out ;
	    bns = bnsnew(fd, 8192) ;
	    bnsuse_sockio(bns) ;
	    bnstimeout ( bns, timeout*1000 ) ;
	    bnsclr(bns) ;
	    bns->fd = fd ; 
	    elog_notify(0, "reading %d bytes from %s\n", SIZE, liss_server) ; 
	    if ( bnsget(bns, seed, BYTES, SIZE ) == 0 ) { 
		out = open(liss_server, O_WRONLY | O_CREAT, 0664 ) ;
		if ( out == 0 ) { 
		    elog_die (0, "Can't open %s to write", liss_server) ;
		}
		elog_notify(0, "writing %d bytes from %s\n", SIZE, liss_server) ; 
		if ( write(out, seed, SIZE) != SIZE ) { 
		   elog_complain(0, "failed to write %d bytes to %s", SIZE, liss_server) ; 
		}
		if ( close(out) != 0 ) { 
		    elog_complain(0, "failed to close %s", liss_server) ; 
		}
	    } else { 
		elog_complain(0, "Failed to read data from %s", liss_server) ; 
	    }
	    if ( bnsclose(bns) != 0 ) { 
		elog_complain(0, "failed to close bns #%d for %s", fd, liss_server) ; 
	    }
	}
    }

    return 0 ;
}
コード例 #14
0
/* This function computes a covariance estimate for slowness 
vector estimates computed by mwap.  It is very specialized
in that it contains hard wired 3 dimensions for the number
of unknowns in this problem.  This estimate is not at all the same
as that proposed in Bear and Pavlis (1997).  They used variations in
estimates made in semblance/slowness space.  Here we use the estimated
uncertainties in the static estimates as estimates of the data covariance
that is scaled by the inverse of the slowness estimation matrix to 
produce a covariance estimate for the slowness vector.  

This routine is confused greatly by being forced to use FORTRAN
indexing to mesh with sunperf.  This leads to some very messy
indexing in a somewhat tricky algorithm I use to compute the
covariance with the SVD components. 

Arguments:
	stations - associative array of station objects
	statics - associative array of MWstatic objects
	c - 3x3 covariance estimate (result) in order of
		ux, uy, dt

Normal return is 0.  Postive returns mean a nonfatal problem
occurred that will be posted to elog.  The routine dies only
from malloc errors.  

Author: G Pavlis
Written:  March 2000
Modified:  March 2002
Removed the sample interval floor on the error.  Previously this
function did not allow the error for a single station to drop
below the one sample lever.  This was done to be conservative
but the new algorithm seems capable of resolving subsample
timing.  Hence, I removed this feature.
*/
int compute_slowness_covariance(Arr *stations,Arr *statics,
				 double *c)
{
	double *A;
	double vt[9];
	double svalue[3];
	double work[9];
	double *Cd1_2;  /* holds vector of diagonal elements of 
		data covariance to 1/2 power (useful for scaling)*/
	int nsta;  /* number of stations = rows in A */
	int nsta_used;  /*actual value when problems happen */
	MWstatic *mws;
	MWstation *s;
	Tbl *t;  /* tbl of keys used to parse statics arr */
	char *sta;
	int i,j,ii;
	int errcount=0;
	int info;

	for(i=0;i<9;++i) c[i] = 0.0;

	t = keysarr(statics);
	nsta = maxtbl(t);

	allot(double *,A,3*nsta);
	allot(double *,Cd1_2,nsta);

	for(i=0,ii=0;i<nsta;++i)
	{
		sta = gettbl(t,i);
		mws = (MWstatic *)getarr(statics,sta);
		s = (MWstation *)getarr(stations,sta);
		if(s==NULL)
		{
			elog_notify(0,"Station %s has a computed MWstatic but is not in station table\nStation array may be corrupted\n",sta);
			++errcount;
		}
		else
		{
			A[ii] = s->deast;
			A[ii+nsta] = s->dnorth;
			A[ii+2*nsta] = 1.0;
			Cd1_2[ii] = (mws->sigma_t);
			++ii;
		}
	}
	nsta_used = ii;
	dgesvd('o','a',nsta,3,A,nsta_used,svalue,NULL,nsta,vt,3,&info);
	/* Now we just compute covariance as C=A+(Cd)(A+)T 
	A+ = VS+UT.  We first replace A by U*S+ */
	for(i=0;i<3;++i)
	{
		dscal(nsta_used,1.0/svalue[i],A+i*nsta,1);
	}
	/* Another devious trick -- row scaling by Cd1_2 elements 
	forms proto form of V [ S+UT]Cd[US+T] VT */
	for(i=0;i<nsta_used;++i) dscal(3,Cd1_2[i],A+i,nsta);

	/* Now compute the term in brackets above = [ S+UT]Cd[US+T] */
	for(i=0;i<3;++i)
	{
		for(j=0;j<3;++j)
			c[i+3*j] = ddot(nsta_used,A+i,1,A+j,1);	
	}
	/* Now we have to complete the products with V and VT.  
	First VT */
	for(i=0;i<3;++i)
		for(j=0;j<3;++j)
			work[i+3*j] = ddot(3,c+i,3,vt+j*3,1);
	/* then V */
	for(i=0;i<3;++i)
		for(j=0;j<3;++j)
			c[i+3*j] = ddot(3,vt+i*3,1,work+j*3,1);	

	free(A);
	free(Cd1_2);
	return(errcount);
}
コード例 #15
0
/* This function is used to check a list of pf names to verify they
are in the parameter space.  It is useful for any program that uses
parameter files that cracks the pf space anywhere except up front.
That is, the pf space is a convenient place to store all the run time
parameters of any program and is a convenient way to pass a large
control structure.  However, because flow can be complex it is possible
to have parameters that are only accessed deep within a program and 
in these situations it is desirable to run a check at program initialization
to verify the required parameters will be there when required.  

Normally a string variable will not cause pfget to die, but it will
here if it is listed as required

Parameters to be checked are grouped by type.  Each numerical fields
can contain an optional range check.  This is not allowed for strings.
Code below only checks int, double, boolean, and string variables.  Because of
the complexity of Tbl and Arrs I thought this not worth messing with.
Furthermore, it is not unusual to have an empty Tbl list or Arr that
the program should handle correctly.  

Function will die on the first occurence of a problem parameter.
It is void because it only returns if everything checks out.

Author:  Gary L. Pavlis
*/
void check_required_pf(Pf *pf)
{
	Tbl *t,*testtbl;
	Pf *pf_required;
	char *key;
	int i,j,nitems;
	int itest, ilowcheck, ihighcheck;
	double dtest, dlowcheck, dhighcheck;
	int bool;
	char *line;
	char *ctest;
	char name[50];

	/* This cracks the "required" &Arr dies if it isn't present 
	at all.  This assumes you wouldn't call this routine if you
	weren't serious about checking */
	if(pfget(pf,"require",(void **)&pf_required) != PFARR)
		die(0,"Arr of required parameters (require &Arr) missing from parameter space\nMust be present to execute this program\n");
	t=pfkeys(pf_required);
	for(i=0;i<maxtbl(t);++i)
	{
		key = gettbl(t,i);
		if(!strcmp(key,"int"))
		{
			testtbl = pfget_tbl(pf_required,"int");
			for(j=0;j<maxtbl(testtbl);++j)
			{
				line = gettbl(testtbl,i);
				nitems = sscanf(line,"%s%d%d",name,&ilowcheck,
							&ihighcheck);
				itest = pfget_int(pf,name);
				if(nitems == 3)
				{
					if( (itest < ilowcheck)
					  || (itest > ihighcheck) ) die(0,
						"Parameter %s has value %d which is outside required range of %d to %d\n",
						   name,itest,ilowcheck,ihighcheck);
				}
			}
		}
		else if(!strcmp(key,"double"))
		{
			testtbl = pfget_tbl(pf_required,"double");
			for(j=0;j<maxtbl(testtbl);++j)
			{
				line = gettbl(testtbl,i);
				nitems = sscanf(line,"%s%lg%lg",name,&dlowcheck,
							&dhighcheck);
				dtest = pfget_double(pf,name);
				if(nitems == 3)
				{
					if( (dtest < dlowcheck)
					  || (dtest > dhighcheck) ) die(0,
						"Parameter %s has value %lg which is outside required range of %lg to %lg\n",
						   name,dtest,dlowcheck,dhighcheck);
				}
			}
		}
		else if(!strcmp(key,"boolean"))
		{
			testtbl = pfget_tbl(pf_required,"boolean");
			for(j=0;j<maxtbl(testtbl);++j)
			{
				line = gettbl(testtbl,i);
				itest = pfget_boolean(pf,line);
			}
		}
		else if(!strcmp(key,"string"))
		{
			testtbl=pfget_tbl(pf_required,"string");
			for(j=0;j<maxtbl(testtbl);++j)
			{
				line = gettbl(testtbl,i);
				ctest = pfget_string(pf,line);
				if(ctest == NULL)
					die(0,"Missing required string variable = %s\n",
						line);
			}
		}
		else
		{
			elog_notify(0,"Unknown required type name = %s\nRequired parameters under this heading will not be checked\n",
				key);
		}
	}
	freetbl(t,0);
}
コード例 #16
0
/* this is a blas like function analogous to scopy, dcopy, etc
for a matrix of pointers to Particle_Motion_Vector objects.  I could
have made this a general matrix function, I suppose, but I decided that
would be a bit opaque, and would promote on of C's most evil features.
The pointers are blindly copied and it assumed the output vector 
bounds are not violated.

Arguments:
	n - number of elements in input and output vectors]
	x - input vector of pointers
	incx - storage increment of x ala blas
	y - output vector
	incy - storage increment of y ala blas.
Written:  February 2000
Author:  G Pavlis
*/
void pmvector_copy(int n, Particle_Motion_Ellipse *x, int incx,
			Particle_Motion_Ellipse *y, int incy)
{
	int i,ix,iy;

	for(i=0,ix=0,iy=0;i<n;++i,ix+=incx,iy+=incy)
	{
		y[iy] = x[ix];
	}
}
#define PM_MINSCALE_MAJOR 0.2  /* This needs to be pretty large compared to 
				good data because if the errors get much
				larger than this the results are trash anyway */
#define PM_MINSCALE_MINOR 1.0 /* Minor axis can easily be totally random.  
				Nearly always happens for pure linear pm.
				This essentially turns off robust weighting */
void pmvector_average(Particle_Motion_Ellipse *pmv, int n,
	Particle_Motion_Ellipse *pmavg, Particle_Motion_Error *pmerr)
{
	int i,j,ii;
	double *v;  /* work space used to store coordinates passed
			to m-estimator routine */
	double avg[3];
	double *weight;
	double nrm_major, nrm_minor;  
	Spherical_Coordinate scoor;
	double U[9];   /* transformation matrix*/
	double work[3];
	double *workn;
	double dotprod;
	double sumsq,sumwt;
	int ndgf;
	MW_scalar_statistics stats;
	double nrmtest;

	allot(double *,v,3*n);
	allot(double *,weight,n);
	allot(double *,workn,n);
	for(i=0,ii=0;i<n;++i,ii+=3)
	{
		/* This could be done with the blas, but it would
		be more obscure and no faster */
		v[ii] = pmv[i].major[0];
		v[ii+1] = pmv[i].major[1];
		v[ii+2] = pmv[i].major[2];
	}
	/* We use relative scaling here because the pm vectors are 
	not normalized.  We could use absolute scaling if we normalized
	them above.  This is a modification that might actually give
	better results.  */
	M_estimator_double_n_vector(v,3,n,
		IQ_SCALE_RELATIVE,PM_MINSCALE_MAJOR,avg,weight);
	nrm_major = dnrm2(3,avg,1);
	for(i=0;i<3;++i) 
	{
	    /* Needed to avoid random NaN */
	    if(nrm_major<FLT_EPSILON)
	    	pmavg->major[i] = avg[i];
	    else
		pmavg->major[i] = avg[i]/nrm_major;
	}

	/* Error estimates are computed completely differently here from
	that described in Bear and Pavlis (1999).  Rather than use a 
	jackknife on individual angles, here I've chosen to use a simple
	standard deviation measure using weighted residuals.  The residuals,
	however, are computed from total angular separation computed using
	a dot product.  This allows us to avoid wraparound errors that 
	are inevitable with angles.  

	First step is to compute a vector of angle residuals.  */
	for(i=0,ii=0;i<n;++i,ii+=3)
	{
		dotprod = ddot(3,v+ii,1,pmavg->major,1);
		dotprod /= dnrm2(3,v+ii,1);
		workn[i] = acos(dotprod);
	}
	/* weighted mean formula for error */
	for(i=0,sumwt=0.0,sumsq=0.0;i<n;++i)
	{
		sumsq += workn[i]*workn[i]*weight[i]*weight[i];
		sumwt += weight[i];
	}
	ndgf = nint(sumwt) - 3;
	if(ndgf<1)
	{
		elog_notify(0,"pmvector_average:  sum of weights = %lf in major axis average implies degrees of freedom less than 1\nUsing 1 degree of freedom\n",sumwt);
		ndgf = 1;
	}
	pmerr->ndgf_major = ndgf;
	pmerr->dtheta_major =  sqrt(sumsq/((double)ndgf));
	/* We scale the azimuthal error by 1/sin(theta) to get a stable
	error estimate that correctly goes to infinitity when theta -> 0*/
	scoor = unit_vector_to_spherical(pmavg->major);
	pmerr->dphi_major = (pmerr->dtheta_major)/sin(scoor.theta);

	/* We first project the minor axis vectors onto the plane
	perpendicular to the average major axis.  This reduces the
	degrees of freedom in a way that I consider reasonable and
	is in line with with Lorie Bear did */
	for(i=0,ii=0;i<n;++i,ii+=3)
	{
		double minor_scale;
		/* Intentionally ignore error return of null project because
		the only error condition in current code cannot happen 
		with this call.  null_project writes result in the
		last argument, so this step is functionally like the 
		v[ii]=pmv[i].major, etc. loop above, but combines
		the projection operation . */
		null_project(pmavg->major,3,1,pmv[i].minor,v+ii);
		/* We also want to scale the vector by a factor
		that is determinable from rectilinearity to keep
		the axis length consistent to allow a refined
		rectilinearity average below */
		minor_scale = 1.0 - pmv[i].rectilinearity;
		dscal(3,minor_scale,v+ii,1);
	}
	/* This constructs a rotational tranformation to a coordinate
	system where x1 and x2 are in the desired projection plane.
	Actually, the null projection above is redundant, but for now
	the extra work is largely irrelevant and is a good cross check
	for debugging. */
	ray_coordinate_trans(scoor,U);
	for(i=0;i<n;++i)
	{
		for(j=0;j<3;++j) 
		{
			work[j] = ddot(3,v+j+3*i,1,U+j,3);
		}
		dcopy(3,work,1,v+3*i,1);
	}
	/* Note the change from above to a 2-d space now.  The above 
	transformations zero the x3 direction after the transformation */
	M_estimator_double_n_vector(v,2,n,
		IQ_SCALE_RELATIVE,PM_MINSCALE_MINOR,avg,weight);
	avg[2] = 0.0;
	nrm_minor = hypot(avg[0],avg[1]);
	/* This is the inverse tranformation -- u is orthogonal */
	for(j=0;j<3;++j)
		work[j] = ddot(3,U+j*3,1,avg,1);

	/* This is similar to above, but, perhaps incorrectly, the
	degrees of freedom are larger by one because we reduce the
	space to 2d */
	for(i=0,ii=0;i<n;++i,ii+=3)
	{
		dotprod = ddot(2,v+ii,1,avg,1);
		nrmtest = dnrm2(2,v+ii,1);
		if(nrmtest<=0.0)
		{
			elog_notify(0,"pmvector_average:  minor axis estimate %d of %d estimates has 0 projection perpendicular to major\nArtificially set to average\n",
				i,n);
			workn[0] = 0.0;
		}
		else
		{
			dotprod/= nrmtest;
		/* because avg wasn't normalized we have divide by norm */
			dotprod /= nrm_minor;
			workn[i] = acos(dotprod);
		}
	}
	/* We want the final result normalized to a unit vector length */
	for(i=0;i<3;++i) pmavg->minor[i] = work[i]/nrm_minor;

	/* weighted mean formula again */
	for(i=0,sumwt=0.0,sumsq=0.0;i<n;++i)
	{
		sumsq += workn[i]*workn[i]*weight[i]*weight[i];
		sumwt += weight[i];
	}
	ndgf = nint(sumwt) - 2;
	if(ndgf<1)
	{
		elog_notify(0,"pmvector_average:  sum of weights = %lf in minor axis average implies degrees of freedom less than 1\nUsing 1 degree of freedom\n",sumwt);
		ndgf = 1;
	}
	pmerr->ndgf_minor = ndgf;
	pmerr->dtheta_minor =  sqrt(sumsq/((double)ndgf));
	/* We cast the minor axis in spherical coordinates like
	the major axis.  This differ's from Lorie's skew measures, but
	it is simpler to deal with in a database output as it treats
	the two vector in a common way */
	scoor = unit_vector_to_spherical(pmavg->minor);
	pmerr->dphi_minor = (pmerr->dtheta_major)/sin(scoor.theta);

	/* Finally, we deal with rectilinearity.
	We use the contents of v which are the projected
	minor axis values rather than the raw minor
	axes.  This estimator will tend to give slightly
	better rectilinearity using the raw vectors
	because a projection is always <= original */
	for(i=0;i<n;++i)
	{
		double minor_nrm;
		minor_nrm = dnrm2(3,v+i*3,1);
		/* Not needed because the major axis vector
		was previously normalized to unit length 
		major_nrm = dnrm2(3,pmv[i].major,1);
		*/

		workn[i] = 1.0 - minor_nrm;
	}
	stats = MW_calc_statistics_double(workn,n);
	pmavg->rectilinearity = stats.median;
	pmerr->ndgf_rect = n - 1;
	/* Assume a simple normal distribution to convert interquartiles
	to standard deviation */
	pmerr->delta_rect = NORMAL_IQSCALE*((stats.q3_4)-(stats.q1_4));

	free(weight);
	free(workn);
	free(v);
}
コード例 #17
0
ファイル: decimate.c プロジェクト: nimanshr/antelope_contrib
int decimate_trace(Tbl *dectbl,float *in, int nin, double dt0, double t0,
                   float **out, int *nout, double *dt, double *t0out)

{

    int i,nstages;
    float *buf, *buf2;
    FIR_decimation *d;
    int decfac;  /* current decimation factor */
    double deltat0=0.0;  /* accumulation of time offsets for edge
			condition of FIR filter (i.e. we don't
			do partial convolutions on edges) */
    double dt_this_stage;
    double si;  /* current sample interval (staged to larger values) */
    int n;  /* current number of samples */
    int ret_code;

    nstages = maxtbl(dectbl);
    buf = (float *) calloc (nin,sizeof(float));
    buf2 = (float *) calloc (nin,sizeof(float));

    if( (buf == NULL) || (buf2 == NULL) )
    {
        elog_notify(0,"decimate_trace:  cannot malloc buffers of length %d\n",
                    nin);
        return(-999);
    }
    /* Note this routine works if nstages = 0 (empty tbl) */
    scopy(nin,in,1,buf,1);
    decfac = 1;
    si=dt0;
    n=nin;
    for (i=0; i<nstages; i++)
    {
        d = (FIR_decimation *) gettbl(dectbl,i);

        /* this computation of the time offset to the first
        decimated output sample assumes the FIR filter is
        zero phase and symmetric.  The -1 may surprise
        you, but is correct and was verified by tests.
        It is the interval versus points problem. */

        decfac *= d->decfac;
        dt_this_stage = si*((double)((d->ncoefs)-1))/2.0;
        deltat0 += dt_this_stage;
        si *= (double)(d->decfac);

        if((d->decfac == 1) && (d->ncoefs == 0) )
        {
            /* Fall in this block for no decimation with
            zero length filter (the "none" case ) */
            scopy(n,buf,1,buf2,1);
            *nout = n;
        }
        else
        {
            if((d->ncoefs)>n)
            {
                free(buf);
                free(buf2);
                out = NULL;
                *nout = 0;
                return(-1);
            }
            ret_code = sconv(buf,n,d->coefs,d->ncoefs,0,d->decfac,
                             buf2,nout);

            /* This fragment should never really be executed, but better
            safe than sorry.  We don't issue a warning because the
            correction should be appropriate. */
            if(ret_code > 0)
            {
                double time_correction;
                time_correction = si*((double)ret_code);
                deltat0 += time_correction;
            }
        }
        /* this always works because nout <= nin */
        scopy(*nout,buf2,1,buf,1);
        n = *nout;
    }

    /* finally the output vector is created here */
    *out = (float *)calloc(*nout,sizeof(float));
    if(*out == NULL)
        elog_die(0,"decimate_trace:  cannot malloc output vector of length %d\n",
                 *nout);
    scopy(*nout,buf2,1,*out,1);
    *t0out = t0 + deltat0;
    *dt = si;
    free(buf);
    free(buf2);
    return(decfac);
}
コード例 #18
0
Travel_Time_Function_Output ttlvz_time_exec(Ray_Endpoints x, 
		char *phase, int mode)
{
	double delta, d_km;  /* epicentral distance in radians and km resp.*/
	double azimuth;  /* source to receiver azimuth angle (radians) */
	double z0;  /* hold first layer depth (see below)  */
	Travel_Time_Function_Output o;
	Vmodel *mod;

	double *v, *z;
	int nz;
	double *work1,*work2;
	double p;
	int up;  /* direct ray flag from ttlvz */

	/* First we compute the epicentral distance and azimuth */
	dist(rad(x.slat), rad(x.slon), rad(x.rlat), rad(x.rlon), 
		&delta, &azimuth);
	d_km = delta*RADIUS_EARTH;

	/* We fetch the correct model structure for this phase */
	mod = (Vmodel *)getarr(ttlvz_models,phase);
	if (mod == NULL)
	{
		elog_complain(1,"ttlvz_time_exec: Don't know how to compute travel times for phase %s\n",phase);
		o.time = TIME_INVALID;
		return(o);
	}
 
	/* We cheat and distort the model to handle elevation corrections.
	We do this by storing the original velocity and depth of the 
	first layer in (v0,z0), and then set the first point to the 
	receiver depth.  I also do something devious here that could
	be confusing.  I set the pointers v and z to the P or S 
	model vectors depending on which phase I want to compute.  This
	avoids repetitious code, but adds a slight overhead at the end
	where we need to reset the first layer values again.*/
	z0 = mod->ztop[0];
	if(x.rz < mod->ztop[1])
		mod->ztop[0] = x.rz;
	else
	{
		elog_notify(0,"Warning (ttlvz_time_exec):  elevation correction error\nStation elevation %f lies below first layer depth %f\nElevation ignored\n",
			x.rz, mod->ztop[1]);
	}
	/* This could be avoided, but it is a relic of the earlier code */
	v = mod->velocity;
	z = mod->ztop;
	nz = mod->nlayers;

	work1 = (double *) calloc(2*nz,sizeof(double));
	work2 = (double *) calloc(2*nz,sizeof(double));
	if( (work1 == NULL) || (work2 == NULL) )
		die(1,"ttlvz_time_exec:  Cannot alloc work arrays for phase %s\n",
			phase);


	ttlvz_(&d_km, &x.sz, &nz, v, z, work1, work2, &o.time, &p, &up); 
        if (o.time < 0.0)
        {
                elog_complain(1,"ttlvz_time_exec: ttlvz could not compute direct wave travel time for phase %s\n",phase);
                o.time = TIME_INVALID;
                return(o);
        }

	if(mode == ALL)
	{
	/* For this routine I calculate time derivatives from the
	ray parameter that is returned by ttlvz.*/
		int i,iz;
		double vsource;

		if(d_km <= 0.0)
		{
			o.dtdx = 0.0;
			o.dtdy = 0.0;
			p = 0.0;
		}
		else
		{
			o.dtdx = - fabs(p)*sin(azimuth);
			o.dtdy = - fabs(p)*cos(azimuth);
		}
		/* Find the velocity in the layer in which the
		source lies.  We need to for the dtdz calculation */
		for(i=1,iz=nz-1;i<nz;++i)
		{
			if(x.sz <= z[i])
			{
				iz = i-1;
				break;
			}
		}
		vsource = v[iz];
		o.dtdz = cos(asin(fabs(p)*vsource))/vsource;
		/* The strange logic for p<0.0 corrects the 
		sign of dtdz for the special case when the source
		is above the first layer top.  In this case, ttlvz
		returns a negative p, and the proper sign of dtdz 
		is negative. */
		if( (!up) || (p < 0.0) )
			o.dtdz = -o.dtdz;
				
	}
	mod->ztop[0] = z0;
	free(work1);
	free(work2);
	return(o);
}
コード例 #19
0
ファイル: MWstack.c プロジェクト: Nikolaus/antelope_contrib
/* This function extracts a time subset of a MWstack object defined
by the Time_Window function passed to it.  It copies the subset of
the stack requested and returns a new MWstack object with the 
ancillary parameters that define it correctly set.  REturns a
NULL pointer if the time window requested does not overlap the
input stack data at all.  If the input data span a smaller range
than the requested window a diagnostic is issue and the object
will be trimmed to match what is possible.  

Arguments:
	instack - input MWstack object
	win - Time_Window defining region to be extractged 
		(only the start and end parameters are used)

Author:  Gary Pavlis
Written:  December 2001
*/
MWstack *MWextract_stack_window(MWstack *instack,Time_Window *win)
{
	int i,j,k,kk,its,ite;
	int tstart, tend;  /* start and end values(in samples) actually used */
	int nused;
	int lag;
	char *message="MWextract_stack_window:  requested window is inconsistent with the stack window";

	MWstack *outstack;
	int nwavelets,nchan;

	nwavelets = instack->nwavelets;
	nchan = instack->nchan;

	its = nint((instack->tstart)/(instack->dt));
	ite = nint((instack->tend)/(instack->dt));
	if(((win->tstart)>=ite) || ((win->tend)<=its) )
	{
		elog_complain(0,"%s\nStack window is %d to %d samples;  Requested %d to %d\n",
			message,its, ite, win->tstart, win->tend);
		return(NULL);
	}
	else if( ((win->tstart)<its) && ((win->tend)<=ite))
	{
		tstart = its;
		tend = win->tend;
		elog_complain(0,"%s\nStack window is %d to %d samples;  Requested %d to %d\nReset to %d to %d\n",
			message,its, ite, win->tstart, win->tend,tstart,tend);
		
	}
	else if( ((win->tstart)>=its) && ((win->tend)>ite))
	{
		tstart = win->tstart;
		tend = ite;
		elog_complain(0,"%s\nStack window is %d to %d samples;  Requested %d to %d\nReset to %d to %d\n",
			message,its, ite, win->tstart, win->tend,tstart,tend);
		
	}
	else
	{
		tstart = win->tstart;
		tend = win->tend;
	}
	lag = tstart - its;
	nused = tend - tstart + 1;
	outstack = create_MWstack(nwavelets,nchan,nused);
	outstack->dt = instack->dt;
	outstack->tstart = instack->tstart + ((double)lag)*instack->dt;
	outstack->tend = outstack->tstart + ((double)(nused-1))*instack->dt;
	outstack->dt = instack->dt;
	for(i=0;i<nwavelets;++i)
		for(j=0;j<nchan;++j)
		{
			outstack->amp[i][j].r = instack->amp[i][j].r;
			outstack->amp[i][j].i = instack->amp[i][j].i;
		}
	for(j=0;j<nchan;++j) outstack->weights[j]=instack->weights[j];
	if(instack->timeweight_applied)
	{
		elog_notify(0,"MWextract_subset_window:  existing stack has a time weight function already applied\nResults may be biased\n");
		for(k=0,kk=lag;k<nused;++k,++kk) 
			outstack->timeweight[k]=instack->timeweight[kk];
	}
	else
		for(k=0;k<nused;++k) outstack->timeweight[k]=1.0;
	outstack->stack_is_valid = 1;
	for(i=0;i<nwavelets;++i)
		ccopy(nused,instack->z[i]+lag,1,outstack->z[i],1);
	return(outstack);
}
コード例 #20
0
Slowness_Function_Output ttlvz_slow_exec (Ray_Endpoints x, 
		char *phase, int mode)
{
	double delta, d_km;  /* epicentral distance in radians and km resp.*/
	double s2raz;  /* source to receiver azimuth angle (radians) */
	double uaz;  /* gcp expected azimuth of propagation of arrival 
				(uaz != s2raz on a spherical earth) */
	double z0;  /* hold first layer depth (see below)  */
	Slowness_Function_Output o;

	Vmodel *mod;

	double *v, *z;
	double *work1,*work2;
	int nz;
	double time, p;
	int up;  /* direct ray flag from ttlvz */
	double ztmp;

	/* First we compute the epicentral distance and azimuth */
	dist(rad(x.slat), rad(x.slon), rad(x.rlat), rad(x.rlon), 
		&delta, &s2raz);
	d_km = delta*RADIUS_EARTH;
	/* Now compute the great circle path propagation azimuth */
	dist(rad(x.rlat),rad(x.rlon),rad(x.slat),rad(x.slon),&delta,&uaz);
	uaz += M_PI;
	if(uaz >= 2.0*M_PI) uaz -= (2.0*M_PI);

	/* We fetch the correct model structure for this phase */
	mod = (Vmodel *)getarr(ttlvz_models,phase);
	if (mod == NULL)
	{
		elog_complain(1,"ttlvz_slow_exec: Don't know how to compute slowness vectors for phase %s\n",phase);
		o.ux = SLOWNESS_INVALID;
		o.uy = SLOWNESS_INVALID;
		return(o);
	}
 
	/* We cheat and distort the model to handle elevation corrections.
	We do this by storing the original velocity and depth of the 
	first layer in (v0,z0), and then set the first point to the 
	receiver depth.  I also do something devious here that could
	be confusing.  I set the pointers v and z to the P or S 
	model vectors depending on which phase I want to compute.  This
	avoids repetitious code, but adds a slight overhead at the end
	where we need to reset the first layer values again.*/
	z0 = mod->ztop[0];
	if(x.rz < mod->ztop[1])
		mod->ztop[0] = x.rz;
	else
	{
		elog_notify(0,"Warning (ttlvz_slowness_exec):  elevation correction error\nStation elevation %f lies below first layer depth %f\nElevation ignored\n",
			x.rz, mod->ztop[1]);
	}
	/* This could be avoided, but it is a relic of the earlier code */
	v = mod->velocity;
	z = mod->ztop;
	nz = mod->nlayers;

	work1 = (double *) calloc(2*nz,sizeof(double));
	work2 = (double *) calloc(2*nz,sizeof(double));
	if( (work1 == NULL) || (work2 == NULL) )
		die(1,"ttlvz_slow_exec:  Cannot alloc work arrays for phase %s\n",
			phase);

	ttlvz_(&d_km, &x.sz, &nz, v, z, work1, work2, &time, &p, &up);
        if (time < 0.0)
        {
                elog_complain(1,"ttlvz_time_exec: ttlvz could not compute direct wave slowness vector for phase %s\n",phase);
                o.ux = SLOWNESS_INVALID;
                o.uy = SLOWNESS_INVALID;
                return(o);
        }

	/* This would be executed only for close, shallow sources.  
	It could probably be deleted, but we'll do it for completeness*/
	if(p<0.0) p = -p;

	o.ux = p*sin(uaz);
	o.uy = p*cos(uaz);

 	if(mode == ALL)
	{
		double dx, dudr, dudz;
		double sin_a, sin_a0, cos_a, cos_a0;
		double p0,p1,p3,p4;
		double dis;

		sin_a0 = sin(s2raz);
		cos_a0 = cos(s2raz);
		sin_a = sin(uaz);
		cos_a = cos(uaz);
		if(up)
		{
			/* we calculate dudr by a 5 point central 
			difference formula.  I don't mess with
			truncation error calculations here, but I 
			do have to assure distance >=0 and < direct
			to refracted crossover.  Both points are
			singular.  When we get to close to the edges
			we revert to simple forward or backward difference 
			formula.*/

			dx = DX_STEP_SIZE;
			if( d_km < 2.0*MINIMUM_DX)
			{
				dis = d_km+dx;
				ttlvz_(&dis,&x.sz, &nz, v, z, 
					work1, work2, &time, &p1, &up);
        			if (time < 0.0)
        			{
                		  elog_complain(1,"ttlvz_time_exec: ttlvz could not compute direct wave slowness vector for phase %s while computing derivatives\n",phase);
                		  o.ux = SLOWNESS_INVALID;
                		  o.uy = SLOWNESS_INVALID;
                		  return(o);
        			}
				dudr = (p1-p)/dx;
			}
			else if(d_km-2.0*dx < 0.0)
			{
				while(d_km-2.0*dx < 0.0)
					dx *= DX_SCALING_FACTOR;
			}
			/* Now check that the value at x+2*dx is
			still an upward branch of the travel time curve.
			If it isn't, reset the step size until it is.
			When this isn't possible, revert to a backward
			difference at the minumum step size. */
			dis = d_km+2.0*dx;
			ttlvz_(&dis,&x.sz, &nz, v, z, 
					work1, work2, &time, &p4, &up);
        		if (time < 0.0)
        		{
                	  elog_complain(1,"ttlvz_time_exec: ttlvz could not compute direct wave slowness vector for phase %s while computing derivatives\n",phase);
                	  o.ux = SLOWNESS_INVALID;
                	  o.uy = SLOWNESS_INVALID;
                	  return(o);
        		}
			while(!up && (dx>=MINIMUM_DX) )
			{
				dx *= DX_SCALING_FACTOR;
				dis = d_km+2.0*dx;
				ttlvz_(&dis,&x.sz, &nz, v, z, 
					work1, work2, &time, &p4, &up);
        			if (time < 0.0)
        			{
                		  elog_complain(1,"ttlvz_time_exec: ttlvz could not compute direct wave slowness vector for phase %s while computing derivatives\n",phase);
                	   	  o.ux = SLOWNESS_INVALID;
                	  	  o.uy = SLOWNESS_INVALID;
                		  return(o);
        			}
			}
			if(dx<MINIMUM_DX)
			{
				/* In this situation, we revert to 
				a two point backward difference */
				dx = MINIMUM_DX;
				/* special for shallow sources close */
				if(d_km-dx < 0.0) dx = d_km;
				dis = d_km +dx;
				ttlvz_(&dis,&x.sz, &nz, v, z, 
					work1, work2, &time, &p0, &up);
				dudr = (p-p0)/dx;
        			if (time < 0.0)
        			{
                		  elog_complain(1,"ttlvz_time_exec: ttlvz could not compute direct wave slowness vector for phase %s while computing derivatives\n",phase);
                	   	  o.ux = SLOWNESS_INVALID;
                	  	  o.uy = SLOWNESS_INVALID;
                		  return(o);
        			}
			}
			else
			{
				/* if we land here we can safely use the
				full 5 point formula.  Five point is 
				a misnomer since the central point 
				cancels out, but so what*/
				dis = d_km-2.0*dx;
				ttlvz_(&dis,&x.sz, &nz, v, z, 
					work1, work2, &time, &p0, &up);
        			if (time < 0.0)
        			{
                		  elog_complain(1,"ttlvz_time_exec: ttlvz could not compute direct wave slowness vector for phase %s while computing derivatives\n",phase);
                	   	  o.ux = SLOWNESS_INVALID;
                	  	  o.uy = SLOWNESS_INVALID;
                		  return(o);
        			}
				dis = d_km-dx;
				ttlvz_(&dis,&x.sz, &nz, v, z, 
					work1, work2, &time, &p1, &up);
        			if (time < 0.0)
        			{
                		  elog_complain(1,"ttlvz_time_exec: ttlvz could not compute direct wave slowness vector for phase %s while computing derivatives\n",phase);
                	   	  o.ux = SLOWNESS_INVALID;
                	  	  o.uy = SLOWNESS_INVALID;
                		  return(o);
        			}
				dis = d_km+dx;
				ttlvz_(&dis,&x.sz, &nz, v, z, 
					work1, work2, &time, &p3, &up);
        			if (time < 0.0)
        			{
                		  elog_complain(1,"ttlvz_time_exec: ttlvz could not compute direct wave slowness vector for phase %s while computing derivatives\n",phase);
                	   	  o.ux = SLOWNESS_INVALID;
                	  	  o.uy = SLOWNESS_INVALID;
                		  return(o);
        			}
				dis = d_km+2.0*dx;
				ttlvz_(&dis,&x.sz, &nz, v, z, 
					work1, work2, &time, &p4, &up);
        			if (time < 0.0)
        			{
                		  elog_complain(1,"ttlvz_time_exec: ttlvz could not compute direct wave slowness vector for phase %s while computing derivatives\n",phase);
                	   	  o.ux = SLOWNESS_INVALID;
                	  	  o.uy = SLOWNESS_INVALID;
                		  return(o);
        			}
				dudr = (p0-8.0*p1+8.0*p3-p4)/(12.0*dx);
			}
			/* bug fix Feb 1998.  Else conditional is necessary
			to avoid an indeterminate form that arises when 
			offset is 0.0 */
			if(d_km > D_KM_CUTOFF) 
			{
			  o.duxdx = -sin_a*sin_a0*dudr - p*cos_a*cos_a0/d_km;
			  o.duxdy = -sin_a*cos_a0*dudr + p*cos_a*sin_a0/d_km;
			  o.duydx = -cos_a*sin_a0*dudr + p*sin_a*cos_a0/d_km;
			  o.duydy = -cos_a*cos_a0*dudr - p*sin_a*sin_a0/d_km;
			}
			else
			{
			  o.duxdx = -dudr;
			  o.duxdy = 0.0;
			  o.duydx = 0.0;
			  o.duydy = -dudr;
			}

			/* We do the z derivatives more crudely because
			they are of significant size only when a source is
			close and below the array.  In that situation,
			accuracy should not be a serious problem with 
			fairly crude scaling like this.  We do a simple
			backward difference to avoid crossing over into
			refracted branches. However, when source is shallow
			we always use a forward difference to avoid 
			negative depths problems.  */
			if(x.sz <= DZ_STEP_SIZE)
			{
				ztmp = x.sz+DZ_STEP_SIZE;
				ttlvz_(&d_km,&ztmp, &nz, v, z, 
					work1, work2, &time, &p0, &up);
        			if (time < 0.0)
        			{
                		  elog_complain(1,"ttlvz_time_exec: ttlvz could not compute direct wave slowness vector for phase %s while computing derivatives\n",phase);
                	   	  o.ux = SLOWNESS_INVALID;
                	  	  o.uy = SLOWNESS_INVALID;
                		  return(o);
        			}
				dudz = (p0 - p)/DZ_STEP_SIZE;
			}
			else
			{
				ztmp = x.sz-DZ_STEP_SIZE;
				ttlvz_(&d_km,&ztmp, &nz, v, z, 
					work1, work2, &time, &p0, &up);
        			if (time < 0.0)
        			{
                		  elog_complain(1,"ttlvz_time_exec: ttlvz could not compute direct wave slowness vector for phase %s while computing derivatives\n",phase);
                	   	  o.ux = SLOWNESS_INVALID;
                	  	  o.uy = SLOWNESS_INVALID;
                		  return(o);
        			}
				dudz = (p - p0)/DZ_STEP_SIZE;
			}
			o.duxdz = dudz*sin_a;
			o.duydz = dudz*cos_a;		
		}
		else
		{
			o.duxdx = -p*cos_a*cos_a0/d_km;
			o.duxdy = p*cos_a*sin_a0/d_km;
			o.duydx = p*sin_a*cos_a0/d_km;
			o.duydy = -p*sin_a*sin_a0/d_km;
			/* With constant velocity layer models, refracted
			rays have exactly zero slowness derviatives wrt z*/

			o.duxdz = 0.0;
			o.duydz = 0.0;  
		}
	}
	mod->ztop[0] = z0;
	free(work1);
	free(work2);
	return(o);
}
コード例 #21
0
int main (int argc, char **argv)
{
	Dbptr master_db, dbtmp;
	char dbname[512];  /* dbtmp name assigned by maketmpdb */
	char *orbname;
	char *pffile=NULL;

	Pf *pf;  /* Input pf object handle */
	Arr *arr_sta;
	Arr *arr_a;  /*Array object associative array -- purely a place holder*/
	Arr *arr_phase;
	int i;
	char *statefile=NULL;
	Point origin;

	int orbin,orbout;  /* We establish both a read and write connection
				on seperate sockets so we can use orbreap on
				the input */
	int quit=0,last_pktid;
	double last_pkttime;
	int exhume_rcode;  /* value returned by exhume*/
	char *packet=0;
	int orid_used;
	Location_options o;
	RTlocate_Options rt_opts;
	ORB_Hypocenter hyp;

	
	/* This initialization is necessary for the orb_arrivals_in routine
	to work correctly on the first pass*/
	hyp.assocs = NULL;

	elog_init(argc, argv);
	elog_notify (0, "$Revision$ $Date$") ;
	if(argc < 2) usage(argv[0]);
	orbname = argv[1];

	for(i=2;i<argc;++i)
	{
		if(!strcmp(argv[i],"-pf"))
		{
			++i;
			pffile = argv[i];
		}
		else if(!strcmp(argv[i],"-S"))
		{
			++i;
			statefile = argv[i];
		}
		else
		{
/* For this kind of program it seems wise to make it a fatal error to 
have the arguments botched */
			elog_complain(0,"Unrecognized argument %s\n",argv[i]);
			usage(argv[0]);
		}
	}
        /* set default this way*/
        if(pffile == NULL) pffile = strdup(DEFAULT_PFFILE);
	if(statefile == NULL) statefile = strdup(DEFAULT_STATEFILE);

	/* parse parameter file and form all the genloc control and
	internal static data structures */
	i = pfread(pffile,&pf);
	if(i != 0) elog_die(1,"Pfread error\n");
	o = parse_options_pf (pf);
	arr_sta = load_station_table(pf);
	arr_a = load_array_table(pf);
 	arr_phase = parse_phase_parameter_file(pf);
	/* Note this is a slightly different use of these variables
	than that used by other genloc routines.  Here we use it
	like a coordinate system origin to select range of distances
	to use. We actually reset these again in the location function,
	but check them here to make sure these variables are in the
	parameter space.  pfget_double will cause the program to die
	if these aren't defined.*/
	origin.lat = pfget_double(pf,"center_latitude");
	origin.lon = pfget_double(pf,"center_longitude");
	origin.z = 0.0;

	rt_opts = parse_rt_options(pf);

	if(dbopen(rt_opts.work_db,"r+",&master_db ) == dbINVALID)
                elog_die(1,"Unable to open master database %s\n",
			rt_opts.work_db);


	/* Now we open the orb server connections */
	if( (orbin=orbopen(orbname,"r&")) < 0)
		elog_die(0,"Cannot open ring buffer %s for reading\n",orbname);
	
	if(orbselect(orbin,"/db/event|/db/origin|/db/assoc|/db/arrival") < 0)
		elog_die(0,"Cannot select any db records from ring buffer %s\n",
			orbname);

	/* These are the state saving routines.  quit is set nonzero 
	whenever the program catches a signal.  We call bury below when
	this happens.  exhume_state is a function because I expect
	it could be used again  */

	exhume_rcode = exhume ( statefile, 0, 0, 0 );
	exhume_state(exhume_rcode);  
        if ( orbresurrect ( orbin, &last_pktid, &last_pkttime ) == 0 )
		elog_complain( 0, "resurrection successful: repositioned to pktid #%d\n", last_pktid ) ;
        else
	{
		orbseek (orbin, ORBOLDEST);
		last_pktid = orbtell(orbin);
		elog_complain( 0, "resurrection unsuccessful\nStarting at beginning of current orb at packet id %d\n",last_pktid ) ;
	}
	/* The following is basically a trick to create a db pointer that
	never references any tables.  This is the preferred approach for
	orbpkt2db records which utilize the scratch record of this database
	pointer.  The fact that we destroy the file this creates turns
	out to be a feature of datascope we can exploit here.  */
	if (maketmpdb ("css3.0", &dbtmp, dbname) < 0) {
		elog_complain(0, "maketmpdb() error.\n");
		exit (1);
	}
	/* This little routine initilizes the null record for each table 
	used here.  This was necessary because we assemble records in the
	scratch record.  This sets proper nulls in fields that are not
	referenced by this program. */
	if(initialize_scratch_records(dbtmp) == dbINVALID)
		elog_complain(0,"Warning:  errors initializing null records in tables.  May generate invalid data in some fields\n");
/*
	unlink (dbname);
*/
	

	if( (orbout=orbopen(orbname,"w&")) < 0)
		elog_die(0,"Cannot open ring buffer %s for writing\n",orbname);

	/* This loop is broken only by an error.  We call bury after each 
	event is processed saving the current packet id.  This should 
	effectively skip events that cause orbgenloc to die for some
	reason. */
	while(1) 
	{
		int return_code;

		return_code = orb_arrivals_in(orbin, dbtmp, &hyp, 
			&last_pktid,rt_opts);
		if(return_code)
		{
		    if(return_code < 0)
			elog_complain(0,"Error reading db records from orb\nCurrent event skipped\n");
		    else
			elog_complain(0,"Sequencing error reading db packets from orbassoc.\nOne or more events were probably skipped\n");
		    continue;
		}
		if(bury())
			elog_complain(0,
			  "bury failed writing statefile %s\n",statefile);

		compute_location(o,rt_opts,arr_sta,arr_a,arr_phase,
				pf,master_db, dbtmp, hyp, orbout);

		/* when last_pktid is -1 orb_arrivals_in does not do 
		an orbseek, so we always reset it here */
		last_pktid = -1;
		/* This is the only appropriate place to release
		this space.  This block is malloced in orb_arrivals_in*/
		free(hyp.assocs);
		hyp.assocs = NULL;
	}
}
コード例 #22
0
/*This is an important function that sets the set of base station corrections
used as the bias term in pmel.  These base station corrections are computed
as the difference between travel times computed by a 3D calculator 
(This program actually has no concept of this directly.  It just uses
the 3D model as a reference.) and a reference model (presumably generally
a 1D model like iasp91, but it could itself be 3D really).  Note
that if the 3D model has any station corrections set they will be applied.
For the reference model (1D) the station corrections are set by this 
function.  This allows testing or application with a global set of station
corrections used as the 3D equivalent, but allowing the results to be
space variable when used with dbpmel.  i.e. you can, if desired, use
the same travel time calculator for the 1D and 3D case, but if 
station corrections are defined for the 3D handle they will be used 
as a global bias term.  Similarly, if this same process is done with
no station corrections one can produce a "unbiased estimate" meaning
the bias term is always forced to 0 everywhere.  Experience has shown
that although this might be conceptually appealing it generally is a
bad idea unless the reference model is very good to start with.

Arguments:
	pha - associative array of phase handles for 1D reference model
		calculator (station correction of these handles are set here).
	pha3D - same as pha, but for the 3D (bias) model calculator
	sa - associative array of Station objects with station location
		information (keyed by sta name).
	hc - hypocentroid location.

Returns:
	0 - normal, aok
	> 0 - count of failures in computing travel times 
	< 0 - total failure
*/
int initialize_station_corrections(Arr *pha,Arr *pha3D, Arr *sa,Hypocenter *hc)
{
	int i,j;
	Phase_handle *p,*p3D;
	Tbl *keys;
	char *phase;
	Station *s;
	Tbl *stakeys;
	char *sta;
	int nsc_fail=0;
	Ray_Endpoints x;
	Travel_Time_Function_Output t,t3D;
	double *sc,*sc3D;

	keys = keysarr(pha);
	stakeys = keysarr(sa);
	x.slat = hc->lat;
	x.slon = hc->lon;
	x.sz = hc->z;

	for(i=0;i<maxtbl(keys);++i)
	{
		phase = gettbl(keys,i);
		p = (Phase_handle *)getarr(pha,phase);
		p3D = (Phase_handle *)getarr(pha3D,phase);
		if(pha3D == NULL)
		{
			elog_notify(0,"No handle for 3d (bias correction) for phase %s\nBias contribution set to 0 for this phase\n",
				phase);
			nsc_fail += cntarr(sa);
			/* Emptying the arr is a simple way to create
			the equivalent of all 0s*/
			if(cntarr(p->time_station_corrections)>0)
			{
				freearr(p->time_station_corrections,free);
				p->time_station_corrections=newarr(0);
			}
			continue;
		}
		for(j=0;j<maxtbl(stakeys);++j)
		{
			sta = gettbl(stakeys,j);
			s = (Station *)getarr(sa,sta);
			x.sta = s->name;
			x.rlat = s->lat;
			x.rlon = s->lon;
			x.rz = -(s->elev);
			/* Get a pointer to hold the new station correction.
			If it doesn't exist yet, create it and enter it into
			the associative array.  Note because these are direct
			pointers we don't have set the entry in the arr below*/
			sc = (double *)getarr(p->time_station_corrections,sta);
			if(sc == NULL)
			{
				allot(double *,sc,1);
				setarr(p->time_station_corrections,sta,sc);
			}
			t3D = p3D->ttcalc(x,phase,RESIDUALS_ONLY);
			t = p->ttcalc(x,phase,RESIDUALS_ONLY);
			if( (t.time == TIME_INVALID) 
				|| (t3D.time == TIME_INVALID) )
			{
				elog_notify(0,"Travel time failure for phase %s computing reference corrections for station %s\nCorrection set to 0.0\n",
					phase,sta);	
				*sc = 0.0;
				++nsc_fail;
			}
			else
			{
				*sc = t3D.time - t.time;
				sc3D = (double *)
				    getarr(p3D->time_station_corrections,sta);
				if(sc3D != NULL)
					*sc += *sc3D;
			}
		}
	}
コード例 #23
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 ;
}
コード例 #24
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();
			}
		}
	}
}
コード例 #25
0
ファイル: orb2rrdc.c プロジェクト: battistuz/antelope_contrib
static void
archive_dlsvar( Dbptr db, char *net, char *sta, char *dls_var, char *dsparams, Tbl *rras, double time, double val )
{
	char	key[STRSZ];
	char	*rrd;
	double	start_time;
	Dbptr	dbt;
	char	datasource[STRSZ];
	char	command[STRSZ];
	char	cacheopt[FILENAME_MAX];
/* Disable response printing for now (see below)
	char	response[STRSZ];
	char	*resp_ptr;
 */
	int	i;

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

	rrd = getarr( Rrd_files, key );

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

		start_time = time - Status_stepsize_sec;

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

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

		trwfname( dbt, Rrdfile_pattern, &rrd );

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

		if( Verbose ) {

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

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

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

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

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

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

		if( VeryVerbose ) { 

			resp_ptr = getaline( Rrdfp, response, STRSZ );

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

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

			} else {

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

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

	if( VeryVerbose ) {

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

	if( CacheDaemon == NULL ) {

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

	} else {

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

	}

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

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

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

	if( VeryVerbose ) { 

		resp_ptr = getaline( Rrdfp, response, STRSZ );

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

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

		} else {

			elog_notify( 0, "%s\n", resp_ptr );
		}
	}
	*/
}
コード例 #26
0
void
mortician()
{
	if (verbose > 1)
		elog_notify(0, "saving state\n");
}
コード例 #27
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);
}
コード例 #28
0
int load_station_geometry(Dbptr db, Arr *a, double time)
{
	Dbptr dbs;
	int i,j,nset;
	Tbl *t;
	char *key;
	int yrday;
	Dbptr dbscr;
	static Hook *hook=NULL;
	Tbl *match_tbl;
	MWstation *s;
	int ondate,offdate;
	char refsta[10];  /*This is used as input buffer that
				is duped to store in each s object*/
	char refsta0[10];  /* Used for comparison to guarantee there
				is no change in refsta */

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

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

			if(nmatch == 1)
			{
				db.record = (int )gettbl(match_tbl,0);
			}
			else
			{
				for(j=0;j<maxtbl(match_tbl);j++)
				{
					db.record = (int)gettbl(match_tbl,j);
					if(dbgetv(db,0,"ondate",&ondate,
							"offdate",&offdate,0)
						== dbINVALID)
					{
						elog_notify(0,"load_station_geometry:  dbgetv error while searching for ondate/offdate match for station %s\nBlundering on\n", 
							s->sta);
						continue;
					}
					if((yrday >= ondate) && (yrday <= offdate)) break;
				}
			}
			/* note if the date match fails,we still end up here 
			using the last record in the db */
			freetbl(match_tbl,0);
			if(dbgetv(db,0,
				"lat",&(s->lat),
				"lon",&(s->lon),
				"elev",&(s->elev),
				"dnorth",&(s->dnorth),
				"deast",&(s->deast),
				"refsta",refsta,
				0) == dbINVALID)
			{
				elog_notify(0,"load_station_geometry:  dbgetv error reading record %d for station %s in site table\nStation deleted from list\n",
					db.record,s->sta);
				delarr(a,s->sta);
				free_MWstation(s);
			}
			else
			{
				if(nset==0) strcpy(refsta0,refsta);
				s->refsta = strdup(refsta0);
				if(!strcmp(s->sta,refsta0))
				{
					if(((s->dnorth)!=0.0) 
						|| ((s->deast)!=0.0))
						elog_die(0,"load_station_geometry:  reference station in site table must have dnorth and deast set to 0.0\nFound refstat = %s with (dnorth,deast)=(%lf,%lf)\n",
							s->sta,s->dnorth,
							s->deast);
					++nset;
				}
				else
				/* This deletes stations != refsta with dnorth 
				and deast not set properly.  */
				{
					if(((s->dnorth)==0.0) && ((s->deast)==0.0))
					{
						elog_notify(0,"load_station_geometry:  unset dnorth and deast entries for station %s\nStation deleted from list\n",
							s->sta);
						delarr(a,s->sta);
						free_MWstation(s);
					}
					else if(strcmp(refsta0,refsta))
						elog_die(0,"load_station_geometry:  reference station change not allowed.\nAll stations to be processed must have a common refsta in site table\n");
					else
						++nset;
				}
			}
		}
	}		
	return(nset);
}
コード例 #29
0
/*
 * Main program loop
 */
int main(int iArgCount, char *aArgList[]) {

	uint8_t *aBBAPkt; /* Buffer to hold a bba packet read from the wire */
	struct stBBAPacketInfo oPktInfo; /* Struct to hold information from the packet header */
	double dPrevTime;
	int bOKToSend;
	char *sOutPkt; /* Packet to put onto the orb */
	int iOutPktLen; /* Length of sOutPkt */

	elog_init(iArgCount, aArgList);

	/* Parse out command line options */
	if (parseCommandLineOptions(iArgCount, aArgList) == RESULT_SUCCESS) {

		/* Read in the parameter file */
		if (paramFileRead() == RESULT_FAILURE) {
			elog_complain(1,
					"main(): Error encountered during paramFileRead() operation.");
			dcbbaCleanup(-1);
		}

		/* Exit if bPFValidateFlag is set */
		if (oConfig.bPFValidateFlag == TRUE) {
			elog_notify(
					0,
					"main(): Parameter File %s validated successfully. Exiting.",
					oConfig.sParamFileName);
			dcbbaCleanup(0);
		}

		/* Allocate memory for our packet */
		allot (uint8_t *, aBBAPkt, oConfig.iBBAPktBufSz);

		/* Set up a signal handler to re-read the parameter file on SIGUSR1*/
		signal(SIGUSR1, sig_hdlr);

		/* Connect to the ORB */
		if ((orbfd = orbopen(oConfig.sOrbName, "w&")) < 0) {
			elog_complain(1, "orbopen: unable to connect to ORB \"%s\".",
					oConfig.sOrbName);
			dcbbaCleanup(-1);
		}

		/* Connect to Data Concentrator's Data read port */
		if (dcDataConnect(oConfig.iConnectionType, oConfig.sDCConnectionParams)
				== RESULT_SUCCESS) {
			dPrevTime = now();

			/*** BEGIN MAIN LOOP ***/
			while (readFromDC(&oPktInfo, aBBAPkt) == RESULT_SUCCESS) {
				bOKToSend = TRUE;
				/* Check the packet age */
				/*if (fabs(oPktInfo.dPktTime - dPrevTime) > 86400.0) {
				 dPrevTime = now();
				 if (fabs(oPktInfo.dPktTime - dPrevTime) > 86400.0) {
				 elog_complain(
				 0,
				 "%s packet has bad time - %s (epoch:%lf). Will discard packet.\n",
				 oPktInfo.sSrcname, sTimeStamp = strtime(
				 oPktInfo.dPktTime), oPktInfo.dPktTime);
				 free(sTimeStamp);
				 bOKToSend = FALSE;
				 } else
				 dPrevTime = oPktInfo.dPktTime;
				 } else
				 dPrevTime = oPktInfo.dPktTime;*/

				if (bOKToSend == TRUE) {
					/* Add orb header to Packet */
					iOutPktLen = (int) stuffBBAPkt(&oPktInfo, aBBAPkt, &sOutPkt);
					if (iOutPktLen == 0) {
						/* There was an error stuffing the packet*/
						elog_complain(
								1,
								"An error occurred while adding the ORB header to the raw packet. Not submitting to the orb.");
					} else if (sOutPkt == 0) {
						elog_die(1,
								"Output packet length was non-zero but pointer to Output packet is null");
					} else {

						/* put it into the orb */
						if (oConfig.bVerboseModeFlag == TRUE) {
							showPkt(0, oPktInfo.sSrcname, oPktInfo.dPktTime,
									sOutPkt, iOutPktLen, stderr, PKT_UNSTUFF);
							showPkt(0, oPktInfo.sSrcname, oPktInfo.dPktTime,
									sOutPkt, iOutPktLen, stderr, PKT_DUMP);
						}

						if (orbput(orbfd, oPktInfo.sSrcname, oPktInfo.dPktTime,
								sOutPkt, iOutPktLen)) {
							elog_complain(0, "orbput() failed in main()\n");
							dcbbaCleanup(-1);
						}

						if (oConfig.bVerboseModeFlag == TRUE)
							elog_notify(0, "packet submitted under %s\n",
									oPktInfo.sSrcname);

						/* Free the packet */
						free(sOutPkt);
					}
				}
			}

			/*
			 * If we get here, it means readFromDC failed to get a packet from oDCDataBNS.
			 * This could be either that an EOF was reached if we were reading from a file,
			 * or that the socket died unexpectedly.
			 */
			dcbbaCleanup(-1);
		}

		/* Else unable to connect, cleanup with failure (-1) exit code */
		else
			dcbbaCleanup(-1);

	} else {
コード例 #30
0
static void
archive_dlsvar( Dbptr db, char *net, char *sta, char *dls_var, char *dsparams, Tbl *rras, double time, double val )
{
	char	key[STRSZ];
	char	*rrd;
	double	start_time;
	Dbptr	dbt;
	char	datasource[STRSZ];
	char	command[STRSZ];
	char	response[STRSZ];
	char	*resp_ptr;
	int	i;

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

	rrd = getarr( Rrd_files, key );

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

		start_time = time - Status_stepsize_sec;

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

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

		trwfname( dbt, Rrdfile_pattern, &rrd );

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

		if( Verbose ) {

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

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

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

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

		if( VeryVerbose ) { 

			resp_ptr = getaline( Rrdfp, response, STRSZ );

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

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

			} else {

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

		setarr( Rrd_files, key, rrd );
	}

	if( VeryVerbose ) {

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

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

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

	if( VeryVerbose ) { 

		resp_ptr = getaline( Rrdfp, response, STRSZ );

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

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

		} else {

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