Waveform filter programs
dise.f
Go to the documentation of this file.
1 c this is <dise.f>
2 c------------------------------------------------------------------------------
3 c
4 c 19/04/99 by Thomas Forbriger (IfG Stuttgart)
5 c
6 c DIfferential SEismograms
7 c
8 c ----
9 c This program 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 REVISIONS and CHANGES
25 c 19/04/99 V1.0 Thomas Forbriger
26 c 20/09/00 V1.1 set matching source time
27 c V1.2 added normalized datasets
28 c
29 c==============================================================================
30 c
31  program dise
32 c
33  character*79 version
34  parameter(version='DISE V1.2 DIfferential SEismograms')
35 c
36 c commandline
37  integer maxopt, lastarg, iargc
38  character*80 argument
39  parameter(maxopt=2)
40  character*2 optid(maxopt)
41  character*40 optarg(maxopt)
42  logical optset(maxopt), opthasarg(maxopt)
43 c
44  character*80 infile1,infile2,outfile,intrace1,intrace2,ssecbeg,ssecend
45  integer ifirst,ilast,itrace1,itrace2
46  real secbeg,secend
47  character*132 wid2line
48 c
49  integer maxsamp
50  parameter(maxsamp=100000)
51  real data1(maxsamp), data2(maxsamp), data3(maxsamp)
52  integer idata1(maxsamp), idata2(maxsamp), idata3(maxsamp)
53  real dataout1(maxsamp), dataout2(maxsamp),dataout3(maxsamp)
54  real dataout4(maxsamp), dataout5(maxsamp),dataout6(maxsamp)
55  integer idataout1(maxsamp), idataout2(maxsamp),idataout3(maxsamp)
56  integer idataout4(maxsamp), idataout5(maxsamp),idataout6(maxsamp)
57  equivalence(data1,idata1)
58  equivalence(data2,idata2)
59  equivalence(data3,idata3)
60  equivalence(dataout1,idataout1)
61  equivalence(dataout2,idataout2)
62  equivalence(dataout3,idataout3)
63  equivalence(dataout4,idataout4)
64  equivalence(dataout5,idataout5)
65  equivalence(dataout6,idataout6)
66 c
67  integer nsamp1, nsamp2, nout
68  real dt1, dt2, tanf1, tanf2
69  double precision rms1, rms2, rms3, rms4
70 c
71  integer i, lu, ierr
72  parameter(lu=10)
73  logical last
74 c debugging
75  logical debug, verbose
76 c here are the keys to our commandline options
77  data optid/2h-d, 2h-v/
78  data opthasarg/2*.false./
79  data optarg/2*1h-/
80 c
81 c------------------------------------------------------------------------------
82 c basic information
83 c
84 c
85  argument=' '
86  if (iargc().eq.1) call getarg(1, argument)
87  if ((argument(1:5).eq.'-help').or.(iargc().ne.7)) then
88  print *,version
89  print *,'Usage: dise infile1 n1 infile2 n2 outfile tb te'
90  print *,' or: dise -help'
91  if (argument(1:5).ne.'-help') stop 'ERROR: wrong number of arguments'
92  print *,' '
93  print *,'DIfferential SEismograms'
94  print *,' '
95  print *,'infile1 SFF input file for trace A'
96  print *,'n1 trace number of trace A in file ''infile1'' '
97  print *,'infile2 SFF input file for trace B'
98  print *,'n2 trace number of trace B in file ''infile2'' '
99  print *,'outfile results will be written to this file'
100  print *,'tb time of first sample (in sec)'
101  print *,'te time of last sample (in sec)'
102  print *,' '
103  print *,'about DISE'
104  print *,'=========='
105  print *,' '
106  print *,' This program compares two time series. These may be'
107  print *,' real data and synthetics or synthetics calculated with'
108  print *,' two different methods. The two time series are named A'
109  print *,' and B and are read from the input file. In order to'
110  print *,' calculate a difference trace (A-B), trace B will be'
111  print *,' resampled to match the sampling interval and time range'
112  print *,' of trace A. Root mean square (rms) values are calculated'
113  print *,' from all three traces within the specified time range'
114  print *,' (as defined by ''tb'' and ''te''). Ratios of the rms values'
115  print *,' are reported on the terminal.'
116  print *,' '
117  print *,' nA and nB are datasets normalized to an rms of 1.'
118  stop
119  endif
120 c
121 c------------------------------------------------------------------------------
122 c read command line arguments
123 c
124  call tf_cmdline(1, lastarg, maxopt, optid,
125  & optarg, optset, opthasarg)
126  debug=optset(1)
127  verbose=optset(2)
128  call getarg(1,infile1)
129  call getarg(2,intrace1)
130  call getarg(3,infile2)
131  call getarg(4,intrace2)
132  call getarg(5,outfile)
133  call getarg(6,ssecbeg)
134  call getarg(7,ssecend)
135 c
136 c------------------------------------------------------------------------------
137 c go
138  read(intrace1, *)itrace1
139  read(intrace2, *)itrace2
140  read(ssecbeg, *)secbeg
141  read(ssecend, *)secend
142  call getfile(infile1, itrace1, data1, idata1, maxsamp, nsamp1,
143  & tanf1, dt1)
144  call getfile(infile2, itrace2, data2, idata2, maxsamp, nsamp2,
145  & tanf2, dt2)
146 c
147 c do only as much as necessary
148  ifirst=1+int((secbeg-tanf1)/dt1)
149  ilast=1+int((secend-tanf1)/dt1)
150  if ((ifirst.gt.ilast).or.(ifirst.lt.1).or.(ilast.gt.nsamp1))
151  & stop 'ERROR: check time range'
152  nout=ilast-ifirst+1
153  call resamp(data2, data3, nsamp1, nsamp2, tanf1, dt1, tanf2, dt2,
154  & ifirst, ilast)
155 c
156  print *,'calculating difference trace (A-B)...'
157  rms1=0.
158  rms2=0.
159  rms3=0.
160  rms4=0.
161  do i=1,nout
162  dataout2(i)=data1(i-1+ifirst)
163  dataout3(i)=data3(i)
164  dataout1(i)=dataout2(i)-dataout3(i)
165  rms1=rms1+dataout1(i)*dataout1(i)
166  rms2=rms2+dataout2(i)*dataout2(i)
167  rms3=rms3+dataout3(i)*dataout3(i)
168  enddo
169  rms1=sqrt(rms1/nout)
170  rms2=sqrt(rms2/nout)
171  rms3=sqrt(rms3/nout)
172 c
173 c notice related values:
174 c data1 dataout2 rms2
175 c data3 dataout3 rms3 (resampled version of data2)
176 c
177  do i=1,nout
178  dataout5(i)=data1(i-1+ifirst)/rms2
179  dataout6(i)=data3(i)/rms3
180  dataout4(i)=dataout5(i)-dataout6(i)
181  rms4=rms4+dataout4(i)*dataout4(i)
182  enddo
183  rms4=sqrt(rms4/nout)
184 c
185  last=.false.
186  print *,'going to write A-B, A and B to ',
187  & outfile(1:index(outfile, ' ')),'...'
188  call sff_wopens(lu, outfile, 'nil ',
189  & 'C', 0., 0., 0., '990420','000000.000', ierr)
190  if (ierr.ne.0) stop 'ERROR: opening output file'
191 c
192  call sff_prepwid2(nout, 1./dt1, 'NSP ', 1999, 4, 20, 0, 0,
193  & 'A-B', 'NSP ', 'NSP ', 0., 1., 1., -1., -1., wid2line, ierr)
194  if (ierr.ne.0) stop 'ERROR: preparing WID2 line for trace one'
195  call sff_wtrace(lu, wid2line, nout, dataout1, idataout1, last, ierr)
196  if (ierr.ne.0) stop 'ERROR: writing first trace to output file'
197 c
198  call sff_prepwid2(nout, 1./dt1, 'NSP ', 1999, 4, 20, 0, 0,
199  & 'A', 'NSP ', 'NSP ', 0., 1., 1., -1., -1., wid2line, ierr)
200  if (ierr.ne.0) stop 'ERROR: preparing WID2 line for trace two'
201  call sff_wtrace(lu, wid2line, nout, dataout2, idataout2, last, ierr)
202  if (ierr.ne.0) stop 'ERROR: writing second trace to output file'
203 c
204  call sff_prepwid2(nout, 1./dt1, 'NSP ', 1999, 4, 20, 0, 0,
205  & 'B', 'NSP ', 'NSP ', 0., 1., 1., -1., -1., wid2line, ierr)
206  if (ierr.ne.0) stop 'ERROR: preparing WID2 line for trace three'
207  call sff_wtrace(lu, wid2line, nout, dataout3, idataout3, last, ierr)
208  if (ierr.ne.0) stop 'ERROR: writing third trace to output file'
209 c
210  call sff_prepwid2(nout, 1./dt1, 'NSP ', 1999, 4, 20, 0, 0,
211  & 'nA-nB', 'NSP ', 'NSP ', 0., 1., 1., -1., -1., wid2line, ierr)
212  if (ierr.ne.0) stop 'ERROR: preparing WID2 line for trace one'
213  call sff_wtrace(lu, wid2line, nout, dataout4, idataout4, last, ierr)
214  if (ierr.ne.0) stop 'ERROR: writing fourth trace to output file'
215 c
216  call sff_prepwid2(nout, 1./dt1, 'NSP ', 1999, 4, 20, 0, 0,
217  & 'nA', 'NSP ', 'NSP ', 0., 1., 1., -1., -1., wid2line, ierr)
218  if (ierr.ne.0) stop 'ERROR: preparing WID2 line for trace two'
219  call sff_wtrace(lu, wid2line, nout, dataout5, idataout5, last, ierr)
220  if (ierr.ne.0) stop 'ERROR: writing fifth trace to output file'
221 c
222  call sff_prepwid2(nout, 1./dt1, 'NSP ', 1999, 4, 20, 0, 0,
223  & 'nB', 'NSP ', 'NSP ', 0., 1., 1., -1., -1., wid2line, ierr)
224  if (ierr.ne.0) stop 'ERROR: preparing WID2 line for trace three'
225  last=.true.
226  call sff_wtrace(lu, wid2line, nout, dataout6, idataout6, last, ierr)
227  if (ierr.ne.0) stop 'ERROR: writing sixth trace to output file'
228 c
229  print *,'results are:'
230  print *,' Arms/Brms: ',rms2,'/',rms3,'=',rms2/rms3
231  print *,' (A-B)rms/Arms: ',rms1,'/',rms2,'=',rms1/rms2
232  print *,' (A-B)rms/Brms: ',rms1,'/',rms3,'=',rms1/rms3
233  print *,' (nA-nB)rms: ',rms4
234 c
235  stop
236  end
237 c
238 c======================================================================
239 c
240  subroutine getfile(filename, itrace, data, idata, maxsamp,
241  & nsamp, tanf, dt)
242 c
243  character filename*(*)
244  integer itrace, nsamp, maxsamp
245  real data(maxsamp)
246  integer idata(maxsamp)
247  real tanf, dt
248 c
249  character cs*1, code*20, time*20, date*20, tist*20, type*30, rs*1
250  character wid2line*132
251  real inv
252  real c1,c2,c3,r1,r2,r3,sffu_tfirst
253  integer ierr, lu, nstack, i
254  parameter(lu=10)
255  logical last
256 c
257  print *,'going to read ',filename(1:index(filename, ' ')),'...'
258 c
259  call sff_ropens(lu, filename, inv, tist, code, type, cs, c1, c2, c3,
260  & date,time,ierr)
261  if (ierr.ne.0) stop 'ERROR opening input file'
262  nsamp=maxsamp
263  last=.false.
264  do i=1,itrace
265  if (last) stop 'ERROR: too few traces in input file'
266  call sff_rtracei(lu, tanf, dt, wid2line, nsamp, data, idata, code,
267  & last, rs, r1, r2, r3, nstack, ierr)
268  if (ierr.ne.0) stop 'ERROR: reading input file'
269  enddo
270  print *,' read trace no.',itrace
271  if (.not.(last)) close(lu)
272  tanf=sffu_tfirst(wid2line, time, date)
273  print *,' trace begins at ',tanf,'sec'
274  print *,' sampling interval is ',dt,'sec'
275  return
276  end
277 c
278 c----------------------------------------------------------------------
279 c
280  subroutine resamp(data2, data3, nsamp1, nsamp2, tanf1, dt1, tanf2, dt2,
281  & ifirst, ilast)
282 c
283  real data2(nsamp2), data3(nsamp1)
284  integer nsamp1, nsamp2, ifirst, ilast
285  real tanf1, tanf2, dt1, dt2
286 c
287  logical verbose
288  parameter(verbose=.true.)
289 c
290  integer maxspec
291  parameter(maxspec=100000)
292  complex spect(maxspec)
293  integer nspec
294 c
295  real pi, t, sum,dper,selbeg,selend,oselbeg,oselend
296  integer ispec,i,oifirst,oilast,onspec,nout
297  integer limit,percount,nextper
298  complex ime, expfac, expfacbase
299  parameter(pi=3.1415926535897931159979,ime=(0.,1.))
300 c
301  if (verbose) then
302  print *,' '
303  print *,'do some resampling...'
304  endif
305 c
306  selbeg=(ifirst-1)*dt1+tanf1
307  selend=(ilast-1)*dt1+tanf1
308  oifirst=int((selbeg-tanf2)/dt2)
309  oilast=2+int((selend-tanf2)/dt2)
310  if ((oifirst.gt.oilast).or.(oifirst.lt.1).or.(oilast.gt.nsamp2))
311  & stop 'ERROR: check times'
312  onspec=oilast-oifirst+1
313  nout=ilast-ifirst+1
314  oselbeg=(oifirst-1)*dt2+tanf2
315  oselend=(oilast-1)*dt2+tanf2
316 c
317  print *,' original trace:'
318  print *,' first sample: ',tanf2,'sec; last sample: ',
319  & (nsamp2-1)*dt2+tanf2,'sec'
320  print *,' sampling interval: ',dt2,'sec'
321  print *,' selected first sample: ',oifirst
322  print *,' selected last sample: ',oilast
323  print *,' selected start time: ',oselbeg,'sec'
324  print *,' selected end time: ',oselend,'sec'
325  print *,' master trace:'
326  print *,' first sample: ',tanf1,'sec; last sample: ',
327  & (nsamp1-1)*dt1+tanf1,'sec'
328  print *,' sampling interval: ',dt1,'sec'
329  print *,' selected first sample: ',ifirst
330  print *,' selected last sample: ',ilast
331  print *,' selected start time: ',selbeg,'sec'
332  print *,' selected end time: ',selend,'sec'
333 c
334  nspec=2
335  do while(nspec.lt.onspec)
336  nspec=nspec*2
337  enddo
338  if (nspec.gt.maxspec) stop 'ERROR: maxspec too small!'
339 c
340  print *,'preparing spectrum with ',nspec,' samples'
341  do i=1,nspec
342  spect(i)=(0.,0.)
343  enddo
344 c
345  print *,' extracting'
346  print *,' original trace ',oifirst,'-',oifirst-1+onspec
347  print *,' to spectrum trace ',1,'-',onspec
348  do i=1,onspec
349  spect(i)=cmplx(data2(oifirst+i-1))
350  enddo
351 c
352  call tf_fork(nspec,spect,-1.)
353 c
354  if (verbose) then
355  print *,' we hold the spectrum now'
356  print *,' going to perform resampling DFT (which will be slow)...'
357  endif
358 c
359 c
360 c dt*sqrt(nsamples) is the factor we have to multiply in order to get
361 c spectral coefficients corresponding to a foruier integral transform
362 c
363 c dt*(nsamples-1) is the time length of the original trace, which is the
364 c recurrence time of the time limited fourier signal
365 c
366 c 1./(dt*nsamples) is the frequency step size
367 c
368  if (dt1.gt.dt2) then
369  print *,' old sampling interval (',dt2,'sec)'
370  print *,' is less than new one (',dt1,'sec) !'
371  print *,
372  & ' it''s up to you to perform a correct low pass filtering'
373  endif
374 c
375 c
376  expfacbase=2.*pi*ime/(dt2*float(nspec))
377  limit=nspec/2
378  dper=10.
379  percount=1
380  nextper=nout*dper/100.
381 c
382  do i=1,nout
383  t=(i-1)*dt1+selbeg
384 c print *,'calc sample ',i,' at ',t,'sec'
385  expfac=expfacbase*(t-oselbeg)
386  if ((t.lt.oselbeg).or.(t.gt.oselend)) then
387  data3(i)=0.
388  print *,'trapped'
389  else
390  sum=0.5*real(spect(1))
391  do ispec=2,limit
392  sum=sum+real(spect(ispec)*cexp(expfac*float(ispec-1)))
393  enddo
394  sum=sum+0.5*real(spect(limit+1)*cexp(expfac*(limit)))
395  data3(i)=2.*sum/sqrt(float(nspec))
396  endif
397  if (i.gt.nextper) then
398  print *,' finished ',percount*dper,'%'
399  percount=percount+1
400  nextper=percount*nout*dper/100.
401  endif
402  enddo
403  print *,' finished 100.%'
404 c
405  return
406  end
407 c
408 c ----- END OF dise.f -----
subroutine getfile(filename, itrace, data, idata, maxsamp, nsamp, tanf, dt)
Definition: dise.f:242
subroutine resamp(data2, data3, nsamp1, nsamp2, tanf1, dt1, tanf2,
Definition: dise.f:281
program dise
Definition: dise.f:31