int opendb( Dset *dset ) { char key[256]; Tbl *sort_sta_ch_tm; if (dbopen_database ( dset->dbname, "r+", &(dset->db) ) == dbINVALID ) die (0, "Can't open database %s\n", dset->dbname ); dset->db = dblookup ( dset->db, 0, "wfdisc", 0, 0); if ( dset->db.table == dbINVALID ) die (0, "Can't open '%s' wfdisc table.\n", dset->dbname ); /* Select specified sta&chan */ sprintf( key,"(chan =~ /%s/ && sta=~ /%s/)\0", dset->chan, dset->sta ); dset->db = dbsubset( dset->db, key, 0 ); sort_sta_ch_tm = strtbl("sta", "chan", "time", 0 ) ; dset->db = dbsort ( dset->db, sort_sta_ch_tm, 0, 0 ) ; dbquery ( dset->db, dbRECORD_COUNT, &(dset->dbrec) ); if( dset->dbrec <= 0 ) die( 0, " no record with sta == %s and chan == %s in %s.\n", dset->sta, dset->chan, dset->dbname ); return 1; }
static int autodrm_response (Dbptr db) { Dbptr dbstage; static Hook *hook = 0; char sta[MAX_STA_SIZE], chan[MAX_CHAN_SIZE]; double time, endtime; long stageid; char *s; Response *response; Response_group *group; char iunits[96], ounits[96]; char gtype[100]; long i, j; Paz *paz; Fir *fir; Fap *fap; Fap2 *fap2; FILE *file; double samprate, gnom, gcalib; double calper=0.0; long decifac; char dir[100], dfile[100]; char filename[STRSZ]; long nmatches; int errors = 0; Tbl *tbl, *stbl; double mintime=0, maxtime=0; char segtype; static Tbl *keys1 = 0, *keys2 = 0; if (keys1 == 0) { keys1 = strtbl ("sta", "chan", "time", NULL); keys2 = strtbl ("sta", "chan", "time::endtime", NULL); } dbstage = dblookup (db, 0, "stage", 0, 0); nmatches = dbmatches (db, dbstage, &keys1, &keys2, &hook, &tbl); switch (nmatches) { case dbINVALID: case 0: dbgetv (db, 0, "sta", sta, "chan", chan, "time", &time, NULL); complain (0, "Can't match record for %s:%s @ %s in stage table", sta, chan, s = strydtime (time)); free (s); errors++; break; default: stbl = newtbl (maxtbl (tbl)); for (i = 0; i < nmatches; i++) { dbstage.record = (long) gettbl (tbl, i); dbgetv (dbstage, 0, "stageid", &stageid, "time", &time, "endtime", &endtime, NULL); if (i == 0) { mintime = time; maxtime = endtime; } else { mintime = MAX (time, mintime); maxtime = MIN (endtime, maxtime); } settbl (stbl, stageid - 1, (char *) i); } if (maxtbl (tbl) != maxtbl (stbl)) { dbgetv (db, 0, "sta", sta, "chan", chan, "time", &time, NULL); complain (0, "stageid numbers for %s:%s @ %s don't add up.", sta, chan, s = strydtime (time)); free (s); errors++; } else { errors += write_cal2 (db, mintime, maxtime, &calper); for (i = 0; i < nmatches; i++) { j = (long) gettbl (stbl, i); dbstage.record = (long) gettbl (tbl, j); dbgetv (dbstage, 0, "sta", sta, "chan", chan, "time", &time, "endtime", &endtime, "stageid", &stageid, "decifac", &decifac, "samprate", &samprate, "gnom", &gnom, "gcalib", &gcalib, "dir", dir, "dfile", dfile, "gtype", gtype, "iunits", iunits, "ounits", ounits, NULL); if (gcalib > 0.0) { gnom *= gcalib; } else if (gcalib < 0.0) { complain (0, "gcalib = %10.3f < 0. is invalid for %s:%s @ %s.\n", gcalib, sta, chan, s = strydtime (time)); free (s); errors++; } if (*dir != '-' || *dfile != '-') { long mark; dbextfile (dbstage, "stage", filename); mark = elog_mark (); elog_log (0, "response file is '%s'", filename); if ((file = fopen (filename, "r")) == 0 || read_response (file, &response) < 0) { register_error (0, "Can't read response file %s for %s_%s @ %s", filename, sta, chan, s = strydtime (time)); free (s); fclose (file); errors++; } else { fclose (file); if (response->ngroups > 1) { register_error (0, "stage response file %s has %d stages, not 1", filename, response->ngroups); errors++; } else { group = response->groups; switch (group->id) { case PAZ: /* The normalization frequency chosen in the * response file may not necessarily be the * same as the one chosen by calibration * table for insertion into the seed volumes. * Consequently, we have to adjust the * specified gnom to be correct for the seed * normalization frequency. Since the gain * is * * G(f) = gnom_db * A_response_file * P(f) = * gnom_seed * A_seed * P(f) * * We have * * gnom_seed = gnom_db * A_response_file / * A_seed * * gnom_db is just the gnom from the stage * table. A_response_file is the * normalization from the response file, left * in the stage structure. Below, we * calculate A_seed by setting * A_response_file to 1.0. * */ paz = (Paz *) group->pvt; for (j = 0; j < strlen (iunits); j++) { iunits[j] = tolower (iunits[j]); } s = getarr (Segtype, iunits); if (s == 0) { segtype = 'D'; } else { segtype = *s; } adwrite_paz (stageid, 0, gnom, segtype, ounits, paz); break; case IIR: paz = (Paz *) group->pvt; for (j = 0; j < strlen (iunits); j++) { iunits[j] = tolower (iunits[j]); } s = getarr (Segtype, iunits); if (s == 0) { segtype = 'D'; } else { segtype = *s; } adwrite_paz (stageid, 1, gnom, segtype, ounits, paz); break; case FIR: fir = (Fir *) group->pvt; errors += adwrite_fir (stageid, gnom, fir); break; case FAP: fap = (Fap *) group->pvt; errors += adwrite_fap (stageid, ounits, fap); break; case FAP2: fap2 = (Fap2 *) group->pvt; errors += adwrite_fap2 (stageid, ounits, fap2); break; default: complain (0, "Unknown filter type %d in response file %s\n", group->id, filename); errors++; break; } } } elog_flush (mark, 0); } else { char *desc = ""; if (gcalib > 0.0) { gnom *= gcalib; } else if (gcalib < 0.0) { complain (0, "gcalib = %10.3f < 0. is an invalid value.\n", gcalib); errors++; } if (strcmp (gtype, "digitizer") == 0 /* following hack for psd2db */ || strcmp (gtype, "sensor") == 0) { fprintf (stdout, "DIG2 %2ld %15.8e %11.5f %s\n", stageid, gnom, samprate, desc); } else if (strcmp (gtype, "amplifier") == 0) { /* no corners */ fprintf (stdout, "GEN2 %2ld %c %15.8e %7.3f 0 %s\n", stageid, *ounits, gnom, calper, desc); } else { complain (0, "Unrecognized gtype='%s' for %s:%s @ %s", gtype, sta, chan, s = strydtime (time)); free (s); errors++; } } } } freetbl (stbl, 0); break; } freetbl (tbl, 0); return errors; }
static Tbl * get_fieldnames( Dbptr db, int flags ) { Tbl *fieldnames; Tbl *view_tables; Tbl *table_fields; char *tablename; char *fieldname; char afield[STRSZ]; Dbvalue result; int itable; int ifield; static Hook *hook = 0; int start; int nchars; int is_view; fieldnames = newtbl( 0 ); view_tables = newtbl( 0 ); dbquery( db, dbTABLE_IS_VIEW, &is_view ); if( is_view ) { dbquery( db, dbVIEW_TABLES, &view_tables ); view_tables = duptbl( view_tables, (void *(*)(void *)) strdup ); } else { dbquery( db, dbTABLE_NAME, &result ); view_tables = strtbl( strdup( result.t ), 0 ); } for( itable = 0; itable < maxtbl( view_tables ); itable++ ) { tablename = gettbl( view_tables, itable ); db = dblookup( db, "", tablename, "", "" ); if( flags & DBXML_PRIMARY ) { dbquery( db, dbPRIMARY_KEY, &table_fields ); } else { dbquery( db, dbTABLE_FIELDS, &table_fields ); } for( ifield = 0; ifield < maxtbl( table_fields ); ifield++ ) { fieldname = gettbl( table_fields, ifield ); if( strcontains( fieldname, "::", &hook, &start, &nchars ) ) { strcpy( afield, fieldname ); afield[start] = '\0'; fprintf( stderr, "SCAFFOLD: adding %s\n", afield); add_fieldname( fieldnames, tablename, afield ); strcpy( afield, fieldname + start + 2 ); fprintf( stderr, "SCAFFOLD: adding %s\n", afield); add_fieldname( fieldnames, tablename, afield ); } else { add_fieldname( fieldnames, tablename, fieldname ); } } } freetbl( view_tables, free ); return fieldnames; }
/* main for dbpmel*/ int main(int argc, char **argv) { char *dbin; /* Input db name */ Tbl *gridlist; Dbptr db; /* input db pointer */ Dbptr dbv; /* set to view formed by join */ char *pfin=NULL; /* input parameter file */ char *sift_exp; /* sift expression for subset */ int sift = 0; /* default is no sift. */ Tbl *sortkeys; /* db row variables */ int nrows, nrows_raw; Pf *pf; char *version="1.0"; int i; int gmin,gmax; char sstring[128]; char *gridname; Tbl *proctbl; /* Initialize the error log and write a version notice */ elog_init (argc, argv) ; fprintf (stdout, "%s version %s\n", argv[0], version) ; if(argc < 3) usage(); dbin = argv[1]; gridlist = parse_gridlist_string(argv[2]); get_gridid_range(gridlist,&gmin,&gmax); for(i=3;i<argc;++i) { if(!strcmp(argv[i],"-pf")) { ++i; if(i>=argc) usage(); pfin = argv[i]; } else if(!strcmp(argv[i],"-sift")) { ++i; if(i>=argc) usage(); sift_exp = argv[i]; sift = 1; } else usage(); } /* set default this way*/ if(pfin == NULL) pfin = (char *)strdup("dbpmel"); i = pfread(pfin,&pf); if(i != 0) die(1,"Pfread error\n"); check_required_pf(pf); /* Set up main database view. This is a derived from code in the related genloc program called relocate. Always join assoc, arrival, and site. We join site to make sure station table is properly dynamic to account for time changes. With this setup, the stations can even move around and this should still work.*/ gridname = pfget_string(pf,"gridname"); if(dbopen(dbin,"r+",&db) == dbINVALID) elog_die(1,"Unable to open input database %s\n",dbin); /* We save the pf object into archive files that document the complex state of this program. This small function does this and saves the results in a special db table */ save_run_parameters(db,pf); db = dblookup(db,0,"hypocentroid",0,0); sprintf(sstring,"gridid>=%d && gridid<=%d && (gridname=~/%s/)",gmin,gmax,gridname); db = dbsubset(db,sstring,0); dbquery(db, dbRECORD_COUNT, &nrows); if(nrows<=0) elog_die(0,"No hypocentroid records in requested gridid range of %d to %d for grid called %s\n", gmin,gmax,gridname); /* This forms the working view for this program */ proctbl = strtbl("dbjoin cluster", "dbjoin event", "dbjoin origin", "dbsubset orid==prefor", "dbjoin assoc", "dbjoin arrival",0); dbv = dbprocess(db,proctbl,0); dbquery(dbv, dbRECORD_COUNT, &nrows); fprintf(stdout,"Raw working database view has %d rows\n",nrows); /* Subset using sift_key if requested */ if(sift) { dbv = dbsubset(dbv,sift_exp,0); if(dbv.record == dbINVALID) die(1,"dbsubset of %s with expression %s failed\n", dbin, sift_exp); } /* First we have to run a unique key sort in the following order to remove redundant picks made on multiple channels. We will issue a warning if the record count changes. This was found to be a common problem that had to be repaired automatically.*/ dbquery(dbv, dbRECORD_COUNT, &nrows_raw); sortkeys = newtbl(0); pushtbl(sortkeys,"gridid"); pushtbl(sortkeys,"evid"); pushtbl(sortkeys,"sta"); pushtbl(sortkeys,"phase"); dbv = dbsort(dbv,sortkeys,dbSORT_UNIQUE,0); dbquery(dbv, dbRECORD_COUNT, &nrows); if(nrows != nrows_raw) complain(0,"Input database has duplicate picks of one or more phases on multiple channels\n\ Which picks will be used here is unpredictable\n\ %d total picks, %d unique\nContinuing\n", nrows_raw, nrows); fprintf(stdout,"Final working view has %d rows\n",nrows); if(dbpmel_process(dbv,gridlist,pf)) { elog_complain(0,"Errors in dbpmel_process\n"); exit(-1); } exit(0); }
static int parse_to_strtbl( PyObject *obj, void *addr ) { Tbl **atbl = (Tbl **) addr; PyObject *seqobj; long nitems = 0; long iitem; char *astring; char errmsg[STRSZ]; if( obj == Py_None ) { *atbl = NULL; return 1; } if( PyString_Check( obj ) ) { *atbl = strtbl( strdup( PyString_AsString( obj ) ), NULL ); return 1; } if( ! PySequence_Check( obj ) ) { PyErr_WarnEx( NULL, "Attempt to convert sequence to table of strings failed: input argument is not a sequence", 1 ); *atbl = NULL; return 0; } nitems = PySequence_Size( obj ); *atbl = newtbl( nitems ); for( iitem = 0; iitem < nitems; iitem++ ) { seqobj = PySequence_GetItem( obj, iitem ); if( ! seqobj ) { freetbl( *atbl, free ); *atbl = NULL; sprintf( errmsg, "Attempt to convert sequence to table of strings failed: " "failed to extract item %ld (counting from 0)", iitem ); PyErr_WarnEx( NULL, errmsg, 1 ); return 0; } if( ! PyString_Check( seqobj ) ) { freetbl( *atbl, free ); *atbl = NULL; sprintf( errmsg, "Attempt to convert sequence to table of strings failed: " "item %ld (counting from 0) is not a string", iitem ); PyErr_WarnEx( NULL, errmsg, 1 ); return 0; } if( ( astring = PyString_AsString( seqobj ) ) == NULL ) { freetbl( *atbl, free ); *atbl = NULL; sprintf( errmsg, "Attempt to convert sequence to table of strings failed: " "conversion of item %ld (counting from 0) to string failed", iitem ); PyErr_WarnEx( NULL, errmsg, 1 ); return 0; } pushtbl( *atbl, strdup( astring ) ); } return 1; }
int dbpmel_save_results(Dbptr db, int nevents, long *evid, Hypocenter *h, Tbl **ta, Location_options o, Pf *pf) #endif { Dbptr dbe,dbo,dba,dboe; Dbptr dbes,dbos,dbas; Dbptr dbs; /* subset view created by dblist2subset */ Tbl *opat,*aspat,*aspat2; Tbl *matches=NULL,*match2; /* output list of matching records */ /* Dan Q advises it is wise to have a separate hook for each table passed through dbmatches */ Hook *hooke=NULL,*hooko=NULL,*hooka=NULL,*hooka2=NULL; long prefor; int i,j; char *auth; Arrival *a; long orid; int nmatch; double **C; float emodel[4]; char *alg=(char *)strdup("dbpmel"); /* A collection of variables from assoc that have to be copied. Earlier algorithm using dbget raw on a subset view failed so I have to copy by this mechanism */ double belief; char timedef[2],slodef[2],azdef[2]; double azres,slores,emares; Tbl *utbl; /* This is needed as a stub for the predicted_error function. Because we don't support slowness vector data in pmel this has to be an empty (NOT NULL) tbl list */ utbl=newtbl(0); /* All of these are used repeatedly so we do one lookup at the top */ dbe = dblookup(db,0,"event",0,0); dbo = dblookup(db,0,"origin",0,0); dba = dblookup(db,0,"assoc",0,0); dboe = dblookup(db,0,"origerr",0,0); dbes = dblookup(db,0,"event",0,0); dbos = dblookup(db,0,"origin",0,0); dbas = dblookup(db,0,"assoc",0,0); dbes.record = dbSCRATCH; dbos.record = dbSCRATCH; dbas.record = dbSCRATCH; opat = strtbl("orid",NULL ); aspat = strtbl("orid",NULL ); aspat2 = strtbl("arid","orid","sta",NULL ); auth = pfget_string(pf,"author"); C = dmatrix(0,3,0,3); /* outer loop over nevents */ for(i=0;i<nevents;++i) { double conf; char *modtype; int model; double smajax,sminax,strike,sdepth,stime; int rc; /* Save nothing for events marked no use */ if(h[i].used==0) continue; /* Start with event table to get prefor */ dbputv(dbes,0,"evid",evid[i],NULL ); dbe.record = dbALL; if(dbmatches(dbes,dbe,0,0,&hooke,&matches)!=1) elog_complain(0,"WARNING: multiple records in event table have evid=%ld.\nThis is a serious database problem that should be corrected. Using first one found in table\n", evid[i]); dbe.record = (long)gettbl(matches,0); /* this is excessively paranoid, but better safe than sorry*/ if(dbe.record<0) { elog_complain(0,"dbmatches invalid record %ld\nSkip saving evid %ld\n", dbe.record,evid[i]); continue; } dbgetv(dbe,0,"prefor",&prefor,NULL ); freetbl(matches,0); matches=NULL; dbputv(dbos,0,"orid",prefor,NULL ); dbo.record = dbALL; nmatch=dbmatches(dbos,dbo,&opat,&opat,&hooko,&matches); if(nmatch>1) elog_complain(0,"WARNING: multiple records in origin table match orid=%ld.\nThis is a serious database problem that should be corrected. Using first one found in table\n", prefor); else if(nmatch<=0) { elog_complain(0,"Cannot find matching origin\ record for orid %ld prefor of event %ld\n", prefor,evid[i]); } dbo.record = (long)gettbl(matches,0); if(dbget(dbo,0)==dbINVALID) { elog_complain(0,"dbget error on origin table for orid %ld\nData for evid %ld will not be saved\n", prefor,evid[i]); continue; } freetbl(matches,0); matches=NULL; /* origerr code cloned from dbgenloc */ conf = pfget_double(pf,"confidence"); modtype = pfget_string(pf,"ellipse_type"); if(modtype == NULL) { elog_complain(0,"parameter ellipse_type not defined--default to chi_square"); model = CHI_SQUARE; } else if( strcmp( modtype, "chi_square" ) == 0 ) { model = CHI_SQUARE; } else if( strcmp( modtype, "F_dist" ) == 0 ) { model = F_DIST; } else { elog_complain(0, "parameter ellipse_type %s incorrect (must be F_dist or chi_square)--default to chi_square", modtype ); model = CHI_SQUARE; } predicted_errors(h[i],ta[i],utbl,o,C,emodel); rc = project_covariance( C, model, &conf, h[i].rms_weighted, h[i].degrees_of_freedom, &smajax, &sminax, &strike, &sdepth, &stime ); if( rc != 0 ) { elog_complain(0, "project_covariance failed." ); smajax = -1; sminax = -1; strike = -1; sdepth = -1; stime = -1; conf = 0.; } orid = dbnextid(dbo,"orid"); if(dbaddv(dboe,0, "orid", orid, "sxx",C[0][0], "syy",C[1][1], "szz",C[2][2], "stt",C[3][3], "sxy",C[0][1], "sxz",C[0][2], "syz",C[1][2], "stx",C[0][3], "sty",C[1][3], "stz",C[2][3], "sdobs", h[i].rms_raw, "smajax", smajax, "sminax", sminax, "strike", strike, "sdepth", sdepth, "stime", stime, "conf", conf, NULL ) < 0 ) { elog_complain(0,"Problem adding origerr record for evid %ld\n", evid[i]); } /* This edits the scratch record and adds it to the end of the origin table */ dbputv(dbos,0,"orid",orid, "lat",h[i].lat, "lon",h[i].lon, "depth",h[i].z, "time",h[i].time, "algorithm",alg, "auth",auth,NULL ); /* printf("Added to origin table: %8d %9.4lf %9.4lf %9.4lf" " %17.5lf %-15s %-15s\n", orid, h[i].lat, h[i].lon, h[i].z, h[i].time, alg, auth); */ if(dbadd(dbo,0)==dbINVALID) elog_complain(0,"dbadd error for origin table\ for new orid %ld of evid %ld\n", orid,evid[i]); /* The assoc tables is much more complex. Rather than do a row for row match against each arrival in ta, I use a staged reduction. Than is I first match the full assoc table against orid=prefor only to get a full list of records for that event. We then run matches against the smaller table for sta/phase in the arrival list. Untested but from previous experience with dbmatches on large tables I'm fairly sure this is a necessary complication to keep this from be very slow*/ dbputv(dbas,0,"orid",prefor,NULL ); dba.record = dbALL; nmatch=dbmatches(dbas,dba,&aspat,&aspat,&hooka,&matches); if(nmatch<=0) { elog_complain(0,"No assoc records for orid %ld\ found\nFail to create new assoc records for orid %ld\n", prefor,orid); freetbl(matches,0); continue; }