/************************************************************************/ /* Populate_Station.pc: Load station information into the NCEDC database /************************************************************************/ /* Author: Stephane Zuzlewski UC Berkeley Seismological Laboratory stephane@seismo.berkeley.edu Purpose: Modification History: Date Ver Who What --------------------------------------------------------------------- 1998/??/?? 1.0 SMZ Initial coding. 2000/01/15 1.0 SMZ Added support for SOH channels. 2000/07/25 1.0 SMZ Added support for optional channel comment in DLOGFC line. 2000/08/14 1.0 SMZ Added support for SEED location code. 2000/10/19 1.0 SMZ Changed float variables to double. 2001/01/09 1.0 SMZ Implemented closed time intervals; [Ts;Te[. 2001/08/16 1.0 SMZ Added support for Digital board. 2002/01/30 1.0 SMZ Added more explicit oracle error messages. 2002/08/12 2.0 SMZ Added support for external channel and source. */ /************************************************************************/ #ifndef lint static char sccsid[] = "%W% %G% %U%"; #endif #include #include #include #define CONNECT_STRING "user/passwd@db" #define NOMOREROWS 1403 #define TOOMANYROWS -2112 #define VERSION "2.0" #define info stdout char *syntax[] = { "%s version " VERSION " -- Load station information into the NCEDC database.", "%s [-h] ", " where:", " -h Help - prints syntax message.", NULL }; /************************************************************************/ EXEC SQL INCLUDE sqlca.h; typedef char asciz[20]; typedef char vc2_arr[11]; EXEC SQL BEGIN DECLARE SECTION; /* User-defined type for null-terminated strings */ EXEC SQL TYPE asciz IS STRING(20) REFERENCE; /* User-defined type for a VARCHAR array element */ EXEC SQL TYPE vc2_arr IS VARCHAR2(11) REFERENCE; asciz username; asciz password; char user_pwd[80]; int i; int j; int k; char sta[7]; /* Station code */ char net[9]; /* Network code */ double lat; /* Latitude */ double lon; /* Longitude */ double elev; /* Elevation */ double slat; /* Sensor latitude */ double slon; /* Sensor longitude */ double selev; /* Sensor elevation */ char test[32]; /* Test string */ char staname[51]; /* Station name */ int nb_sensor; /* Number of sensors */ int nb_filamp; /* Number of filter-amplifiers */ int nb_digi; /* Number of digitizers */ int nb_data; /* Number of dataloggers */ char s_dat[32]; /* Start date */ char e_dat[32]; /* End date */ int sensor_nb; /* Sensor number */ char sensor_sn[32]; /* Sensor serial number */ double depth; /* Sensor depth */ int nb_component; /* Number of components */ int pdn; /* Preamplifier/Digitizer number */ char dtyp[32]; /* Digitizer type */ double az; /* Azimuth */ double dip; /* Dip */ int pdch; /* Preamplifier/Digitizer channel */ char pdtyp; /* Preamplifier/Digitizer */ char preamp_sn[32]; /* Preamplifier serial number */ int nch; /* Number of channels */ int dno; /* Digitizer number */ int dch; /* Digitizer channel number */ int drch; /* Digitizer *REAL* channel number */ char digi_sn[32]; /* Digitizer serial number */ int nb_pri; /* Number of primary channels */ int nb_aux; /* Number of auxiliary channels */ int nb_cha; /* Total number of channels */ int dln; /* Datalogger number */ char dtyp[32]; /* Digitizer type */ int dlch; /* Datalogger channel number */ char pol[32]; /* Digitizer polarity */ char data_sn[32]; /* Datalogger serial number */ int dnch; /* Number of channels */ char board_type; /* Board type */ char channel_type; /* Channel type */ char seed_io[32]; /* SEED instrument and orientation code */ int nbf; /* Number of filters */ char seed[32]; /* Channel/Location/External field */ char seed1[32]; char seed2[32]; char seedchan[4]; /* SEED channel name */ char location[3]; /* SEED location code */ char channel[4]; /* External channel name */ char channelsrc[9]; /* External channel source */ double sps; /* Sampling rate */ double mrgf; /* Master rgain frequency */ double ctol; /* Clock tolerance */ char dtyp[32]; /* Data type */ char seq[32]; /* Filter sequence */ char dfmt[32]; /* Data format */ char ctyp[32]; /* Compression type */ int blks; /* Block size */ int sensor_id; /* Sensor identifier */ int filamp_id; /* Filter-amplifier identifier */ int data_id; /* Datalogger identifier */ int seqfil_id; /* Sequence of filters identifier */ int comp_type; /* Compression type */ int unit_signal; /* Units of signal responses */ int unit_calib; /* Units of calibration */ int digi_nb; /* Digitizer number */ int digi_pchannel_nb; /* Digitizer physical channel number */ int data_nb; /* Datalogger number */ int data_pchannel_nb; /* Datalogger physical channel number */ int filamp_nb; /* Filter-Amplifier number */ int filamp_pchannel_nb; /* Filter-Amplifier physical channel number */ int sensor_nb; /* Sensor number */ int component_nb; /* Component number */ int channel_nb; /* Channel number */ char remark[31]; /* Optional comment */ short ind; /* Indicator */ EXEC SQL END DECLARE SECTION; /************************************************************************/ /* External variables and symbols. */ /************************************************************************/ char *cmdname; /* program name from command line. */ long SQLCODE; FILE* f_err; /* Error File descriptor */ void sql_error(); /* handles unrecoverable errors */ /************************************************************************/ /* print_syntax: */ /* Print the syntax description of program. */ /************************************************************************/ int print_syntax (char *cmd, /* program name. */ char *syntax[], /* syntax array. */ FILE *fp) /* FILE ptr for output. */ { int i; for (i=0; syntax[i] != NULL; i++) { fprintf (fp, syntax[i], cmd); fprintf (fp, "\n"); } return (0); } /************************************************************************/ /* Convert_Date: */ /* Function to convert a julian date to a Oracle date. */ /************************************************************************/ char* Convert_Date (char d[16]) { EXEC SQL BEGIN DECLARE SECTION; static char nd[32]; char day[16]; EXEC SQL END DECLARE SECTION; char hour[5]; char year[5]; char sday[4]; sprintf (year, "%.4s", d); sprintf (sday, "%.3s", d+5); sprintf (hour, "%.4s", d+9); if (!strcmp (year, "2599")) { strcpy (nd, "3000/01/01 00:00:00"); return (nd); } else if (!strcmp (year, "????")) { strcpy (nd, "0001/01/01 00:00:00"); return (nd); } strcpy (day, d); day[8] = '\0'; EXEC SQL SELECT TO_CHAR (TO_DATE (:day, 'YYYY.DDD'), 'YYYY/MM/DD HH24:MI:SS') INTO :nd FROM DUAL; sprintf (nd, "%.4s/%.2s/%.2s %.2s:%.2s:00", year, nd+5, nd+8, hour, hour+2); return (nd); } /************************************************************************/ /* main: main program. /************************************************************************/ main (int argc, char* argv[]) { FILE* f_station; /* Station file descriptor */ char n_station[32]; /* Station file name */ char line[1025]; /* Line information */ char linecm[1025]; /* Line information */ char header[7]; /* Header */ int FlagCm = 0; /* Comment Flag */ char sdat[16]; /* Start date */ char edat[16]; /* End date */ char *ctmp; /* Variables needed for getopt. */ extern char *optarg; extern int optind, opterr; int c; char *p; cmdname = ((p = strrchr(*argv,'/')) != NULL) ? ++p : *argv; /* Parse command line options. */ while ( (c = getopt(argc,argv,"h")) != -1) switch (c) { case '?': case 'h': print_syntax(cmdname,syntax,info); exit(0); break; default: fprintf (info, "Unknown option: -%c\n", c); exit(1); } /* Skip over all options and their arguments. */ argv = &(argv[optind]); argc -= optind; /* Testing parameters */ if (argc != 1) { print_syntax(cmdname,syntax,info); exit (0); } /* Opening the station file */ sprintf (n_station, "%s", argv[0]); if ((f_station = fopen (n_station, "rt")) == NULL) { printf ("\n Error [File (%s) could not be opened].\n\n", n_station); exit (0); } /* Opening the error file */ if ((f_err = fopen ("Error.log", "w+t")) == NULL) { printf ("\n Error [File (Error.log) could not be opened].\n\n"); exit (0); } /* Connect to ORACLE. */ EXEC SQL WHENEVER SQLERROR DO sql_error(); strcpy (user_pwd, CONNECT_STRING); EXEC SQL CONNECT :user_pwd; printf ("\n Connected to ORACLE as user: %s\n", username); /* Parsing station file */ fgets (line, 1024, f_station); while (!feof (f_station)) { strcpy (header, ""); sscanf (line, "%s", header); if (!strcmp (header, "SCODE")) { /* Reading station information */ sscanf (line, "%*s %s %s %lf %lf %lf \"%s\"", sta, net, &lat, &lon, &elev, staname); strcpy (staname, strstr (line+15, staname)); staname[strlen (staname) - 2] = '\0'; printf ("\n Station : %s\t%s\t%f\t%f\t%f\t%s", sta, net, lat, lon, elev, staname); } else if (!strcmp (header, "STINST")) { /* Reading instrument information */ sscanf (line, "%*s %d %d %d %d %s %s", &nb_sensor, &nb_filamp, &nb_digi, &nb_data, sdat, edat); /* Converting dates format */ strcpy (s_dat, Convert_Date (sdat)); strcpy (e_dat, Convert_Date (edat)); printf ("\n Instrument : %d\t%d\t%d\t%d\t%s\t%s", nb_sensor, nb_filamp, nb_digi, nb_data, s_dat, e_dat); EXEC SQL INSERT INTO Station (sta, net, lat, lon, elev, staname, nb_sensor, nb_filamp, nb_digi, nb_data, datumhor, datumver, ondate, offdate, lddate) VALUES (:sta, :net, :lat, :lon, :elev, :staname, :nb_sensor, :nb_filamp, :nb_digi, :nb_data, 'WGS84', 'WGS84', :s_dat, :e_dat, SYSDATE); /* Reading sensor information */ for (i=1;i<=nb_sensor;i++) { fgets (line, 1024, f_station); /* Reading sensor information */ strcpy (test, ""); sscanf (line, "%*s %*s %*s %*s %*s %s", test); if (strlen (test) == 0) { sscanf (line, "%*s %s %d %lf %d", sensor_sn, &sensor_nb, &depth, &nb_component); slat = lat; slon = lon; selev = elev; } else sscanf (line, "%*s %s %d %lf %lf %lf %lf %d", sensor_sn, &sensor_nb, &slat, &slon, &selev, &depth, &nb_component); printf ("\n\t Sensor %d: %s\t%f\t%d", sensor_nb, sensor_sn, depth, nb_component); EXEC SQL SELECT sensor_id INTO :sensor_id FROM Sensor WHERE serial_nb = :sensor_sn AND :s_dat >= ondate AND :s_dat < offdate; if (sqlca.sqlcode == (TOOMANYROWS)) { fprintf (f_err, "\nError: Multiple entries for sensor 'serial_nb=%s, ondate<=%s= ondate AND :s_dat < offdate; if (sqlca.sqlcode == (TOOMANYROWS)) { fprintf (f_err, "\nError: Multiple entries for filter-amplifier 'serial_nb=%s, ondate<=%s= ondate AND :s_dat < offdate; if (sqlca.sqlcode == (TOOMANYROWS)) { fprintf (f_err, "\nError: Multiple entries for datalogger 'serial_nb=%s, ondate<=%s