# http://pyrocko.org - GPLv3 # # The Pyrocko Developers, 21st Century # ---|P------/S----------~Lg----------
# how to call the programs 'qseis2d.qseisS2014': 'fomosto_qseisS2014', 'qseis2d.qseisR2014': 'fomosto_qseisR2014', }
1: 'z r t'.split(), 2: 'e n u'.split(), }
# defaults
except OSError: return False
return ' '.join('%i' % val for val in vals)
return ' '.join("'%s'" % val for val in vals)
if not cs: return '\n#'
return '\n' + ' '.join('(%e,%e)' % (c.real, c.imag) for c in cs)
'%(mne)15e %(med)15e %(mnd)15e ' % self.__dict__
return '%(min_depth)15e %(max_depth)15e ' \ '%(filtered_phase)i' % self.__dict__
return '%(order) %(lower_cutoff)5e %(upper_cutoff)5e' % self.__dict__
def example(): conf = QSeisSConfigFull() conf.source_depth = 15. conf.receiver_basement_depth = 35. conf.receiver_max_distance = 2000. conf.earthmodel_1d = cake.load_model().extract(depth_max='cmb') conf.sw_flat_earth_transform = 1 return conf
[''] + [x.string_for_config() for x in xx])
"'slowness window' undefined and 'calc_slowness_window'=0"
d['str_slowness_window'] = str_float_vals(default_slowness_window) else:
aggregate(self.propagation_filters)
# This is the input file of FORTRAN77 program "QseisS" for calculation of # f-k spectra of upgoing seismic waves at the reveiver-site basement. # # by # Rongjiang Wang <wang@gfz-potsdam.de> # GeoForschungsZentrum Potsdam # Telegrafenberg, D-14473 Potsdam, Germany # # Modified from qseis2006, Potsdam, Dec. 2014 # # SOURCE DEPTH # ============ # 1. source depth [km] #------------------------------------------------------------------------------ %(source_depth)e |dble; #------------------------------------------------------------------------------ # # RECEIVER-SITE PARAMETERS # ======================== # 1. receiver-site basement depth [km] # 2. max. epicental distance [km] #------------------------------------------------------------------------------ %(receiver_basement_depth)e |dble; %(receiver_max_distance)e |dble; #------------------------------------------------------------------------------ # TIME SAMPLING PARAMETERS # ======================== # 1. length of time window [sec] # 2. number of time samples (<= 2*nfmax in qsglobal.h) #------------------------------------------------------------------------------ %(time_window)e |dble: t_window; %(nsamples)i |int: no_t_samples; #------------------------------------------------------------------------------ # SLOWNESS WINDOW PARAMETERS # ========================== # 1. the low and high slowness cut-offs [s/km] with tapering: 0 < slw1 < slw2 # defining the bounds of cosine taper at the lower end, and 0 < slw3 < slw4 # defining the bounds of cosine taper at the higher end. # 2. slowness sampling rate (1.0 = sampling with the Nyquist slowness, 2.0 = # sampling with twice higher than the Nyquist slowness, and so on: the # larger this parameter, the smaller the space-domain aliasing effect, but # also the more computation effort); # 3. the factor for suppressing time domain aliasing (> 0 and <= 1). #------------------------------------------------------------------------------ %(str_slowness_window)s |dble: slw(1-4); %(wavenumber_sampling)e |dble: sample_rate; %(aliasing_suppression_factor)e |dble: supp_factor; #------------------------------------------------------------------------------ # OPTIONS FOR PARTIAL SOLUTIONS # ============================= # 1. switch for filtering waves with a shallow penetration depth (concerning # their whole trace from source to receiver), penetration depth limit [km] # (Note: if this option is selected, waves whose travel path never exceeds # the given depth limit will be filtered ("seismic nuting"). the condition # for selecting this filter is that the given shallow path depth limit # should be larger than both source and receiver depth.) # 2. number of depth ranges where the following selected up/down-sp2oing P or # SV waves should be filtered # 3. the 1. depth range: upper and lower depth [km], switch for filtering P # or SV wave in this depth range: # switch no: 1 2 3 4 other # filtered phase: P(up) P(down) SV(up) SV(down) Error # 4. the 2. ... # (Note: the partial solution options are useful tools to increase the # numerical resolution of desired wave phases. especially when the desired # phases are much smaller than the undesired phases, these options should # be selected and carefully combined.) #------------------------------------------------------------------------------ %(filter_shallow_paths)i %(filter_shallow_paths_depth)e %(n_depth_ranges)i %(str_depth_ranges)s |int, dble, dble, int; #------------------------------------------------------------------------------ # OUTPUT FILE FOR F-K SPECTRA of GREEN'S FUNCTIONS # ================================================ # 1. info-file of Green's functions (ascii including f-k sampling parameters) # 2. file name of Green's functions (binary files including explosion, strike # -slip, dip-slip and clvd sources) #------------------------------------------------------------------------------ '%(info_path)s' '%(fk_path)s' #------------------------------------------------------------------------------ # GLOBAL MODEL PARAMETERS # ======================= # 1. switch for flat-earth-transform # 2. gradient resolution [percent] of vp, vs, and rho (density), if <= 0, then # default values (depending on wave length at cut-off frequency) will be # used #------------------------------------------------------------------------------ %(sw_flat_earth_transform)i |int: sw_flat_earth_transform; %(gradient_resolution_vp)e %(gradient_resolution_vs)e %(gradient_resolution_density)e #------------------------------------------------------------------------------ # SOURCE-SITE LAYERED EARTH MODEL # =============================== # 1. number of data lines of the layered model #------------------------------------------------------------------------------ %(n_model_lines)i |int: no_model_lines; #------------------------------------------------------------------------------ # no depth[km] vp[km/s] vs[km/s] rho[g/cm^3] qp qs #------------------------------------------------------------------------------ %(model_lines)s ; #-----------------------END OF INPUT PARAMETERS--------------------------------
Glossary
SLOWNESS: The slowness is the inverse of apparent wave velocity = sin(i)/v with i = incident angle and v = true wave velocity.
SUPPRESSION OF TIME-DOMAIN ALIASING: The suppression of the time domain aliasing is achieved by using the complex frequency technique. The suppression factor should be a value between 0 and 1. If this factor is set to 0.1, for example, the aliasing phase at the reduced time begin is suppressed to 10 percent.
MODEL PARAMETER GRADIENT RESOLUTION: Layers with a constant gradient will be discretized with a number of homogeneous sublayers. The gradient resolutions are then used to determine the maximum allowed thickness of the sublayers. If the resolutions of Vp, Vs and Rho (density) require different thicknesses, the smallest is first chosen. If this is even smaller than 1 percent of the characteristic wavelength, then the latter is taken finally for the sublayer thickness. ''' # noqa
optional=True, default=QSeisRSourceMechMT.D())
def example(): conf = QSeisRConfigFull() conf.source = QSeis2dSource(lat=-80.5, lon=90.1) conf.receiver_location = QSeisRReceiver(lat=13.4, lon=240.5, depth=0.0) conf.time_reduction = 10.0 conf.earthmodel_receiver_1d = cake.load_model().extract( depth_max='moho') return conf
def components(self):
return len(xx), '\n'.join( [''] + [x.string_for_config() for x in xx])
# Actually not existing anymore in code # d['sw_surface'] = 0 # 0-free-surface, 1-no fre surface
d['str_w_samples'] = '\n' \ + '%i\n' % len(self.user_wavelet_samples) \ + str_float_vals(self.user_wavelet_samples) else:
d['str_receiver_filter'] = self.receiver_filter.string_for_config() else:
else: d['str_source'] = '0'
# This is the input file of FORTRAN77 program "QseisR" for calculation of # synthetic seismograms using the given f-k spectra of incident seismic # waves at the receiver-site basement, where the f-k spectra should be # prepared by the "QseisS" code. # # by # Rongjiang Wang <wang@gfz-potsdam.de> # GeoForschungsZentrum Potsdam # Telegrafenberg, D-14473 Potsdam, Germany # # Modified from qseis2006, Potsdam, Dec. 2014 # #------------------------------------------------------------------------------ # SOURCE PARAMETERS # ================= # 1. epicenter (lat[deg], lon[deg]) # 2. moment tensor in N*m: Mxx, Myy, Mzz, Mxy, Myz, Mzx # Note: x is northward, y is eastward and z is downard # conversion from CMT system: # Mxx = Mtt, Myy= Mpp, Mzz = Mrr, Mxy = -Mtp, Myz = -Mrp, Mzx = Mrt # 3. file of f-k spectra of incident waves # 4. source duration [s], and selection of source time functions, i.e., # source wavelet (0 = user's own wavelet; 1 = default wavelet: normalized # square half-sinusoid) # 5. if user's own wavelet is selected, then number of the wavelet time samples # (<= 1024), followed by # 6. the equidistant wavelet time series (no comment lines between the time # series) #------------------------------------------------------------------------------ %(str_source_location)s |dble(2); %(str_source)s |dble(6); '%(fk_path)s' |char; %(wavelet_duration)e %(wavelet_type)i %(str_w_samples)s |dble, int, dbls; #------------------------------------------------------------------------------ # RECEIVER PARAMETERS # =================== # 1. station location (lat[deg], lon[deg], depth[km]) # Note: the epicentral distance should not exceed the max. distance used # for generating the f-k spectra # 2. time reduction[s] # 3. order of bandpass filter(if <= 0, then no filter will be used), lower # and upper cutoff frequences[Hz] # 4. selection of output format (1 = Down/Radial/Azimuthal, 2 = East/North/Up) # 5. output file of velocity seismograms # 6. number of datalines representing the layered receiver-site structure, and # selection of surface condition (0 = free surface, 1 = without free # surface, i.e., upper halfspace is replaced by medium of the 1. layer) # 7. ... layered structure model #------------------------------------------------------------------------------ %(str_receiver)s |dble(3); %(time_reduction)e |dble; %(str_receiver_filter)s |int, dble(2); %(output_format)i |int; %(str_output_filename)s |char; #------------------------------------------------------------------------------ %(n_model_receiver_lines)i |int: no_model_lines; #------------------------------------------------------------------------------ # MULTILAYERED MODEL PARAMETERS (shallow receiver-site structure) # =============================================================== # no depth[km] vp[km/s] vs[km/s] ro[g/cm^3] qp qs #------------------------------------------------------------------------------ %(model_receiver_lines)s #-----------------------END OF INPUT PARAMETERS-------------------------------- # #-Requirements to use QSEIS2d: ------------------------------------------------ # (1) Teleseismic body waves with penetration depth much larger than the # receiver-site basement depth # (2) The last layer parameters of the receiver-site structure should be # identical with that of the source-site model at the depth which is # defined as the common basement depth # (3) The cutoff frequency should be high enough for separating different # wave types. ''' # noqa
''' Combined config object for QSeisS and QSeisR.
This config object should contain all settings which cannot be derived from the backend-independant Pyrocko GF Store config. '''
def __str__(self): return 'Interrupted.'
''' Takes QSeis2dConfigFull or QSeisSConfigFull objects, runs the program. '''
config = QSeisSConfig(**config.qseis_s_config)
'%s===== end qseisS input =====' % input_str.decode())
os.kill(proc.pid, signal.SIGTERM) interrupted.append(True)
except OSError: os.chdir(old_wd) raise QSeis2dError('could not start qseisS: "%s"' % program)
finally:
raise KeyboardInterrupt()
'%s===== end qseisS output =====' % output_str.decode())
errmess.append( 'qseisS had a non-zero exit state: %i' % proc.returncode)
errmess.append('qseisS emitted something via stderr')
errmess.append("the string 'error' appeared in qseisS output")
self.keep_tmp = True
os.chdir(old_wd) raise QSeis2dError(''' ===== begin qseisS input ===== %s===== end qseisS input ===== ===== begin qseisS output ===== %s===== end qseisS output ===== ===== begin qseisS error ===== %s===== end qseisS error ===== %s qseisS has been invoked as "%s" in the directory %s'''.lstrip() % ( input_str.decode(), output_str.decode(), error_str.decode(), '\n'.join(errmess), program, self.tempdir))
else: logger.warn( 'not removing temporary directory: %s' % self.tempdir)
''' Takes QSeis2dConfig or QSeisRConfigFull objects, runs the program and reads the output. '''
config = QSeisRConfigFull(**config.qseis_r_config)
'%s===== end qseisR input =====' % input_str.decode())
os.kill(proc.pid, signal.SIGTERM) interrupted.append(True)
except OSError: os.chdir(old_wd) raise QSeis2dError('could not start qseisR: "%s"' % program)
finally:
raise KeyboardInterrupt()
'%s===== end qseisR output =====' % output_str.decode())
errmess.append( 'qseisR had a non-zero exit state: %i' % proc.returncode)
errmess.append('qseisR emitted something via stderr')
errmess.append("the string 'error' appeared in qseisR output")
self.keep_tmp = True
os.chdir(old_wd) raise QSeis2dError(''' ===== begin qseisR input ===== %s===== end qseisR input ===== ===== begin qseisR output ===== %s===== end qseisR output ===== ===== begin qseisR error ===== %s===== end qseisR error ===== %s qseisR has been invoked as "%s" in the directory %s'''.lstrip() % ( input_str.decode(), output_str.decode(), error_str.decode(), '\n'.join(errmess), program, self.tempdir))
# qseis2d gives velocity-integrate to displacement # integration removes one sample, add it again in front (num.zeros(1), data[:, itrace + 1])), dx=deltat)
'', '%04i' % itrace, '', comp, tmin=tmin, deltat=deltat, ydata=displ, meta=dict(distance=rec.distance, azimuth=0.0))
else: logger.warn( 'not removing temporary directory: %s' % self.tempdir)
force=False):
else:
self, storeconf, step, block_size=block_size)
storeconf.earthmodel_receiver_1d
else: conf_r.earthmodel_receiver_1d = \ storeconf.earthmodel_1d.extract( depth_max='moho') # depth_max=conf_s.receiver_basement_depth*km)
baseconf.time_region[0], baseconf.time_region[1], force=force)
num.ceil(d['tlenmax'] / self.gf_config.sample_rate) * self.gf_config.sample_rate)
phases = [ storeconf.tabulated_phases[i].phases for i in range(len( storeconf.tabulated_phases))]
all_phases = [] map(all_phases.extend, phases)
mean_source_depth = num.mean(( storeconf.source_depth_min, storeconf.source_depth_max))
arrivals = conf_s.earthmodel_1d.arrivals( phases=all_phases, distances=num.linspace( conf_s.receiver_min_distance, conf_s.receiver_max_distance, 100) * cake.m2d, zstart=mean_source_depth)
ps = num.array( [arrivals[i].p for i in range(len(arrivals))])
slownesses = ps / (cake.r2d * cake.d2m / km)
shared['slowness_window'] = (0., 0., 1.1 * float(slownesses.max()), 1.3 * float(slownesses.max()))
else:
util.ensuredir(self.tmp)
self.get_block_extents(iblock)
else: (rz, sz, firstx), (rz, sz, lastx), (nr, ns, nx) = \ self.get_block_extents(iblock)
logger.info('Skipping step %i / %i, block %i / %i' '(GF already exists)' % (self.step + 1, self.nsteps, iblock + 1, self.nblocks)) return
'Starting step %i / %i, block %i / %i' % (self.step + 1, self.nsteps, iblock + 1, self.nblocks))
else: lon=180., tstart=0.0, distance=firstx) lon=0.0, depth=source_depth)
{'r': (0, 1), 't': (3, 1), 'z': (5, 1)}) {'r': (1, 1), 't': (4, 1), 'z': (6, 1)}) {'r': (2, 1), 'z': (7, 1)}) {'r': (8, 1), 'z': (9, 1)})
mnn=f(m[0, 0]), mee=f(m[1, 1]), mdd=f(m[2, 2]), mne=f(m[0, 1]), mnd=f(m[0, 2]), med=f(m[1, 2])) else: conf_r.source_mech = None
interrupted.append(True)
continue
else: args = (rz, sz, x, ig)
self.qseis_baseconf.cut[0], args[:-1]) self.qseis_baseconf.cut[1], args[:-1])
continue
ta, tb, tc, td = [ self.store.t(v, args[:-1]) for v in self.qseis_baseconf.fade]
if None in (ta, tb, tc, td): continue
if not (ta <= tb and tb <= tc and tc <= td): raise QSeis2dError( 'invalid fade configuration')
t = tr.get_xdata() fin = num.interp(t, [ta, tb], [0., 1.]) fout = num.interp(t, [tc, td], [1., 0.]) anti_fin = 1. - fin anti_fout = 1. - fout
y = tr.ydata
sum_anti_fin = num.sum(anti_fin) sum_anti_fout = num.sum(anti_fout)
if sum_anti_fin != 0.0: yin = num.sum(anti_fin * y) / sum_anti_fin else: yin = 0.0
if sum_anti_fout != 0.0: yout = num.sum(anti_fout * y) / sum_anti_fout else: yout = 0.0
y2 = anti_fin * yin + \ fin * fout * y + \ anti_fout * yout
if self.qseis_baseconf.relevel_with_fade_in: y2 -= yin
tr.set_ydata(y2)
except gf.store.DuplicateInsert: duplicate_inserts += 1
finally: logger.warn('%i insertions skipped (duplicates)' % duplicate_inserts)
raise KeyboardInterrupt()
'Done with step %i / %i, block %i / %i' % (self.step + 1, self.nsteps, iblock + 1, self.nblocks))
if variant is None: variant = '2014'
if variant not in ('2014'): raise gf.store.StoreError('unsupported variant: %s' % variant)
modelling_code_id = 'qseis2d.%s' % variant
qseis2d = QSeis2dConfig()
qseis2d.time_region = ( gf.meta.Timing('begin-50'), gf.meta.Timing('end+100'))
qseis2d.cut = ( gf.meta.Timing('begin-50'), gf.meta.Timing('end+100'))
qseis2d.qseis_s_config.sw_flat_earth_transform = 1
store_id = os.path.basename(os.path.realpath(store_dir))
config = gf.meta.ConfigTypeA(
id=store_id, ncomponents=10, sample_rate=0.2, receiver_depth=0 * km, source_depth_min=10 * km, source_depth_max=20 * km, source_depth_delta=10 * km, distance_min=100 * km, distance_max=1000 * km, distance_delta=10 * km, earthmodel_1d=cake.load_model().extract(depth_max='cmb'), modelling_code_id=modelling_code_id, tabulated_phases=[ gf.meta.TPDef( id='begin', definition='p,P,p\\,P\\,Pv_(cmb)p'), gf.meta.TPDef( id='end', definition='2.5'), gf.meta.TPDef( id='P', definition='!P'), gf.meta.TPDef( id='S', definition='!S'), gf.meta.TPDef( id='p', definition='!p'), gf.meta.TPDef( id='s', definition='!s')])
config.validate() return gf.store.Store.create_editables( store_dir, config=config, extra={'qseis2d': qseis2d})
iblock=None):
store_dir, force=force, nworkers=nworkers, continue_=continue_, step=step, iblock=iblock) |