📄 find_segment.c
字号:
/* ================================================================*//* DMC Interim out | find_segment.c | Scan_phase *//*=================================================================*//*Name: find_segment.c Purpose:to find the next continuous series of data records each of which lies in whole or in part within the given time spanUsage: int find_segment () char *filename; FILE * fptr; struct input_time *start; struct input_time *end; int n; struct input_time *fend; int flen; struct input_time *end_tspan; struct input_scan *scan; int *start_o; int *end_o; int ret; err = find_segment(fptr,start,end,n,fend,flen,scan,start_o,end_o)Input: FILE * fptr open file struct input_time *start ptr->window start time struct input_time *end ptr->window end time int n number of time segments in file struct input_time *fend file end time int flen file length in bytes struct input_time *end_tspan; time of end of current tspanOutput: struct input_scan *scan ptr->data hdr of found time segment int *start_o ptr->fseek offset to start of data int *end_o ptr->fseek offset to end of data + 1 int find_segment ()=0 time segment found =1 last time segment found =2 eof detected before time segment found =3 read errorExternals:Debug - setting of environment variable DEBUG (globals.h)Messages: Warnings: Errors: Fatals: Called by: Calls to:cmp_time compares two times in struct input_time fmt add_time adds e-04 sec to time in struct input_time fmt get_scaninfo get subset of data hdr info and data start/endAlgorithm:Read records from open file until requested start time found. Then, continue reading records until the requested end time is reached OR until a time discontinuity is reached OR until eof is reached OR, if the requested end time extends beyond the end time of the file, until the balance of the file consists of only one continuous time segment. Return file pointers and header info describing the time segment.Notes: Assumes archive data record length = LreclProblems:Segment counter (segcnt) does not properly count segments which precede the requested time window so will only quit at eof or at the end of the requested time window (whichever comes first). If the data file contains more tears in the time series than documented (illegal but does occur), this routine will count up to the documented number and quit, lumping all remaining data (tears and all) in the last segment. Assumes all data record headers in 680xx-compatible byte order. Precision of timing (time tears) set to an ad-hoc value, but should really be taken directly from field 19 of blockette 052.Debug: level D_MIN - print out start and finish notices level D_MED - position of data record relative to time window level D_MAX - start and end times of data recordsReferences: noneLanguage:ANSI standard C, under Sun OS 3.5Revisions:03/06/89 Kevin MacKenzie original version 10jul90 mw bugfix: pass the end of current timespan time to get_scaninfo to provide the end time for zero sample interval channels. 20nov90 mw mod - pass endtime back to caller for seed v2.1 for blockette 074s 28dec90 mw change no data for this record from WARN to INFO change number of chars in station,chan to 5,3 xxyyy91 ss bugfix (sue shoch) 03sep91 mw increase size of msg, yet again! was 151, now 351 11feb92 mw bugfix The end time for a segment was being returned as the end time of the record past the proper end. This only showed up in v2.1 or greater SEED in the blockette 074's. This was fixed. mw change Since the segment is *always* ignored, I removed the code which could return if the segment count was exhausted. This has not been in use for quite some time, and it added a bit of complexity. segcnt was global, and it should not have been. 05/16/95 CL - added network code to scan.location - 3.0*/ /*=====================================*//*=================| |=================*/ /*=====================================*/#include "output.h"#define BOOL int#define TRIM_STR(s)\{\ char *ch_ptr;\ while((ch_ptr = strchr(s, ' ')) != NULL)\ *ch_ptr = 0;\}extern float User_tolerance;extern int Process_location_code;/* ------------------------------------------------------------------ *//* the following definitions provide private storage over multiple entries */static char buf[8196];static int save_o = -1; /* start offset pointer */ /* = -1, no segment found */ /* >= 0, start of segment */static struct input_scan save_scan; /* segment hdr scan info */static int file_o = 0; /* file offset pointer */static struct input_time est_rec_start; /* estim. start time of next rec */static struct input_time save_endtime; /* saved end time */static int segcnt = 0; /* segment count */ static int msg_printed = 0;/* ------------------------------------------------------------------------- */int find_segment (filename, fptr, start, end, n, fend, flen, end_tspan, scan, endtime, start_o, end_o)char *filename; /* filename - for err msgs */FILE *fptr; /* open file pointer */struct input_time *start; /* ptr->window start time */struct input_time *end; /* ptr->window end time */int n; /* number of segments in file */struct input_time *fend; /* ptr->file end time */int flen; /* length of file in bytes */struct input_time *end_tspan; /* ptr->end of current timespan */struct input_scan *scan; /* ptr->data hdr of found time segment*/struct input_time *endtime; /* ptr->data end time */int *start_o; /* ptr->fseek offset to start of data */int *end_o; /* ptr->fseek offset to end of data+1 */{ int len; /* length of buffer returned by read */ struct input_scan rec_scan; /* data hdr scan info of data record */ struct input_time rec_start; /* start time of data record */ struct input_time rec_end; /* end time of data record */ long interval; /* data sample interval,e-04 sec/samp */ long precision; /* time comparison precision, e-04 sec*/ int err = -1; /* result */ int result; /* */ char msg[351]; /* info */ struct input_data_logrec *rec; /* log rec header + data rec header *//* * the code to handle non-zero segment counts was removed, so * make sure it can't happen. */ if( n != 0 ) error_handler( FATAL, "[find_segment] called with non-zero segment count" ); if (Debug >= D_MIN) fprintf (D_OUT, "[find_segment] Started.\n"); if (Debug >= D_MAX) print_time ("[find_segment] window start=",start); if (Debug >= D_MAX) print_time ("[find_segment] window end=",end); if (Debug >= D_MED && save_o >0) fprintf (D_OUT, "[find_segment] Start of segment at offset = %d\n",save_o); rec = (struct input_data_logrec *)buf; /* if file_o os non-zero, we encounter a break in data on a * previous scan, so don't scan for start segment, use the * file_o as starting point. file_o gets set to 0 if all the * data was scanned, see bottom */ if (file_o == 0) file_o = ftell(fptr); while (err < 0 && ((len = fread (buf, 1, (unsigned int) Lrecl, fptr)) > 0)) { if (Debug >= D_MAX) fprintf (D_OUT, "[find_segment] read bytes = %d -> %d\n",file_o,file_o + len -1); if (rec->hdr.full.nsamples == 0) { /* simply accept this block, no data but blockettes? */ continue; } get_scaninfo (buf, end_tspan, &rec_scan, &rec_start, &rec_end, &interval, filename); if (Debug >= D_MAX) print_time ("[find_segment] rec_start=",&rec_start); if (Debug >= D_MAX) print_time ("[find_segment] rec_end=\t",&rec_end); if (User_tolerance != 1) precision = User_tolerance; else /* = 20% samp int or 20 msec */ precision = min (200, (interval / 5)); /* if LOG record - check to see if start of record * lies btw a request span */ if ((strncasecmp(rec_scan.channel, "LOG", 3) == 0) || (rec->hdr.full.nsamples == 0)) { /* have we scanned a valid record */ if (save_o < 0) { /* save_o < 0 means still scanning */ /* check to see that starting record falls * btw req start/end times */ if (((cmp_time (rec_start, *start, precision)) >= 0) && ((cmp_time (rec_start, *end, precision)) <= 0)) { save_o = file_o; /* save file offset of start */ save_scan = rec_scan; /* save hdr info*/ segcnt++; } } else { if ((cmp_time (rec_start, *end, precision)) > 0) { /* ends at end of requested time window */ *end_o = file_o; err = 1; } segcnt++; save_endtime = rec_start; } file_o += len; /* increment file offset memory */ continue; } if (save_o < 0) { /* find the start of the next time segment */ if( Debug >= D_MAX ) fprintf( D_OUT, "[find_segment] look for start\n" ); if (cmp_time (rec_end, *start, precision) < 0) { /* record precedes start of time window */ if( Debug >= D_MAX ) fprintf( D_OUT, "[find_segment] record end < request start\n" ); if (file_o > 0 && cmp_time (est_rec_start, rec_start, precision) != 0) { segcnt++;/* count segments anyway */ } } else if ((cmp_time (rec_start, *end, precision)) <= 0) { /* start a new time segment */ if( Debug >= D_MAX ) fprintf( D_OUT, "[find_segment] record start < request end\n" ); save_o = file_o; /* save file offset of start */ save_scan = rec_scan; /* save hdr info*/ save_endtime = rec_end; segcnt++; if (Debug >= D_MED) fprintf (D_OUT, "[find_segment] Start of segment at offset = %d\n",save_o); } else { /* err = 2; */ /* record beyond end of time window */ if( Debug >= D_MAX ) fprintf( D_OUT, "[find_segment] record start > request end\n" ); } } else /* if save_o */ { /* find the end of the time segment */ if( Debug >= D_MAX ) fprintf( D_OUT, "[find_segment] look for end\n" ); if ((cmp_time (rec_start, *end, precision)) > 0) { /* ends at end of requested time window */ *end_o = file_o; err = 1; if( Debug >= D_MAX ) fprintf( D_OUT, "[find_segment] record start > request end\n" ); } else if (cmp_time (est_rec_start, rec_start, precision) != 0) { /* ends at data time discontinuity */ *end_o = file_o; err = 0; if( Debug >= D_MAX ) fprintf( D_OUT, "[find_segment] discontinuity found\n" ); } else { save_endtime = rec_end; /* no special case, read next */ } } est_rec_start = add_time (rec_end, interval); file_o += len; /* increment file offset memory */ } /* while more data *//* * Our story so far: err has been set to * -1 end of file * 0 time discontinuity found before this record * 1 this record is > end time, but some data was in window * 2 this record is > end time, and no data in window */ if( Debug >= D_MAX ) fprintf( D_OUT, "[find_segment] len read = %d\n",len ); if (len < 0) { err = 3; /* read error */ sprintf( msg, "[find_segment] read error on file %s", filename ); (void)error_handler( ERROR,msg ); } else if (save_o < 0) { /* no time segment found */ err = 2; if (Debug >= D_MED) fprintf (D_OUT, "[find_segment] save_o = %d start_o = %d end_o = %d\n", save_o, *start_o, *end_o);/* * do it this way cuz input_time_to_asc is static and is overwritten * during a printf call */ sprintf( msg, "[find_segment] No data in request window:\tfile %s\t", filename ); strcat( msg, input_time_to_asc(*start) ); strcat( msg, " to " ); strcat( msg, input_time_to_asc(*end) ); error_handler( INFO, msg ); if (Debug >= D_MED) fprintf (D_OUT,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -