1 | |
---|
2 | /* file residual.c |
---|
3 | * ========== |
---|
4 | * |
---|
5 | * version 4, 22-May-2006 |
---|
6 | * |
---|
7 | * Reading interpolated residual times from residual tables. |
---|
8 | * K. Stammler, 3-Feb-2001 |
---|
9 | */ |
---|
10 | |
---|
11 | |
---|
12 | /* |
---|
13 | * |
---|
14 | * SeismicHandler, seismic analysis software |
---|
15 | * Copyright (C) 1992, Klaus Stammler, Federal Institute for Geosciences |
---|
16 | * and Natural Resources (BGR), Germany |
---|
17 | * |
---|
18 | * This program is free software; you can redistribute it and/or modify |
---|
19 | * it under the terms of the GNU General Public License as published by |
---|
20 | * the Free Software Foundation; either version 2 of the License, or |
---|
21 | * (at your option) any later version. |
---|
22 | * |
---|
23 | * This program is distributed in the hope that it will be useful, |
---|
24 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
25 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
26 | * GNU General Public License for more details. |
---|
27 | * |
---|
28 | * You should have received a copy of the GNU General Public License |
---|
29 | * along with this program; if not, write to the Free Software |
---|
30 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
---|
31 | * |
---|
32 | */ |
---|
33 | |
---|
34 | |
---|
35 | #include <stdio.h> |
---|
36 | #include <string.h> |
---|
37 | #include "basecnst.h" |
---|
38 | #ifdef BC_INC_STDLIB |
---|
39 | #include BC_INC_STDLIB |
---|
40 | #endif |
---|
41 | #include "sysbase.h" |
---|
42 | #include "erusrdef.h" |
---|
43 | #include "utusrdef.h" |
---|
44 | #include "residual.h" |
---|
45 | |
---|
46 | |
---|
47 | |
---|
48 | /* global variables */ |
---|
49 | TRsTable *vrs_roottable=NULL; /* pointer to root table */ |
---|
50 | |
---|
51 | |
---|
52 | /* prototypes of local routines */ |
---|
53 | static void RsEnlistTable( TRsTable *tab ); |
---|
54 | static void RsDumpTable( TRsTable *tab ); |
---|
55 | |
---|
56 | |
---|
57 | |
---|
58 | /*----------------------------------------------------------------------------*/ |
---|
59 | |
---|
60 | |
---|
61 | |
---|
62 | void RsReadTables( char fname[], TSyStatus *status ) |
---|
63 | |
---|
64 | /* Read in residual tables from file |
---|
65 | * |
---|
66 | * parameters of routine |
---|
67 | * char file[]; input; filename |
---|
68 | * STATUS *status; output; return status |
---|
69 | */ |
---|
70 | { |
---|
71 | /* local variables */ |
---|
72 | char locname[cBcFileLth+1]; /* local file name */ |
---|
73 | char *env; /* pointer to environment variable */ |
---|
74 | FILE *fp; /* pointer to input file */ |
---|
75 | char line[cBcLineLth+1]; /* current line of file */ |
---|
76 | char tmpstr[cBcLineLth+1];/* scratch string */ |
---|
77 | TRsTable *curtab; /* pointer to current table */ |
---|
78 | int i; /* counter */ |
---|
79 | |
---|
80 | /* executable code */ |
---|
81 | |
---|
82 | /* generate filename if not given */ |
---|
83 | if (*fname == '\0' || strcmp(fname,"default") == 0) { |
---|
84 | env = (char *)getenv( "SH_INPUTS" ); |
---|
85 | if ((strlen(env)+strlen(cRsDefaultName)) > cBcFileLth) { |
---|
86 | *status = eRsLongFilename; |
---|
87 | return; |
---|
88 | } /*endif*/ |
---|
89 | strcpy( locname, env ); |
---|
90 | strcat( locname, cRsDefaultName ); |
---|
91 | } else { |
---|
92 | if (strlen(fname) > cBcFileLth) { |
---|
93 | *status = eRsLongFilename; |
---|
94 | return; |
---|
95 | } /*endif*/ |
---|
96 | strcpy( locname, fname ); |
---|
97 | } /*endif*/ |
---|
98 | |
---|
99 | /* open file */ |
---|
100 | fp = fopen( locname, "r" ); |
---|
101 | if (fp == NULL) { |
---|
102 | *status = eRsFileNotFound; |
---|
103 | return; |
---|
104 | } /*endif*/ |
---|
105 | |
---|
106 | /* read through file */ |
---|
107 | curtab = NULL; |
---|
108 | while (fgets(line,cBcLineLth,fp) != NULL) { |
---|
109 | |
---|
110 | /* ignore comment and empty lines */ |
---|
111 | if (*line == '!') continue; |
---|
112 | if (*line == '\n') continue; |
---|
113 | |
---|
114 | /* create new table on station */ |
---|
115 | if (strncmp(line,"station:",8) == 0) { |
---|
116 | if (curtab != NULL) { |
---|
117 | *status = eRsTableNotClosed; |
---|
118 | sy_deallocmem( curtab ); |
---|
119 | return; |
---|
120 | } /*endif*/ |
---|
121 | /* create new table */ |
---|
122 | curtab = (TRsTable *)sy_allocmem( 1, sizeof(TRsTable), status ); |
---|
123 | if (SySevere(status)) return; |
---|
124 | RsInitTable( curtab ); |
---|
125 | sscanf( line, "station: %s\n", tmpstr ); |
---|
126 | if (strlen(tmpstr) > cRsStationLth) { |
---|
127 | *status = eRsLongName; |
---|
128 | return; |
---|
129 | } /*endif*/ |
---|
130 | ut_cap( tmpstr ); |
---|
131 | strcpy( curtab->station, tmpstr ); |
---|
132 | } /*endif*/ |
---|
133 | |
---|
134 | /* read phase list */ |
---|
135 | if (strncmp(line,"phases:",7) == 0) { |
---|
136 | if (curtab == NULL) { |
---|
137 | *status = eRsSyntaxError; |
---|
138 | return; |
---|
139 | } /*endif*/ |
---|
140 | sscanf( line, "phases: %s\n", tmpstr ); |
---|
141 | if (strlen(tmpstr) > cRsPhaseListLth-2) { |
---|
142 | *status = eRsLongPhaseList; |
---|
143 | return; |
---|
144 | } /*endif*/ |
---|
145 | curtab->phases[0] = ','; |
---|
146 | strcpy( curtab->phases+1, tmpstr ); |
---|
147 | strcat( curtab->phases, "," ); |
---|
148 | } /*endif*/ |
---|
149 | |
---|
150 | /* read slowness range */ |
---|
151 | if (strncmp(line,"slowness:",9) == 0) { |
---|
152 | if (curtab == NULL) { |
---|
153 | *status = eRsSyntaxError; |
---|
154 | return; |
---|
155 | } /*endif*/ |
---|
156 | if (sscanf(line,"slowness:%f\n-%f\n", |
---|
157 | &(curtab->minslow),&(curtab->maxslow)) != 2) { |
---|
158 | *status = eRsReadSlowness; |
---|
159 | return; |
---|
160 | } /*endif*/ |
---|
161 | } /*endif*/ |
---|
162 | |
---|
163 | /* read length, azim & resid */ |
---|
164 | if (strncmp(line,"entries:",8) == 0) { |
---|
165 | if (curtab == NULL) { |
---|
166 | *status = eRsSyntaxError; |
---|
167 | return; |
---|
168 | } /*endif*/ |
---|
169 | if (sscanf(line,"entries:%d\n",&(curtab->tablth)) != 1) { |
---|
170 | *status = eRsReadTablth; |
---|
171 | return; |
---|
172 | } /*endif*/ |
---|
173 | fscanf( fp, "%s", tmpstr ); |
---|
174 | if (strcmp(tmpstr,"azim:") != 0) { |
---|
175 | *status = eRsSyntaxError; |
---|
176 | err_setcontext( " ## 'entries' must be followed by 'azim' " ); |
---|
177 | } /*endif*/ |
---|
178 | curtab->azim = (float *)sy_allocmem( |
---|
179 | curtab->tablth, (int)sizeof(float), status ); |
---|
180 | if (SySevere(status)) return; |
---|
181 | for (i=0; i<(curtab->tablth); i++) { |
---|
182 | if (fscanf(fp,"%f\n",(curtab->azim)+i) != 1) { |
---|
183 | *status = eRsSyntaxError; |
---|
184 | err_setcontext( " ## reading azim list " ); |
---|
185 | return; |
---|
186 | } /*endif*/ |
---|
187 | } /*endfor*/ |
---|
188 | fscanf( fp, "%s", tmpstr ); |
---|
189 | if (strcmp(tmpstr,"resid:") != 0) { |
---|
190 | *status = eRsSyntaxError; |
---|
191 | err_setcontext( " ## 'azim' must be followed by 'resid' " ); |
---|
192 | } /*endif*/ |
---|
193 | curtab->resid = (float *)sy_allocmem( |
---|
194 | curtab->tablth, (int)sizeof(float), status ); |
---|
195 | if (SySevere(status)) return; |
---|
196 | for (i=0; i<(curtab->tablth); i++) { |
---|
197 | if (fscanf(fp,"%f\n",(curtab->resid)+i) != 1) { |
---|
198 | *status = eRsSyntaxError; |
---|
199 | err_setcontext( " ## reading resid list " ); |
---|
200 | return; |
---|
201 | } /*endif*/ |
---|
202 | } /*endfor*/ |
---|
203 | } /*endif*/ |
---|
204 | |
---|
205 | /* insert table when finished */ |
---|
206 | if (strncmp(line,"end",3) == 0) { |
---|
207 | /* check for completeness */ |
---|
208 | if (curtab == NULL) {*status = eRsIncompleteTable; return;} |
---|
209 | if (curtab->station[0] == '\0') |
---|
210 | {*status = eRsIncompleteTable; err_setcontext("station"); return;} |
---|
211 | if (curtab->phases[0] == '\0') |
---|
212 | {*status = eRsIncompleteTable; err_setcontext("phases"); return;} |
---|
213 | if (curtab->minslow < 0.0) |
---|
214 | {*status = eRsIncompleteTable; err_setcontext("minslow"); return;} |
---|
215 | if (curtab->maxslow < 0.0) |
---|
216 | {*status = eRsIncompleteTable; err_setcontext("maxslow"); return;} |
---|
217 | if (curtab->tablth <= 0) |
---|
218 | {*status = eRsIncompleteTable; err_setcontext("tablth"); return;} |
---|
219 | if (curtab->azim == NULL) |
---|
220 | {*status = eRsIncompleteTable; err_setcontext("azim"); return;} |
---|
221 | if (curtab->resid == NULL) |
---|
222 | {*status = eRsIncompleteTable; err_setcontext("resid"); return;} |
---|
223 | RsEnlistTable( curtab ); |
---|
224 | curtab = NULL; |
---|
225 | } /*endif*/ |
---|
226 | |
---|
227 | } /*endwhile*/ |
---|
228 | |
---|
229 | if (curtab != NULL) { |
---|
230 | *status = eRsIncompleteTable; |
---|
231 | err_setcontext( curtab->station ); |
---|
232 | sy_deallocmem( curtab ); |
---|
233 | return; |
---|
234 | } /*endif*/ |
---|
235 | |
---|
236 | fclose( fp ); |
---|
237 | |
---|
238 | } /* end of RsReadTables */ |
---|
239 | |
---|
240 | |
---|
241 | |
---|
242 | /*----------------------------------------------------------------------------*/ |
---|
243 | |
---|
244 | |
---|
245 | |
---|
246 | void RsInitTable( TRsTable *tab ) |
---|
247 | |
---|
248 | /* initializes table |
---|
249 | * |
---|
250 | * parameters of routine |
---|
251 | * TRsTable *tab; output; table to initialize |
---|
252 | */ |
---|
253 | { |
---|
254 | /* executable code */ |
---|
255 | |
---|
256 | tab->station[0] = '\0'; |
---|
257 | tab->minslow = cRsEmptySlowness; |
---|
258 | tab->maxslow = cRsEmptySlowness; |
---|
259 | tab->tablth = 0; |
---|
260 | tab->azim = NULL; |
---|
261 | tab->resid = NULL; |
---|
262 | tab->next = NULL; |
---|
263 | |
---|
264 | } /* end of RsInitTable */ |
---|
265 | |
---|
266 | |
---|
267 | |
---|
268 | /*----------------------------------------------------------------------------*/ |
---|
269 | |
---|
270 | |
---|
271 | |
---|
272 | void RsDumpTables( void ) |
---|
273 | |
---|
274 | /* Dumps all tables to stdout |
---|
275 | * |
---|
276 | * no parameters |
---|
277 | */ |
---|
278 | { |
---|
279 | /* local variables */ |
---|
280 | TRsTable *t; /* moving pointer */ |
---|
281 | |
---|
282 | /* executable code */ |
---|
283 | |
---|
284 | printf( "\nResidual Table List Dump\n\n" ); |
---|
285 | |
---|
286 | t = vrs_roottable; |
---|
287 | while (t != NULL) { |
---|
288 | RsDumpTable( t ); |
---|
289 | t = t->next; |
---|
290 | } /*endwhile*/ |
---|
291 | |
---|
292 | printf( "\n\n" ); |
---|
293 | |
---|
294 | } /* end of RsDumpTables */ |
---|
295 | |
---|
296 | |
---|
297 | |
---|
298 | /*----------------------------------------------------------------------------*/ |
---|
299 | |
---|
300 | |
---|
301 | |
---|
302 | float RsResidual( char station[], char phase[], float slowness, float azimuth, |
---|
303 | TSyStatus *status ) |
---|
304 | |
---|
305 | /* Returns residual time in s for given station, phase, slowness and |
---|
306 | * back-azimuth |
---|
307 | * |
---|
308 | * parameters of routine |
---|
309 | * char station[]; input; station name |
---|
310 | * char phase[]; input; phase name |
---|
311 | * float slowness; input; slowness in s/deg |
---|
312 | * float azimuth; input; back-azimuth n deg |
---|
313 | * TSyStatus status; output; return status |
---|
314 | */ |
---|
315 | { |
---|
316 | /* local variables */ |
---|
317 | char locstat[cRsStationLth+1]; /* local station name */ |
---|
318 | TRsTable *t; /* matching table */ |
---|
319 | TSyBoolean found; /* found right table */ |
---|
320 | int i; /* index */ |
---|
321 | float resid; /* interpolated residual */ |
---|
322 | char pstr[cRsPhaseListLth+1]; /* search string */ |
---|
323 | |
---|
324 | /* executable code */ |
---|
325 | |
---|
326 | /* create phase search string with commas */ |
---|
327 | *pstr = ','; |
---|
328 | strcpy( pstr+1, phase ); |
---|
329 | strcat( pstr, "," ); |
---|
330 | |
---|
331 | /* create uppercase station name */ |
---|
332 | if (strlen(station) > cRsStationLth) { |
---|
333 | *status = eRsLongName; |
---|
334 | return; |
---|
335 | } /*endif*/ |
---|
336 | strcpy( locstat, station ); |
---|
337 | ut_cap( locstat ); |
---|
338 | |
---|
339 | /* find matching table */ |
---|
340 | t = vrs_roottable; |
---|
341 | while (t != NULL) { |
---|
342 | found = TRUE; |
---|
343 | if (strcmp(t->station,locstat) != 0) found = FALSE; |
---|
344 | if (strstr(t->phases,pstr) == NULL) found = FALSE; |
---|
345 | if (slowness < t->minslow) found = FALSE; |
---|
346 | if (slowness >= t->maxslow) found = FALSE; |
---|
347 | if (found) break; |
---|
348 | t = t->next; |
---|
349 | } /*endwhile*/ |
---|
350 | |
---|
351 | if (t == NULL) { |
---|
352 | *status = eRsNoTableFound; |
---|
353 | err_setcontext( " ## station: " ); |
---|
354 | err_setcontext( locstat ); |
---|
355 | err_setcontext( " phase: " ); |
---|
356 | err_setcontext( phase ); |
---|
357 | err_setcontext( " slowness: " ); |
---|
358 | err_setcontext_r( slowness ); |
---|
359 | return 0.0; |
---|
360 | } /*endif*/ |
---|
361 | |
---|
362 | /* |
---|
363 | printf( "\nfound table:\n" ); |
---|
364 | RsDumpTable( t ); |
---|
365 | */ |
---|
366 | |
---|
367 | if (azimuth < t->azim[0] || azimuth > t->azim[(t->tablth)-1]) { |
---|
368 | *status = eRsAzimOutOfRange; |
---|
369 | err_setcontext( " ## station: " ); |
---|
370 | err_setcontext( locstat ); |
---|
371 | err_setcontext( " slowness: " ); |
---|
372 | err_setcontext_r( slowness ); |
---|
373 | err_setcontext( " azimuth: " ); |
---|
374 | err_setcontext_r( azimuth ); |
---|
375 | return 0.0; |
---|
376 | } /*endif*/ |
---|
377 | |
---|
378 | i = 1; |
---|
379 | while (t->azim[i] < azimuth) { |
---|
380 | i++; |
---|
381 | if (i >= t->tablth) { |
---|
382 | *status = eRsProgramBug; |
---|
383 | err_setcontext( " ## find azimuth index" ); |
---|
384 | return; |
---|
385 | } /*endif*/ |
---|
386 | } /*endwhile*/ |
---|
387 | |
---|
388 | /* |
---|
389 | printf( "azimuth %5.1f is between %5.1f and %5.1f\n", |
---|
390 | azimuth, t->azim[i-1], t->azim[i] ); |
---|
391 | */ |
---|
392 | |
---|
393 | resid = t->resid[i-1] + (azimuth - t->azim[i-1]) |
---|
394 | * ((t->resid[i] - t->resid[i-1]) / (t->azim[i] - t->azim[i-1])); |
---|
395 | |
---|
396 | return resid; |
---|
397 | |
---|
398 | } /* end of RsResidual */ |
---|
399 | |
---|
400 | |
---|
401 | |
---|
402 | /*----------------------------------------------------------------------------*/ |
---|
403 | |
---|
404 | |
---|
405 | |
---|
406 | static void RsEnlistTable( TRsTable *tab ) |
---|
407 | |
---|
408 | /* Appends table to the table list |
---|
409 | * |
---|
410 | * parameters of routine |
---|
411 | * TRsTable *tab; input; table to append |
---|
412 | */ |
---|
413 | { |
---|
414 | /* local variables */ |
---|
415 | TRsTable *t; /* moving pointer */ |
---|
416 | |
---|
417 | /* executable code */ |
---|
418 | |
---|
419 | if (vrs_roottable == NULL) { |
---|
420 | vrs_roottable = tab; |
---|
421 | return; |
---|
422 | } /*endif*/ |
---|
423 | |
---|
424 | t = vrs_roottable; |
---|
425 | while (t->next != NULL) |
---|
426 | t = t->next; |
---|
427 | |
---|
428 | t->next = tab; |
---|
429 | |
---|
430 | } /* end of RsEnlistTable */ |
---|
431 | |
---|
432 | |
---|
433 | |
---|
434 | /*----------------------------------------------------------------------------*/ |
---|
435 | |
---|
436 | |
---|
437 | |
---|
438 | static void RsDumpTable( TRsTable *tab ) |
---|
439 | |
---|
440 | /* Dumps residual table to stdout |
---|
441 | * |
---|
442 | * parameters of routine |
---|
443 | * TRsTable *tab; input; table to dump |
---|
444 | */ |
---|
445 | { |
---|
446 | /* local varaibles */ |
---|
447 | int i; /* counter */ |
---|
448 | |
---|
449 | /* executable code */ |
---|
450 | |
---|
451 | if (tab == NULL) { |
---|
452 | printf( "table == NULL\n" ); |
---|
453 | return; |
---|
454 | } /*endif*/ |
---|
455 | |
---|
456 | printf( "station: >%s<\n", tab->station ); |
---|
457 | printf( "phases: %s\n", tab->phases ); |
---|
458 | printf( "slowness: %4.2f - %4.2f\n", tab->minslow, tab->maxslow ); |
---|
459 | printf( "entries: %d\n", tab->tablth ); |
---|
460 | printf( "azim: " ); |
---|
461 | for (i=0; i<(tab->tablth); i++) |
---|
462 | printf( "%5.1f ", tab->azim[i] ); |
---|
463 | printf( "\n" ); |
---|
464 | printf( "resid: " ); |
---|
465 | for (i=0; i<(tab->tablth); i++) |
---|
466 | printf( "%5.2f ", tab->resid[i] ); |
---|
467 | printf( "\n\n" ); |
---|
468 | |
---|
469 | } /* RsDumpTable */ |
---|
470 | |
---|
471 | |
---|
472 | |
---|
473 | /*----------------------------------------------------------------------------*/ |
---|
474 | |
---|