forked from jwookey/sheba
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsheba_stack.f90
More file actions
286 lines (245 loc) · 10.1 KB
/
Copy pathsheba_stack.f90
File metadata and controls
286 lines (245 loc) · 10.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
!===============================================================================
! S H E B A - Shear-wave Birefringence Analysis
!===============================================================================
! This software is distributed in the hope that it will be useful,
! but WITHOUT ANY WARRANTY; without even the implied warranty of
! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
!===============================================================================
!
! James Wookey, School of Earth Sciences, University of Bristol
!
!-------------------------------------------------------------------------------
!
! SHEBA_STACK stacks single event error surfaces, after
! Wolfe & Silver (1998). Simplified method after
! Restivo and Helffrich (GJI, 1999)
!
! Update: ignore commented lines in input file
!
! Update: added some command line options:
! -wgt [snr|filename|one] snr = SNR ala Restivo and Helffrich '99
! filename = file with weights
! one = equal weighting (the default)
!
!===============================================================================
program sheba_stack
!===============================================================================
use array_sizes
!-------------------------------------------------------------------------------
implicit none
real :: error_in(np1,np2int,nsurfmax), error_stack(np1,np2int)
integer :: n1,n2,nsurf,ndf_stack,ndf_in(nsurfmax),ndf
real :: dtlag_step,lam2min,dfast,dtlag,fast,tlag
real :: wgt(nsurfmax)
integer ifast,itlag,i,j,iskip
integer :: iargc
real idfast,idtlag
character (len = 12) :: fmt
character (len = 80) :: arg,wfname ! weight file name
integer :: iwmode ! 1=even weighting, 2=snr weighting, 3=file of weights
! ** parse command line options
iwmode = 1
iskip = 0
do 5 i=1,iargc()
if (i .le. iskip) go to 5
call getarg(i,arg)
if (arg(1:4) == '-wgt') then
call getarg(i+1,arg)
if (arg(1:3) == 'one') then
iwmode = 1
elseif (arg(1:3) == 'snr') then
iwmode = 2
else
iwmode = 3
wfname = arg
endif
iskip = i+1
else
write(0,*) '**Unrecognized: ',arg(1:index(arg,' '))
endif
5 continue
! ** load error surfaces from the file
call load_error_surfaces(iwmode,wfname,nsurf,n1,n2, &
dtlag_step,ndf_in,wgt,error_in)
! ** stack the error surfaces
call stack_error_surfaces(nsurf,n1,n2,error_stack,error_in,ndf_in,wgt,ndf)
! ** find the minimum position
call zerror_min(error_stack,np1,np2int,ifast,itlag,lam2min)
print*,'Minimum at:', -90.0+real(ifast-1),0+real(itlag-1)*dtlag_step
fast = -90.0+real(ifast-1)
tlag = 0.0+real(itlag-1)*dtlag_step
! ** calculate errors from the 95% confidence interval
call zerror95(error_stack,ndf,lam2min,idfast,idtlag)
! print*,idfast,idtlag,ndf
dtlag = idtlag * dtlag_step
dfast = real(idfast)
print*,'Minimum lambda 2',lam2min,' at:'
print*,' FAST',fast,' +/- ',dfast
print*,' TLAG',tlag,' +/- ',dtlag
! ** output results to read in MATLAB
open(31,file='sheba_stack.err')
open(32,file='sheba_stack.sol')
write(fmt,'(a1,i5.5,a)') '(',np2int,'f12.4)'
do i=1,np1
write(31,fmt) (error_stack(i,j),j=1,np2int)
enddo
close(31)
write(32,'(a)') 'FAST DFAST TLAG DTLAG NSTACKED TLAG_STEP LAM2'
write(32,'(4f8.4,i5,2f8.4)') fast,dfast,tlag,dtlag,nsurf,dtlag_step,lam2min
stop
end program sheba_stack
!===============================================================================
!===============================================================================
subroutine stack_error_surfaces(nsurf,nfast,ntlag,error_stack, &
error_in,ndf_in,wgt,ndf)
!===============================================================================
!
! load error surfaces from files listed in sheba_stack.in
!
use array_sizes
!-------------------------------------------------------------------------------
implicit none
real :: error_in(np1,np2int,nsurfmax), error_stack(np1,np2int)
integer :: nfast,ntlag,nsurf,ndf_stack,ndf,ndf_in(nsurfmax)
real :: dtlag_step,rndf
integer :: isurf,ifast,itlag
real :: lam2max,lam2min ! maximum lamba in surface
real :: wgt(nsurfmax)
real :: sumwgt ! sum of weights applied
error_stack(:,:) = 0.0
rndf = 0.0
sumwgt = 0.0
do isurf = 1 , nsurf
! ** get lam2max,lam2min for this surface
lam2max = 0.0
lam2min = error_in(1,1,isurf)
do ifast = 1,nfast
do itlag = 1,ntlag
if (error_in(ifast,itlag,isurf) > lam2max) &
lam2max = error_in(ifast,itlag,isurf)
if (error_in(ifast,itlag,isurf) < lam2min) &
lam2min = error_in(ifast,itlag,isurf)
enddo ! ifast = 1,nfast
enddo ! itlag = 1,ntlag
! ** normalize error surface lam2min to 1
error_in(:,:,isurf) = error_in(:,:,isurf)/lam2min
! ** apply weighting (e.g.,Restivo & Helffrich, GJI, 1999)
error_in(:,:,isurf) = error_in(:,:,isurf)*wgt(isurf)
! ** add to the stack
error_stack(:,:) = error_stack(:,:) + error_in(:,:,isurf)
rndf = rndf + real(ndf_in(isurf))*wgt(isurf)
sumwgt = sumwgt + wgt(isurf)
enddo ! isurf = 1 , nsurf
! ** average error surface
error_stack(:,:) = error_stack(:,:) / sumwgt
! ** calculate weighted NDF
rndf = rndf/sumwgt*real(nsurf)
ndf = nint(rndf)
return
end subroutine stack_error_surfaces
!===============================================================================
!===============================================================================
function funwgt(x)
!===============================================================================
! Function funwth defines weight to give to samples with a determined S/N rat.
! It is defined so that samples below S/N* = 1.0 are given a weight that from
! 0.01 tends asynthotically to 0.0, while samples over S/N* = 21.0 are given a
! weight that from 0.99 tends to 1.0. Values of S/N* in between return a weight
! which steadily increases with S/N.
! S/N* indicates the S/N ratio calculated by the shear program (biased higher).
!
! Restivo + Helffrich, GJI, 1999
!-------------------------------------------------------------------------------
real k,mu
epstop = 21.0
epsbot = 1.0
width = epstop-epsbot
mu = width/2.
funetp = 0.99
funebt = 0.01
k = (log(funebt**2./funetp**2.))/width
funwgt = 1./(exp(k*(x-mu))+1.)
return
end function funwgt
!===============================================================================
!===============================================================================
subroutine load_error_surfaces(iwmode,wfname,nsurf,n1,n2,dtlag_step, &
ndf_in,wgt,error_in)
!===============================================================================
!
! load error surfaces from files listed in sheba_stack.in
!
use array_sizes
!-------------------------------------------------------------------------------
implicit none
character (len = 80) :: filename
character (len = 80) :: wfname ! weight file name
real :: error_in(np1,np2int,nsurfmax),snr,wgt(nsurfmax)
integer :: n1,n2,nsurf,ndf_in(nsurfmax)
integer :: n1first,n2first,i,j
real :: dtlag_step,dtlagfirst
real :: funwgt ! weighting function
integer :: iwmode ! 1=even weighting, 2=snr weighting, 3=file of weights
! ** loop through file list, and get file names
! ** for each file read in error surface and NDF
open(10,file='sheba_stack.in') ! open error surface file list
! ** if necessary open the weight file
if (iwmode==3) then
open(30,file=wfname)
endif
nsurf = 0
do ! forever
50 read(10,*,end=100) filename
nsurf = nsurf + 1
if (filename(1:1)=='%' .or. filename(1:1)=='!') then ! comment line
nsurf = nsurf - 1
goto 50 ! sorry
endif
! ** check whether NSURF has been exceeded.
if (nsurf>nsurfmax) then
write(0,'(a)') &
'Maximum number of surfaces exceeded. Check the value of NSURFMAX.'
stop
endif
open(20,file=filename)
read(20,*) n1, n2
read(20,*) dtlag_step
! ** check that the new grid is the same size as the first
if (nsurf == 1) then
n1first = n1 ; n2first = n2; dtlagfirst = dtlag_step
else
if (n1/=n1first .or. n2/=n2first .or. dtlag_step/=dtlagfirst) then
print*,'Warning! Grid ',nsurf,' has a different number of nodes'
print*,' or a different DTLAG'
print*,'Ignoring ...'
nsurf = nsurf - 1
goto 50 ! sorry
endif
endif
! ** if we get to here then we can go ahead and read the file
read(20,*) ndf_in(nsurf)
read(20,*) snr
! ** set the weight based on options
if (iwmode == 1) then
wgt(nsurf) = 1.0
elseif (iwmode == 2) then
wgt(nsurf) = funwgt(snr)
print*,wgt(nsurf),snr
else
! ** read in the weight
read(30,*) wgt(nsurf)
endif
print*,'File ',nsurf, ' SNR ',snr, ' IWMODE ',iwmode
print*,'N1 N2 DTLAG NDF WGT',n1,n2,dtlag_step,ndf_in(nsurf),wgt(nsurf)
do i=1,n1
read(20,*) (error_in(i,j,nsurf),j=1,n2)
enddo
close(20)
enddo
100 continue
! ** loop is finished
print*,'Read ',nsurf, ' files'
! ** produce the error stack
return
end subroutine load_error_surfaces
!===============================================================================