📄 rdseed.c
字号:
/*===========================================================================*//* SEED reader | rdseed | main program *//*===========================================================================*//*Name: rdseedPurpose: read Standard Exchange of Earthquake Data (SEED) format volumeUsage: Current usage is: rdseed inputfile -{a | c | d [list] | l | s | t} where inputfile = name of input file or device (required); a = retrieve abbreviation dictionaries; c = retrieve table of contents records from volume. d = retrieve all [selected] data, selection by list of record numbers; l = list contents of each block in volume; s = retrieve all station header information; t = show start/end times of all events on volume S = extract station records e = retrieve event information One of the function switch set {a c d l s t} is required. Eventually (subject to revision), usage will be: rdseed inputfile [precl] -{a | c | d [list] | l | s [list] | t} where inputfile = name of input file or device (required); precl = length of physical records on inputfile, default = 32768 (32 Kbytes) (optional); a = retrieve abbreviation dictionaries; c = retrieve volume table of contents. d = retrieve all [selected] data, selection by list of record numbers, station names, or times; l = list contents of each block in volume; s = retrieve all [selected] station header information, selection via list of station names; t = show start/end times of all events on volume One of the function switch set {a c d l s t} is required.Input: an input file or device on which the SEED data reside a function switch, from the list given above for function 'd', an optional space-separated list of desired seismograms, selected by beginning record number, station name, or time. If no list is given, all seismograms present are extracted. If record numbers are specified, only those seismograms which begin at the cited record numbers are extracted. The following may be added at in a later release: the physical record length of the data present on the input file for function 'd', If station names are given, all seismograms from the selected stations are written. If times are given, all seismograms starting near (plus or minus some time interval) the specified times are output. for function 's', an optional space-separated list of desired station headers.Output: for function 'a': the abbreviation dictionary is written to the standard output. for function 'c': the set of time headers for the volume, indicating station, component, start time, and starting record number, are written to the standard output. for function 'd': seismograms are written to files named by beginning time, station, and component; for example, 1988.023.15.34.08.2800.ANMO.SPZ is the filename for a seismogram from year 1988, Julian day 23, 15:34:08.2800 UT, recorded at station ANMO from component SPZ. for function 's': station header information is written to the standard output. for function 't': start/stop times for all events on the volumeWarnings several warnings are given by subprocedures. Typical response to a warning is that a message is sent to the standard error device and execution continues.Errors: various errors are trapped by subprocedures. Typical response to an error is that a message is sent to the standard error device and execution is terminated.Called by: userCalls to: Each logical record type has its own processor, as listed below. Each processor includes several parsing routines which parse the various blockette types; the parsing routines are described more fully in the leading comments of the process_xxxx source files. The processing routines are: process_data - for data records process_timeh - for time index header records process_stationh - for station header records process_abbrevdic - for abbreviation dictionary records process_volh - for volume header records process_blank - for blank records (default) - for unknown record typesAlgorithm: Open the input file for reading; if the input file cannot be opened, issue an error message and quit. Process the input file one logical record at a time; each record type has an initial type flag which is used by this procedure to determine which type of processing to apply. The information contained in each header type (except volume) is concatenated into a volume-inclusive table for each different type: six abbreviation dictionaries containing data format, comment description, cited source, generic abbreviation, units abbreviation, and beam configuration dictionaries (see Halbert et al.); a station header table containing complete information for each channel of each station; and a volume time span index.Tables: The structure of tables created by this process are described here. In all cases, -> and | represent links in a linked list and NULL indicates end-of-table. 1. Structure of the volume header list. volume id volume station header index volume time span index 2. Abbreviation dictionary tables. data format 1 -> ... -> last data format -> NULL comment description 1 -> ... -> last comment descrip -> NULL cited source 1 -> ... -> last cited source -> NULL generic abbreviation 1 -> ... -> last generic abbrev -> NULL units abbreviation 1 -> ... -> last units abbrev -> NULL beam configuration 1 -> ... -> last beam config -> NULL 3. Structure of the station table. station1 -> station2 -> ... -> last station -> NULL | | | information information information specific specific specific to to to station1 station2 last station An entry for an individual station is also a linked list; entries specific to a particular station are represented above by a phrase and are shown in detail below. generic station entry structure +++++++++++++++++++++++++++++++++++++++++++ | | |station comment 1 channels station update link | and or NULLstation comment 2 responses (See Note 1) | [to A] ... | .station comment N | . NULL . . . . . . . . . . [from A] | channel1 -> channel2 -> ... -> last channel -> NULL | | | information information information specific specific specific to to to channel1 channel2 last channel generic channel entry structure +++++++++++++++++++++++++++++++++++++++++++ | | | response 1 channel comment 1 channel update link | | or NULL response 2 channel comment 2 (See Note 2) | | ... ... | | last response last channel comment | | NULL NULL An alternative picture of the link structure described above is: station 1 --> station 2 --> ... --> last station --> NULL | | | | | +--> station update link --> ... --> last update --> NULL | | | +--> station comment 1 --> ... --> last comment --> NULL | +--> channel 1 --> channel 2 --> ... --> last channel --> NULL | | | | | +--> channel update link --> ... --> last update --> NULL | | | +--> channel comment 1 --> ... --> last comment --> NULL | +--> response 1 --> ... --> last response --> NULL where the link structure contained in all station entries is shown only for station 1, and the link structure contained in all channel entries is shown only for channel 1. 4. Structure of the time span index. time span 1 -> ... -> last time span -> NULL Notes: 1. Not implemented as of initial release date. 2. Not implemented as of initial release date. 3. This implementation has not been optimized for speed.Problems: see various subprocedures. "read", used in "rdseed.c" and "read_blockette.c", is not defined in the ANSI standard for C.References: Halbert, S. E., R. Buland, and C. R. Hutt (1988). Standard for the Exchange of Earthquake Data (SEED), Version V2.0, February 25, 1988. United States Geological Survey, Albuquerque Seismological Laboratory, Building 10002, Kirtland Air Force Base East, Albuquerque, New Mexico 87115. 82 pp.Language: C, hopefully to ANSI standard for portability.Author: Dennis O'NeillRevisions: 07/15/88 Dennis O'Neill Initial preliminary release 0.9 11/21/88 Dennis O'Neill changed option names; added -t option 11/21/88 Dennis O'Neill Production release 1.0 7/1/90 Allen Nance release 2.1 changes 6/11/93 Chris Laughbon added stderr loggingChanges needed in main and/or subprocs: get logical record length from volume header determine physical record length from volume or user input eliminate use of "memncpy" with direct references using pointers blockette length (see structures.h, rdseed.h, globals.h, read_blockette) should be dynamically allocated*/#define MAIN#include <stdlib.h>#include <ctype.h>#include <sys/types.h>#include <sys/stat.h>#include <sys/errno.h>#include <sys/param.h>#if 0#include <sys/ioctl.h>#include <sys/mtio.h>#endif#include <signal.h>#include "rdseed.h" /* rdseed headers */#include "version.h"#include "patchlevel.h"extern int errno;extern char *getenv(); /* define getenv system call */extern void init_error_file();extern int rdseed_alert;FILE *get_alt_file(); /* returns next alt response file */void init_alt_files(char *); /* Initialize alt response file usage */#define NUMARGS 3 /* min # of command line args */#define TAPE_DEVICE 0 /* used by check_block_mode */#define DISK_DEVICE -1 /* for readability */#define NO_NL(s) s[strlen(s) - 1] = 0/* function control flags, defined here for local subprocedure access */static int abbrev_flag = FALSE; /* abbreviation dict. flag */static int data_flag = FALSE; /* data recovery flag */static int stations_flag = FALSE; /* station info flag */static int contents_flag = FALSE; /* volume tbl of cnts flag */static int snoop_flag = FALSE; /* contents lister flag */static int times_flag = FALSE; /* start/stop times flag */static int event_flag = FALSE; /* output event info */static int ex_stn_flag = FALSE; /* extract station stuff */static char inputfilename[100]; /* name of input file */static int outputformat_flag = FALSE; /* output format defined */static int output_pipe = FALSE; /* output pipe defined */static int Volume_start;static int station_comments_flag;static int channel_comments_flag;char prevStn[6];char prevChn[4];char prevLoc[3];char prevNet[3];int strip_flag; /* strip out records with * zero for a sample count */int mini_flag = FALSE; /* make data only seed */int Seed_flag = FALSE; /* make new seed volume */int Output_PnZs = FALSE; /* write poles and Zeros */static int got_station = FALSE;static int from_weed = FALSE;int read_summary_flag = FALSE;int ignore_net_codes = FALSE; /* don't scan for network codes */int ignore_loc_codes = FALSE; /* ditto location codes */float WeedVersion;int EventDirFlag; /* whether to group output traces * in directories per event, as * found in the summary file */ char Rdseed_Cwd[MAXPATHLEN];char output_dir[MAXPATHLEN];void usage (); /* fcn to show usage *//* -------------------------------- Main ------------------------------ */main (argc, argv, evp)int argc;char *argv[];char *evp[];{ int i; /* counter */ int j; /* counter */ int eof_count; /* count of EOF marks found */ int opt_count; /* count of options found */ struct input_data_hdr *input_data_hdr; /* fixed data header */ char *input_data_ptr; struct optstruct *options; FILE *save_file; /* save place for input file */ char wrkstr[512]; strcpy(prevStn, ""); strcpy(prevLoc, ""); strcpy(prevNet, ""); strcpy(prevChn, ""); WeedVersion = 2.0; /* default */ EventDirFlag = FALSE; getcwd(Rdseed_Cwd, MAXPATHLEN); strcpy(output_dir, "./"); if (argc > 1) if (strcmp(argv[1], "FROM_WEED") == 0) { extern char *optarg; extern int optint; extern int opterr; int c; from_weed = TRUE; /* increment past the FROM_WEED arg */ argc--; argv++; while ((c = getopt(argc, argv, "v:")) != -1) switch(c) { case 'v' : WeedVersion = atof(optarg); break; default : fprintf(stderr, "Bad option scanned: %c\n", c); break; } /* return the arg now - getopt doesn't like it */ argc++; argv--; } /* set up the error file for stderr messages */ init_error_file();/* fprintf(stderr, "<< IRIS SEED Reader, Release %s.%1.1f >>\n", VERSION, PATCHLEVEL); */ /* no patchlevel */ fprintf(stderr, "<< IRIS SEED Reader, Release %s >>\n",VERSION);/* +=======================================+ *//*=================| Process command line, set flags |=================*//* +=======================================+ *//* - development - echo command line arguments *//* fprintf (stderr,"Command line was: \n"); fprintf (stderr,"argc = %d\n", argc); for (i = 0; i < argc; i++) fprintf (stderr,"item %d: %s\n", i, argv[i]);*/ /* options: a read abbreviations dictionaries c read volume table of contents l list contents (deterministic) s read station headers t list time segments (deterministic) d: recover data f: input filename o: output data format */begin: LRECL = 4096; /* start at 4096 until volume header has been read */ input_data_hdr = (struct input_data_hdr *) input.data; input_data_ptr = input.data; outputfile = stdout; output_pipe = FALSE; volume_number = 1; station_count = 0; channel_count = 0; network_count = 0; location_count = 0; start_time_count = 0; end_time_count = 0; seis_buffer_length = MAX_DATA_LENGTH; strcpy(inputfilename,"/dev/nrst0"); outresp_old_flag = FALSE; outresp_flag = FALSE; output_flag = FALSE; output_format = 0; check_reverse = 0; q_flag = 'E'; opt_count = 0; abbrev_flag = FALSE; contents_flag = FALSE; snoop_flag = FALSE; stations_flag = FALSE; times_flag = FALSE; strip_flag = FALSE; station_comments_flag = channel_comments_flag = FALSE; /* set flags to false in process_stnh() */ reset_stn_chn_flags(); Volume_start = 0; strcpy(channel_list, ""); strcpy(station_list, ""); mini_flag = data_flag = Seed_flag = read_summary_flag = FALSE; outputformat_flag = FALSE; event_flag = FALSE; ex_stn_flag = FALSE; Output_PnZs = FALSE; EventDirFlag = FALSE; got_station = FALSE; ignore_net_codes = FALSE; ignore_loc_codes = FALSE; /* read in alias strings */ get_environment(); if (!from_weed) if ((options = cmdlineproc (argc, argv, "iacklprRsStdeug:z:o:f:v:x:C:q:Q:b:")) != NULL) { for (i = 0; i < options->number_options; i++) { if (!options->option_present[i]) continue; opt_count++; parse_option(options->option[i], options->argument[i]); } if (output_format == 4) /* Seed output */ { /* removes files perhaps left behind */ clean_up_output_seed(); Seed_flag = TRUE; /* set for new seed */ } } if (opt_count == 0) option_prompt(); if (data_flag||mini_flag) if ((seismic_data = (float *) malloc((seis_buffer_length+000)*4)) == NULL) { fprintf (stderr, "\tERROR - Data Buffer too large\n"); exit(1); } if ((inputfile = fopen(inputfilename, "r")) == NULL) { fprintf (stderr, "\tERROR (rdseed): "); fprintf (stderr, "Input file %s unavailable for reading.\n", inputfilename); perror(argv[0]); fprintf (stderr, "\tExecution terminated.\n"); exit (-1); } /* determine type of file character or block */ input_file_type = check_block_mode(inputfilename); if (data_flag||mini_flag) {/* if (options->next_arg == 0) numitems = 0; else for (i = options->next_arg-1, j = 0; i < argc; i++, j++) { item[j] = argv[i]; numitems = j+1; }*/ if (!input_file_type) printf("WARNING - Input Device is Character Type - Processing will be SEQUENTIAL\n"); if (station_volume&&input_file_type) printf("WARNING - Volume Type is Station - Processing will be SEQUENTIAL\n");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -