Waveform filter programs
stufi.f
Go to the documentation of this file.
1 c this is <stufi.f> by Thomas Forbriger 1996
2 c
3 c this is a special version of SEIFE by E. Wielandt
4 c for input and output fo sff format files
5 c
6 c Copyright 1996, 2010 by Thomas Forbriger
7 c
8 c ----
9 c STUFI is free software; you can redistribute it and/or modify
10 c it under the terms of the GNU General Public License as published by
11 c the Free Software Foundation; either version 2 of the License, or
12 c (at your option) any later version.
13 c
14 c This program is distributed in the hope that it will be useful,
15 c but WITHOUT ANY WARRANTY; without even the implied warranty of
16 c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 c GNU General Public License for more details.
18 c
19 c You should have received a copy of the GNU General Public License
20 c along with this program; if not, write to the Free Software
21 c Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 c ----
23 c
24 c (sff is the Stuttgart File Format as defined in sff.doc)
25 c
26 c REVISIONS and CHANGES
27 c V1.0 11/11/96 first running version
28 c V1.1 13/12/96 set correct file status on open action
29 c V1.2 14/12/96 - added overwrite option
30 c - and fixed some decleration bugs (not serious)
31 c - fixed trace number output decimals
32 c - fixed more traces estimation when not using selection
33 c V1.3 21/01/97 correct array-dimension to sff_RData in libstuff V1.07
34 c V1.4 10/02/97 changed line splitting for seife commands
35 c V1.5 15/07/98 * give usage information only without arguments
36 c * introduced verbose mode
37 c V1.6 21/02/99 changed tflib calls to tf_
38 c V1.7 09/02/00 allow longer path names
39 c V1.8 15/04/05 catch sample rates that do not fit on the output format
40 c V1.9 08/10/10 code relied on Fortran to initialize variables
41 c
42 c======================================================================
43  program stufi
44  character*77 version, creator
45  parameter(version=
46  & 'STUFI V1.9 E. Wielandts filter routines for sff files')
47  parameter(creator='1996 by Thomas Forbriger (IfG Stuttgart)')
48 c dimensions
49  integer maxcontrol, maxsamples, maxfree, maxselect
50  parameter(maxcontrol=50, maxsamples=500000, maxfree=400)
51  parameter(maxselect=200)
52  character*200 junkfile
53  parameter(junkfile='stufijunkforreplace')
54 c common definitions
55  integer filep,trace,i,j
56  character*200 line
57  logical debug
58 c control file
59  character*200 command(maxcontrol)
60  integer ncommand
61 c sff specific
62  character*20 code, outcode
63  integer sffversion, ierr, nfilefree, ntracefree,flmax
64  character*13 timestamp
65  character*80 filefree(maxfree), tracefree(maxfree)
66  character*200 infile
67  character*132 wid2line
68  character soutyp*20, soucs*1, soudate*6, soutime*10
69  real souc1, souc2, souc3, tanf, ampfac
70  double precision srat
71  integer idata(maxsamples)
72  logical moretraces, expectmoretraces
73  integer hour, minute
74  real second
75  real tracec1, tracec2, tracec3
76  character tracecs*1
77  integer tracenstack
78 c using selections
79  logical useselect
80  logical selection(maxselect)
81 c commandline
82  integer maxopt, lastarg, iargc
83  parameter(maxopt=6)
84  character*2 optid(maxopt)
85  character*80 optarg(maxopt)
86  logical optset(maxopt), opthasarg(maxopt)
87  character*20 extension
88  character*80 outfile, controlfile
89  logical setext, replace, newfile, overwrite, verbose
90 c seife-sepcific variables
91  double precision x(maxsamples)
92  character typ*3, par*80, msg*79
93  integer nsamples
94  real dt, tmin, tsec
95 c here are the keys to our commandline options
96  data optid/2h-e,2h-r,2h-t,2h-d,2h-o,2h-v/
97  data opthasarg/.true.,.false.,.true.,3*.false./
98  data optarg/4h.sfi,1h-,4hjunk,3*1h-/
99 
100 c----------------------------------------------------------------------
101 c
102 c go on with some basic information
103 c
104  controlfile=' '
105  if (iargc().eq.1) call getarg(1, controlfile)
106 c give control-file information
107  if ((controlfile(1:5).eq.'-help').or.(iargc().lt.1)) then
108  print *,version
109  print *,' ',creator
110  print *,'Usage: stufi controlfile [-e ext | -r | -t file] [-o] [-v]'
111  print *,' file [t:list] ...'
112  print *,'or: stufi -help'
113  if (iargc().lt.1) stop 'ERROR: missing arguments\n'
114  print *,' '
115  print *,'controlfile Contains a sequence of seife commands'
116  print *,' that will be executed on every'
117  print *,' selected dataset. See below for'
118  print *,' available seife commands. A maximum'
119  print *,' of ',maxcontrol,' lines is allowed.'
120  print *,'-e ext Write results to a file with the same'
121  print *,' name as the original dataset but with'
122  print *,' filename extension ext. The resluting'
123  print *,' file will contain all original data'
124  print *,' traces (the ones not selected will be'
125  print *,' unchanged. the default extension is:'
126  print *,' .sfi'
127  print *,'-r Replace the original datasets with'
128  print *,' the results of the filter operation.'
129  print *,'-t file Write all results to one file with'
130  print *,' the given name. This file will contain'
131  print *,' only the selected traces. Any file'
132  print *,' related FREE blocks or source'
133  print *,' definitions will be omitted.'
134  print *,'-o Overwrite existing file (is default together'
135  print *,' with -r option.'
136  print *,'-v be verbose'
137  print *,'-d produce debug output'
138  print *,' '
139  print *,'Each datafile name may be followed by a list of'
140  print *,'traces. This list selects a range of traces in'
141  print *,'the file which will be processed. This list may'
142  print *,'contain no blank (which is the separator to the'
143  print *,'next filname). The traces will always be processed'
144  print *,'in the order they appear in the data file.'
145  print *,' '
146  print *,'Examples:'
147  print *,' t:2 will select only trace 2'
148  print *,' t:4-6,2,4 will select traces 2, 4, 5 and 6'
149  print *,' t:9,8,10,14 will select traces 8, 9, 10 and 14'
150  print *,' '
151  print *,'The message returned by each seife command will be'
152  print *,'appended to the FREE block of each trace.'
153  print *,' '
154 c----------------------------------------------------------------------
155  print *,'Some comments that come with the underlying library:'
156  print *,''
157  typ='hel'
158  par=''
159  nsamples=1
160  dt=1.
161  call seife(typ,par,nsamples,dt,tmin,tsec,x,msg)
162  print *,' '
163  print *,'This program is compiled for:'
164  print *,' maximum number of samples: ',
165  & maxsamples
166  print *,' maximum number of lines in FREE block: ',
167  & maxfree
168  print *,' maximum number of lines in control file: ',
169  & maxcontrol
170  print *,' maximum number of traces to be selected: ',
171  & maxselect
172  stop
173  endif
174 c----------------------------------------------------------------------
175 c
176 c extract information from command line
177 c
178  extension='.sfi'
179  outfile='junk'
180  setext=.true.
181  replace=.false.
182  newfile=.false.
183  overwrite=.false.
184 c first read the commandline
185  call tf_cmdline(2, lastarg,
186  & maxopt, optid, optarg, optset, opthasarg)
187  if (optset(1)) then
188  setext=.true.
189  replace=.false.
190  newfile=.false.
191  extension=optarg(1)
192  endif
193  if (optset(2)) then
194  setext=.false.
195  replace=.true.
196  newfile=.false.
197  endif
198  if (optset(3)) then
199  setext=.false.
200  replace=.false.
201  newfile=.true.
202  outfile=optarg(3)
203  endif
204  debug=optset(4)
205  overwrite=optset(5)
206  verbose=optset(6)
207  if (debug) print *,'DEBUG: debug messages are switched on'
208  lastarg=lastarg+1
209 c get name of commandfile
210  call getarg(1, controlfile)
211 c check for datafiles
212  if (iargc().lt.lastarg) stop 'ERROR: missing data file\n'
213 c----------------------------------------------------------------------
214 c initialize counters
215  ntracefree=0
216  nfilefree=0
217  ncommand=0
218  tracenstack=0
219 c----------------------------------------------------------------------
220 c
221 c read in control file
222 c
223  if (debug) print *,'DEBUG: read control file'
224  ncommand=0
225  open(10, file=controlfile, err=99, status='old')
226  1 continue
227  read(10, '(a)', err=98, end=96) line
228  ncommand=ncommand+1
229  command(ncommand)=line
230  if (line(1:3).ne.'end') goto 1
231  ncommand=ncommand-1
232  if (ncommand.lt.1) stop 'ERROR: missing commands\n'
233  close(10, err=97)
234 c----------------------------------------------------------------------
235 c
236 c open output file if necessary
237 c
238  if (newfile) then
239  if (verbose) print 80,'writing to file ',outfile
240  if (overwrite) then
241  call sff_new(10, outfile, ierr)
242  if (ierr.ne.0) stop 'ERROR: deleting file'
243  endif
244  open(10, file=outfile, err=95, status='new')
245  code='F'
246  call sff_wstatus(10, code)
247  write(filefree(1), '(a)') version
248  write(filefree(2), '(a)')
249  & 'collecting all results in one file'
250  write(filefree(3), '(a)')
251  & 'file related FREE blocks and source informations are ignored'
252  nfilefree=3
253  call sff_wfree(10, nfilefree, filefree)
254  endif
255 c----------------------------------------------------------------------
256 c
257 c go through all data files
258 c
259  filep=lastarg
260  if (debug) print *,'DEBUG: enter main loop'
261  2 continue
262 c
263 c get file names
264 c
265  call getarg(filep, infile)
266  if (verbose) then
267  print *,' '
268  print *,' '
269  print 80,'reading new file ',infile
270  endif
271  if (setext) then
272  outfile=infile
273  call tf_nameext(outfile, extension)
274  if (verbose) print 80,'writing to file ',outfile
275  elseif (replace) then
276  outfile=junkfile
277  if (verbose) print *,'replacing input file'
278  endif
279 c
280 c open files
281 c
282  open(11, file=infile, err=92, status='old')
283  if (.not.(newfile)) then
284  if (overwrite) then
285  call sff_new(10, outfile, ierr)
286  if (ierr.ne.0) stop 'ERROR: deleting file'
287  endif
288  open(10, file=outfile, err=95, status='new')
289  endif
290 c
291 c do selections
292 c
293  call getarg(filep+1, line)
294  if (line(1:2).eq.'t:') then
295  filep=filep+1
296  useselect=.true.
297  call tf_listselect(maxselect, selection, 3, line, ierr)
298  if (ierr.eq.1) then
299  print *,'WARNING: selection exceeds possible range',
300  & ' from 1 to',maxselect
301  print *,' selecting only up to no.',maxselect
302  elseif (ierr.eq.2) then
303  print *,'WARNING: missing selection list - selecting ',
304  & 'all traces'
305  useselect=.false.
306  elseif (ierr.ne.0) then
307  print *,'WARNING: unknown error code by tf_listselect'
308  print *,' selecting all traces'
309  useselect=.false.
310  endif
311  else
312  useselect=.false.
313  endif
314 c
315 c go through file
316 c
317 c +++++++++++
318 c read file header
319 c
320  call sff_rstatus(11,sffversion,timestamp,code,ierr)
321  if (debug) print *,'DEBUG: read status'
322  if (ierr.ne.0) stop 'ERROR: reading status of input file\n'
323  if (.not.(newfile)) then
324  call sff_wstatus(10, code)
325  if (debug) print *,'DEBUG: wrote status'
326  endif
327  i=1
328  10 if (code(i:i).ne.' ') then
329  if (debug) print *,'DEBUG: code: ',code(i:i)
330  if (code(i:i).eq.'F') then
331  if (newfile) then
332  if (verbose)
333  & print *,'MESSAGE: skipping FREE block of input file'
334  call sff_skipfree(11, ierr)
335  if (debug) print *,'DEBUG: skipped FREE block of file'
336  if (ierr.ne.0) stop 'ERROR: skipping FREE block\n'
337  else
338  if (debug) print *,'DEBUG: read FREE block'
339  call sff_rfree(11, nfilefree, filefree,
340  & flmax, maxfree, ierr)
341  if (debug) print *,'DEBUG: read FREE block of file'
342  if (ierr.ne.0) stop 'ERROR: reading FREE block\n'
343  call sff_wfree(10, nfilefree, filefree)
344  if (debug) print *,'DEBUG: wrote FREE block of file'
345  endif
346  elseif (code(i:i).eq.'S') then
347  call sff_rsource(11, soutyp, soucs, souc1, souc2, souc3,
348  & soudate, soutime, ierr)
349  if (debug) print *,'DEBUG: read SOURCE line of file'
350  if (ierr.ne.0) stop 'ERROR: reading SOURCE line\n'
351  if (newfile) then
352  if (verbose) print *,'MESSAGE skipping SOURCE line'
353  else
354  call sff_wsource(10, soutyp, soucs, souc1, souc2,
355  & souc3, soudate, soutime)
356  if (debug) print *,'DEBUG: wrote SOURCE line of file'
357  endif
358  endif
359  i=i+1
360  goto 10
361  endif
362 c +++++++++++
363 c go through traces
364 c
365  trace=0
366  20 trace=trace+1
367  if (debug) print *,'DEBUG: next trace:',trace
368  moretraces=.false.
369  if (verbose) then
370  print *,' '
371  print 81,'trace no.',trace,':'
372  endif
373  nsamples=maxsamples
374  call sff_rdata(11, wid2line, nsamples, tanf, dt,
375  & idata, ampfac, code, ierr)
376  if (nsamples.gt.maxsamples)
377  & stop 'ERROR: too many samples\n'
378  if (debug) print *,'DEBUG: read data'
379  if (ierr.ne.0) stop 'ERROR: reading trace'
380  i=1
381  21 if (code(i:i).ne.' ') then
382  if (code(i:i).eq.'F') then
383  call sff_rfree(11, ntracefree, tracefree,
384  & flmax, maxfree, ierr)
385  if (debug) print *,'DEBUG: read trace FREE block'
386  if (ierr.ne.0) stop 'ERROR: reading FREE block\n'
387  elseif (code(i:i).eq.'I') then
388  call sff_rinfo(11, tracecs, tracec1, tracec2, tracec3,
389  & tracenstack, ierr)
390  if (debug) print *,'DEBUG: read trace INFO line'
391  if (ierr.ne.0) stop 'ERROR: reading INFO line\n'
392  elseif (code(i:i).eq.'D') then
393  moretraces=.true.
394  endif
395  i=i+1
396  goto 21
397  endif
398 c ++++++++++++
399 c do seife
400 c
401  if (newfile.and.useselect.and.(.not.selection(trace))) then
402  if (verbose) print *,'MESSAGE skipping trace'
403  else
404  if ((.not.useselect).or.selection(trace)) then
405 c ++++++++++++
406 c watch out for more traces
407 c (in case of extracting only selected traces we have to estimate
408 c whether there will be one more trace ore not)
409 c
410  expectmoretraces=.false.
411  if (newfile) then
412  if (debug) print *,'DEBUG: looking for more traces'
413  outcode=' '
414  if (useselect) then
415  do i=trace+1,maxselect
416  if (selection(i)) expectmoretraces=.true.
417  enddo
418  else
419  expectmoretraces=moretraces
420  endif
421  if ((debug).and.(expectmoretraces))
422  & print *,'DEBUG: more traces selected'
423  if (iargc().gt.filep) then
424  expectmoretraces=.true.
425  if (debug) print *,'DEBUG: more files selected'
426  endif
427  i=1
428  j=1
429  23 if (code(i:i).ne.' ') then
430  if (code(i:i).eq.'F') then
431  outcode(j:j)='F'
432  j=j+1
433  endif
434  if (code(i:i).eq.'I') then
435  outcode(j:j)='I'
436  j=j+1
437  endif
438  i=i+1
439  goto 23
440  endif
441  if (expectmoretraces) outcode(j:j)='D'
442  if (debug) print *,
443  & 'DEBUG: code for this trace was: >',code,'<'
444  code=outcode
445  if (debug) print *,
446  & 'DEBUG: code for this trace is: >',code,'<'
447  endif
448 c
449 c BEGIN
450 c SEIFE BLOCK
451 c
452 c
453 c prepare data for seife
454  if (debug) print *,'DEBUG: entering seife'
455  if (debug) print *,'DEBUG: convert int to double'
456  call tf_inttodouble(nsamples, maxsamples,
457  & idata, x, ampfac)
458  tmin=float(int(tanf/60.))
459  tsec=tanf-(60.*tmin)
460 c call seife
461  do i=1,ncommand
462  line=command(i)
463  typ=line(1:3)
464  par=line(4:)
465 c read(line(1:3), '(a3)') typ
466 c read(line(6:), '(a75)') par
467  if (debug) print *,'DEBUG: +',typ,'++',par,'+'
468  call seife(typ, par, nsamples, dt, tmin, tsec,
469  & x, msg)
470  if (debug) print *,'DEBUG: returned from seife: ',msg
471  if (ntracefree.lt.maxfree) then
472  if (debug) print *,'DEBUG: write to FREE block'
473  if (debug) print *,'DEBUG: ',ntracefree
474  if (debug) print *,'DEBUG: ',maxfree
475  ntracefree=ntracefree+1
476  write(tracefree(ntracefree), '(a)') msg
477  else
478  print *,
479  & 'WARNING: reached maximum length of FREE block'
480  endif
481  if (verbose) print *,msg
482  enddo
483 c prepare seife data to be written in sff format
484 c to WID2: nsamples, dt, tmin, tsec
485  hour=int(tmin/60.)
486  if ((hour.gt.23).or.(hour.lt.0)) then
487  print *,'WARNING: time of first sample out of range'
488  print *,'WARNING: time of first sample set to zero'
489  hour=0
490  minute=0
491  second=0.
492  else
493  minute=int(tmin)-hour*60
494  if (minute.lt.0) then
495  print *,'WARNING: time of first sample out of range'
496  print *,'WARNING: time of first sample set to zero'
497  hour=0
498  minute=0
499  second=0.
500  else
501  second=tsec
502  endif
503  endif
504  write(wid2line(17:28), '(i2,a1,i2,a1,f6.3)')
505  & hour,':',minute,':',second
506  srat=1./dt
507  if ((srat.lt.1.e-4).or.(srat.gt.100.)) then
508  write(wid2line(58:68), '(e11.6)') 1./dt
509  else
510  write(wid2line(58:68), '(f11.6)') 1./dt
511  endif
512  write(wid2line(49:56), '(i8)') nsamples
513  call tf_doubletoint(nsamples, maxsamples,
514  & idata, x, ampfac)
515  if (debug) print *,'DEBUG: exiting seife'
516 c
517 c
518 c SEIFE BLOCK
519 c END
520 c
521 
522  endif
523 c ++++++++++++
524 c write data
525 c
526  if (debug) print *,'DEBUG: ',wid2line
527  if (debug) print *,'DEBUG: nsamples ',nsamples
528  if (debug) print *,'DEBUG: ampfac ',ampfac
529  if (debug) print *,'DEBUG: code ',code
530  call sff_wdata(10, wid2line, nsamples, idata,
531  & ampfac, code)
532  if (debug) print *,'DEBUG: wrote data'
533  i=1
534  22 if (code(i:i).ne.' ') then
535  if (code(i:i).eq.'F') then
536  call sff_wfree(10, ntracefree, tracefree)
537  if (debug) print *,'DEBUG: wrote FREE block of trace'
538  elseif (code(i:i).eq.'I') then
539  call sff_winfo(10, tracecs, tracec1, tracec2, tracec3,
540  & tracenstack)
541  if (debug) print *,'DEBUG: wrote INFO line of trace'
542  endif
543  i=i+1
544  goto 22
545  endif
546  endif
547  if (moretraces) goto 20
548 c close files
549 c
550  if (.not.(newfile)) then
551  close(10, err=93)
552  endif
553  close(11, err=91)
554 c
555 c do replace
556 c
557  if (replace) then
558  call system('/bin/mv '//junkfile//' '//infile)
559  if (debug) print *,'DEBUG: /bin/mv '//junkfile//' '//infile
560  endif
561  filep=filep+1
562  if (filep.le.iargc()) goto 2
563 c----------------------------------------------------------------------
564 c
565 c close output file if necessary
566 c
567  if (newfile) close(10, err=93)
568  if (expectmoretraces) then
569  print *,'WARNING: there were still some traces expected'
570  print *,'WARNING: last trace of output file may be not'
571  print *,' marked correctly'
572  endif
573  stop
574  80 format(a,a)
575  81 format(a,i3,a)
576  99 stop 'ERROR: opening control file\n'
577  98 stop 'ERROR: reading control file\n'
578  97 stop 'ERROR: closing control file\n'
579  96 stop 'ERROR: unexpected end of control file\n'
580  95 stop 'ERROR: opening output file\n'
581  94 stop 'ERROR: writing output file\n'
582  93 stop 'ERROR: closing output file\n'
583  92 stop 'ERROR: opening input file\n'
584  91 stop 'ERROR: closing input file\n'
585  end
program stufi
Definition: stufi.f:43