Browse Source

mole: update si structure WIP

pull/6/head
mmetz 2 months ago
parent
commit
24789ebf84
  1. 19
      src/apps/mole.py
  2. 139
      src/data/examples/grond_dynamic_source.gronf
  3. 173
      src/data/examples/grond_mt_source.gronf
  4. 4
      src/gm/config.py
  5. 4
      src/ls/config.py
  6. 275
      src/si/config.py
  7. 18
      src/si/invert.py
  8. 92
      src/si/module.py
  9. 36
      src/store.py

19
src/apps/mole.py

@ -152,16 +152,17 @@ def command_go(args):
parser.add_argument(
'--offline', dest='offline', action='store_true',
help='If given, offline not realtime mode is done')
help='If given, offline not realtime mode is done. '
'default is %(default)s')
parser.add_argument(
'--playback_sim', dest='playback', action='store_true',
help='If given, offline data is replayed as in realtime')
help='If given, offline data is replayed as in realtime. '
'default is %(default)s')
parser.add_argument(
'--event', dest='event_id', action='store',
help='If given, evaluate local data in ./data/<event_id>. '
'default is %(default)s')
help='If given, evaluate local data in ./data/<event_id>.')
parser.add_argument(
'--data', dest='data_dir', action='store',
@ -189,9 +190,13 @@ def command_go(args):
'--ls_conf', dest='ls_conf', action='store',
help='LandSlide config file, if config/ls.conf shall not be used')
parser.add_argument(
'--create-report', dest='create_report', action='store_true',
help='If given, Grond and IDS reports are created.')
parser, args = cl_parse('go', args, setup=setup)
storage = store.ResultStorage(store_dir='.')
storage = store.ResultStorage(store_dir=op.abspath('.'))
storage.open(
conf_dir=args.config,
si_conf=args.si_conf,
@ -209,7 +214,9 @@ def command_go(args):
playback=args.playback,
configs=storage.configs)
problem.run(force=args.force)
problem.set_parent(storage)
problem.run(force=args.force, create_report=args.create_report)
# TODO capture logs, errors etc

139
src/data/examples/grond_dynamic_source.gronf

@ -0,0 +1,139 @@
%YAML 1.1
--- !grond.Config
# Is automatically updated by mole
path_prefix: /local/home
rundir_template: runs_fastmodel_syn/${problem_name}.grun
# Dataset config is automatically update by mole
dataset_config: !grond.DatasetConfig
stations_stationxml_paths: ['path/to/stationxml.xml']
events_path: 'path/to/event/file.yaml'
waveform_paths: ['path/to/waveforms/directory']
responses_stationxml_paths: ['path/to/responses.xml']
extend_incomplete: true
picks_paths: []
blacklist_paths: ['path/to/blacklist.txt']
blacklist: [TU.AYVA, KO.BODT, KO.DATO, KO.TVSB, KO.CAVI]
whitelist_paths: []
target_groups:
- !grond.WaveformTargetGroup
normalisation_family: td
path: td.p
weight: 1.0
interpolation: nearest_neighbor
store_id: ak135_2000km_1Hz
distance_min: 0.0
distance_max: 150000.0
include: [NO.IKAR, NO.094A, NO.SAMU]
exclude: []
channels: [Z, R]
misfit_config: !grond.WaveformMisfitConfig
quantity: displacement
fmin: 0.01
fmax: 0.05
ffactor: 1.5
tmin: '0.'
tmax: '80.'
tfade: 20.0
domain: time_domain
norm_exponent: 1
tautoshift_max: 5.0
autoshift_penalty_max: 0.3
- !grond.WaveformTargetGroup
normalisation_family: td
path: td.pacc
weight: 1.0
interpolation: nearest_neighbor
store_id: ak135_2000km_1Hz
distance_min: 0.0
distance_max: 150000.0
include: [KO.GMLD, KO.KUSD, TK.0911, TK.0918, TK.0920, TK.3511, TK.3512, TK.3514,
TK.3517, TK.3524, TK.3523, TK.3528, TK.3533, TK.3538]
exclude: []
channels: [Z, R]
misfit_config: !grond.WaveformMisfitConfig
quantity: acceleration
fmin: 0.01
fmax: 0.05
ffactor: 1.5
tmin: '0.'
tmax: '80.'
tfade: 20.0
domain: time_domain
norm_exponent: 1
tautoshift_max: 5.0
autoshift_penalty_max: 0.3
- !grond.WaveformTargetGroup
normalisation_family: td
path: td.pbb
weight: 1.0
interpolation: nearest_neighbor
store_id: ak135_500km_1Hz
distance_min: 100000.0
distance_max: 200000.0
include: [HL.APE, HL.PRK, HL.PRK, KO.MLSB, KO.YAYO, KO.DAT, KO.BODT, KO.DKL,
KO.YER, KO.GORD, KO.NAZL, KO.SOMA, KO.YAYO, TU.CAM, TU.TURN,
TU.BDRM, TU.SUL, TU.STEP, TU.KOCA, TU.MULA, TU.BUHA, TU.AKHS,
TU.ZEDA, TU.AYVA, TU.MANT, TU.KTT, TU.IZMD, TU.ESEN, TU.IZMR,
TU.YAZI, TU.KIRA]
exclude: []
channels: [Z, R]
misfit_config: !grond.WaveformMisfitConfig
quantity: displacement
fmin: 0.01
fmax: 0.05
ffactor: 1.5
tmin: '0.'
tmax: '80.'
tfade: 20.0
domain: time_domain
norm_exponent: 1
tautoshift_max: 5.0
autoshift_penalty_max: 0.3
problem_config: !grond.DynamicRuptureProblemConfig
name_template: 'dynamic_rupture_run'
norm_exponent: 1
ranges:
depth: 1000 .. 10000
dip: 0 .. 90
east_shift: -25000 .. 25000
gamma: 0.7 .. 0.9
length: 10000 .. 60000
north_shift: -25000 .. 25000
nucleation_x: -1 .. 1
nucleation_y: -1 .. 1
nx: 9 .. 9
ny: 5 .. 5
rake: -180 .. 180
slip: 0.1 .. 7
strike: -180 .. 180
time: -15 .. 15 | add
width: 5000 .. 20000
anchor: top
decimation_factor: 1
distance_min: 1000.0
nthreads: 4
adaptive_resolution: 'off'
adaptive_start: 0
pure_shear: true
smooth_rupture: true
point_source_target_balancing: true
analyser_configs:
- !grond.TargetBalancingAnalyserConfig
niterations: 1000
use_reference_magnitude: false
optimiser_config: !grond.HighScoreOptimiserConfig
sampler_phases: []
# - !grond.InjectionSamplerPhase
# niterations: 2236
# ntries_preconstrain_limit: 1000
# sources_path: /data/local/home/pyrocko/projects/samos_2020/grond/Samos_20201030_115127/sources_inject_test0.yaml
chain_length_factor: 8.0
nbootstrap: 20
engine_config: !grond.EngineConfig
gf_stores_from_pyrocko_config: false
gf_store_superdirs: [/absolute/path/to/pyrocko/gf/stores]
gf_store_dirs: []
event_names: [event_name]
event_names_exclude: []

173
src/data/examples/grond_mt_source.gronf

@ -0,0 +1,173 @@
%YAML 1.1
--- !grond.Config
# Is automatically updated by mole
path_prefix: /local/home
rundir_template: runs_fastmodel_syn/${problem_name}.grun
# Is automatically updated by mole
dataset_config: !grond.DatasetConfig
stations_stationxml_paths: ['path/to/stationxml.xml']
events_path: 'path/to/event/file.yaml'
waveform_paths: ['path/to/waveforms/directory']
responses_stationxml_paths: ['path/to/responses.xml']
extend_incomplete: true
picks_paths: []
blacklist_paths: ['path/to/blacklist.txt']
blacklist: [TU.AYVA, KO.BODT, KO.DATO, KO.TVSB, KO.CAVI]
whitelist_paths: []
target_groups:
- !grond.WaveformTargetGroup
normalisation_family: td
path: td.rayleighacc
weight: 0.75
interpolation: nearest_neighbor
store_id: ak135_2000km_1Hz
distance_min: 0.0
distance_max: 100000.0
include: [KO.GMLD, KO.KUSD, KO.CESE, KO.DIDI, TK.0911, TK.0918, TK.0920, TK.3511,
TK.3512, TK.3514, TK.3517, TK.3524, TK.3523, TK.3528, TK.3533, TK.3536, TK.3538]
exclude: []
channels: [R, Z]
misfit_config: !grond.WaveformMisfitConfig
quantity: acceleration
fmin: 0.01
fmax: 0.03
ffactor: 1.5
tmin: '{stored:any_P}'
tmax: '{vel_surface:2.0}'
domain: time_domain
norm_exponent: 1
tautoshift_max: 2.5
autoshift_penalty_max: 0.05
- !grond.WaveformTargetGroup
normalisation_family: td
path: td.loveacc
weight: 0.75
interpolation: nearest_neighbor
store_id: ak135_2000km_1Hz
distance_min: 0.0
distance_max: 100000.0
include: [KO.GMLD, KO.KUSD, KO.CESE, KO.DIDI, TK.0911, TK.0918, TK.0920, TK.3511,
TK.3512, TK.3514, TK.3517, TK.3524, TK.3523, TK.3528, TK.3533, TK.3536, TK.3538]
exclude: []
channels: [T]
misfit_config: !grond.WaveformMisfitConfig
quantity: acceleration
fmin: 0.01
fmax: 0.03
ffactor: 1.5
tmin: '{stored:any_P}'
tmax: '{vel_surface:2.0}'
domain: time_domain
norm_exponent: 1
tautoshift_max: 2.5
autoshift_penalty_max: 0.05
- !grond.WaveformTargetGroup
normalisation_family: td
path: td.rayleigh
weight: 1.0
interpolation: nearest_neighbor
store_id: ak135_2000km_1Hz
distance_min: 100000.0
distance_max: 900000.0
exclude: [TK.3539, TK.1016, TK.1027, TK.3525, TK.3512, TK.4814, TK.1019, TK.4823,
TK.0905, TK.0910, TK.3511, TK.4812, TK.4502, TK.1719, TK.1716, TK.4801, TK.4507,
TK.0913, TK.3526, TK.1017, TK.4509, TK.4511, TK.3521, TK.1028, TK.3519, TK.3503,
TK.4503, TK.3523, TK.3518, TK.0917, TK.0921, TK.3537, TK.0911, TK.0918, TK.1013,
TK.3506, TK.1704, TK.0916, TK.0919, TK.1724, TK.3514, TK.4815, TK.4819, TK.0920,
TK.3513, TK.1005, TK.4818, TK.0922, TK.4508, TK.3508, TK.4821, TK.1022, TK.3534,
TK.3517, TK.3524, TK.3516, TK.4506, TK.4822, TK.4809, TK.1008, TK.4810, TK.3522,
TK.3538, TK.3528, TK.1707, TK.1021, TK.3536, TK.3520, TK.4807, TK.1720, TK.3527,
TK.1015, TK.0912, TK.4808, TK.1026, TK.4501, TK.3533, TK.4817, TK.4806, KO.AKS,
KO.CANM, KO.CESE, KO.DATC, KO.DIDI, KO.EZNE, KO.FOCM, KO.GMLD, KO.GOMA, KO.KRBN,
KO.KUSD, KO.YENI, KO.YKAV, TU.BOZC, TU.CNKL, TU.IZMD, TU.IZMR]
channels: [R, Z]
misfit_config: !grond.WaveformMisfitConfig
quantity: displacement
fmin: 0.01
fmax: 0.03
ffactor: 1.5
tmin: '{stored:any_P}'
tmax: '{vel_surface:2.0}'
domain: time_domain
norm_exponent: 1
tautoshift_max: 2.5
autoshift_penalty_max: 0.05
- !grond.WaveformTargetGroup
normalisation_family: td
path: td.love
weight: 1.0
interpolation: nearest_neighbor
store_id: ak135_2000km_1Hz
distance_min: 100000.0
distance_max: 900000.0
exclude: [TK.3539, TK.1016, TK.1027, TK.3525, TK.3512, TK.4814, TK.1019, TK.4823,
TK.0905, TK.0910, TK.3511, TK.4812, TK.4502, TK.1719, TK.1716, TK.4801, TK.4507,
TK.0913, TK.3526, TK.1017, TK.4509, TK.4511, TK.3521, TK.1028, TK.3519, TK.3503,
TK.4503, TK.3523, TK.3518, TK.0917, TK.0921, TK.3537, TK.0911, TK.0918, TK.1013,
TK.3506, TK.1704, TK.0916, TK.0919, TK.1724, TK.3514, TK.4815, TK.4819, TK.0920,
TK.3513, TK.1005, TK.4818, TK.0922, TK.4508, TK.3508, TK.4821, TK.1022, TK.3534,
TK.3517, TK.3524, TK.3516, TK.4506, TK.4822, TK.4809, TK.1008, TK.4810, TK.3522,
TK.3538, TK.3528, TK.1707, TK.1021, TK.3536, TK.3520, TK.4807, TK.1720, TK.3527,
TK.1015, TK.0912, TK.4808, TK.1026, TK.4501, TK.3533, TK.4817, TK.4806, KO.AKS,
KO.CANM, KO.CESE, KO.DATC, KO.DIDI, KO.EZNE, KO.FOCM, KO.GMLD, KO.GOMA, KO.KRBN,
KO.KUSD, KO.YENI, KO.YKAV, TU.BOZC, TU.CNKL, TU.IZMD, TU.IZMR]
channels: [T]
misfit_config: !grond.WaveformMisfitConfig
quantity: displacement
fmin: 0.01
fmax: 0.033
ffactor: 1.5
tmin: '{stored:any_P}'
tmax: '{vel_surface:2.0}'
domain: time_domain
norm_exponent: 1
tautoshift_max: 2.5
autoshift_penalty_max: 0.05
problem_config: !grond.CMTProblemConfig
name_template: 'moment_tensor_run'
norm_exponent: 1
ranges:
depth: 2000 .. 30000
duration: 5 .. 30
east_shift: -25000 .. 25000
magnitude: 4 .. 8
north_shift: -25000 .. 25000
rmdd: -1.41421 .. 1.41421
rmed: -1 .. 1
rmee: -1.41421 .. 1.41421
rmnd: -1 .. 1
rmne: -1 .. 1
rmnn: -1.41421 .. 1.41421
time: -15 .. 15 | add
distance_min: 1000.0
mt_type: full
stf_type: HalfSinusoidSTF
nthreads: 1
analyser_configs:
- !grond.TargetBalancingAnalyserConfig
niterations: 1000
use_reference_magnitude: false
optimiser_config: !grond.HighScoreOptimiserConfig
sampler_phases: []
# - !grond.UniformSamplerPhase
# niterations: 1000
# ntries_preconstrain_limit: 1000
# - !grond.DirectedSamplerPhase
# niterations: 20000
# ntries_preconstrain_limit: 1000
# scatter_scale_begin: 2.0
# scatter_scale_end: 0.45
# starting_point: excentricity_compensated
# sampler_distribution: normal
# standard_deviation_estimator: median_density_single_chain
# ntries_sample_limit: 1000
chain_length_factor: 8.0
nbootstrap: 100
engine_config: !grond.EngineConfig
gf_stores_from_pyrocko_config: false
gf_store_superdirs: [/absolute/path/to/pyrocko/gf/stores]
gf_store_dirs: []
event_names: [Samos_20201030_115127]
event_names_exclude: []

4
src/gm/config.py

@ -13,5 +13,9 @@ def get_config(*args, **kwargs):
return GroundMotionConfig(*args, **kwargs)
def get_module_extra(self):
return []
class GroundMotionConfig(ModuleConfig):
pass

4
src/ls/config.py

@ -13,5 +13,9 @@ def get_config(*args, **kwargs):
return LandSlideConfig(*args, **kwargs)
def get_module_extra(self):
return []
class LandSlideConfig(ModuleConfig):
pass

275
src/si/config.py

@ -2,24 +2,16 @@
#
# The Developers, 21st Century
import logging
import os.path as op
from pyrocko import model
from pyrocko.guts import Float, Tuple, String, Bool, List
from pyrocko.gf import Range
from pyrocko.gf.meta import QuantityType
from pyrocko.guts import Int
from grond import (
Path, read_config, Config,
DirectedSamplerPhase, HighScoreOptimiserConfig,
UniformSamplerPhase, InjectionSamplerPhase, EngineConfig,
DatasetConfig)
from grond.targets import WaveformMisfitConfig, WaveformTargetGroup
from grond.problems import CMTProblemConfig
from grond.analysers.target_balancing import TargetBalancingAnalyserConfig
from grond import Path, read_config, Config
from ewrica import util
from ewrica.module import ModuleConfig
from ewrica.dataset import tsumaps
from .invert import SourceInjectionConfig, GrondInverter
logger = logging.getLogger('ewrica.si.config')
@ -27,226 +19,89 @@ logger = logging.getLogger('ewrica.si.config')
km = 1e3
ps_config_fn = 'grond_mt_source.gronf'
ds_config_fn = 'grond_dynamic_source.gronf'
def get_config(*args, **kwargs):
return SourceInversionConfig(*args, **kwargs)
def get_module_extra():
return [util.data_file(
op.join('examples', fn)) for fn in (ps_config_fn, ds_config_fn)]
class InversionConfig(ModuleConfig):
config_path = Path.T(
grond_config_fn = Path.T(
default='',
help='Path to the grond inversion configuration file.')
config__ = Config.T(
grond_config__ = Config.T(
optional=True,
help='loaded grond inversion configuration object')
help='Loaded grond inversion configuration object.')
def __init__(self, *args, **kwargs):
ModuleConfig.__init__(self, *args, **kwargs)
self.config__ = None
injection_config = SourceInjectionConfig.T(
optional=True,
default=SourceInjectionConfig(),
help='Loaded injection configuration object.')
def generate_config(self, *args, **kwargs):
raise NotImplementedError
threads = Int.T(
default=1,
help='Number of threads.')
def get_config(self, *args, **kwargs):
if self.config__:
return self.config__
if self.config_path:
self.config__ = read_config(self.config_path)
return self.config__
self.generate_config(*args, **kwargs)
return self.config__
class PointSourceInversionConfig(InversionConfig):
distance_range = Tuple.T(
default=(100*km, 200*km))
fmin = Float.T(
default=0.01,
help='Minimum waveform frequency')
fmax = Float.T(
default=0.1,
help='Maximum waveform frequency')
quantity = QuantityType.T(
default='displacement',
help='Target quantity, where synthetic and real data are compared.')
mt_type = String.T(
default='full',
help=('Components of the full moment tensor, which are inverted:'
'"full", "deviatoric" or "dc".'))
inject_models_from_tsumaps = Bool.T(
default=True,
help='If true, models based on tsumaps probabilities are injected.')
store_id = String.T(
default='ak135_2000km_1Hz',
help='Greens function store id')
gf_store_superdirs = List.T(
Path.T(),
default=['.'],
help='Greens function store super directory')
event_file = Path.T(
default='',
help='Event file path')
event_id = String.T(
default='',
help='Event ID')
station_paths = List.T(
Path.T(),
default=[],
help='List of StationXML station and response files')
waveform_paths = List.T(
Path.T(),
default=[],
help='List of paths to waveform directories')
parent_path = Path.T(
default='.',
help='Path to parent directory. Other paths can be relative to it.')
blocklist_paths = List.T(
Path.T(),
parallel = Int.T(
default=1,
help='Number of parallel processes.')
base_path = Path.T(
optional=True,
default=None,
help='Path to txt file with blocked stations.')
def generate_config(self, *args, **kwargs):
target_groups = []
target_groups += [WaveformTargetGroup(
normalisation_family='td',
path='td.p',
distance_min=self.distance_range[0],
distance_max=self.distance_range[1],
channels=['Z', 'R'],
weight=1.0,
interpolation='nearest_neighbor',
store_id=self.store_id,
misfit_config=WaveformMisfitConfig(
quantity=self.quantity,
fmin=self.fmin,
fmax=self.fmax,
ffactor=1.5,
tmin='{stored:any_P}',
tmax='{stored:any_P}+50.',
domain='time_domain',
tautoshift_max=2.5,
autoshift_penalty_max=0.05,
norm_exponent=1))]
problem_conf = CMTProblemConfig(
name_template='',
ranges=dict(
time=Range(start=-15, stop=15, relative='add'),
north_shift=Range(start=-25.e3, stop=25.e3, step=1e3),
east_shift=Range(start=-25.e3, stop=25.e3, step=1e3),
depth=Range(start=1.e3, stop=25.e3, step=1e3),
magnitude=Range(start=4.0, stop=8.0, step=0.1),
rmnn=Range(start=-1.41421, stop=1.41421, step=0.05),
rmee=Range(start=-1.41421, stop=1.41421, step=0.05),
rmdd=Range(start=-1.41421, stop=1.41421, step=0.05),
rmne=Range(start=-1., stop=1., step=0.05),
rmnd=Range(start=-1., stop=1., step=0.05),
rmed=Range(start=-1., stop=1., step=0.05),
duration=Range(start=5., stop=20., step=1.)),
distance_min=1e3,
mt_type=self.mt_type,
norm_exponent=1)
anaylser_confs = []
anaylser_confs += [TargetBalancingAnalyserConfig(niterations=1000)]
optimiser_phases = []
optimiser_phases += [UniformSamplerPhase(niterations=1000)]
optimiser_phases += [DirectedSamplerPhase(
niterations=5000,
scatter_scale_begin=2.0,
scatter_scale_end=0.5)]
optimiser_conf = HighScoreOptimiserConfig(
nbootstrap=50, sampler_phases=optimiser_phases)
engine_conf = EngineConfig(
gf_stores_from_pyrocko_config=False,
gf_store_superdirs=self.gf_store_superdirs)
dataset_conf = DatasetConfig(
stations_stationxml_paths=self.station_paths,
responses_stationxml_paths=self.station_paths,
events_path=self.event_file,
waveform_paths=self.waveform_paths,
blacklist_paths=self.blocklist_paths or None,
apply_correction_factors=True,
extend_incomplete=True)
dataset_conf.set_basepath('/')
return Config(
rundir_template=op.join(
self.parent_path,
self.event_id, 'si', 'proc', '${problem_name}.grun'),
path_prefix='', # self.parent_path,
event_names=[self.event_id],
dataset_config=dataset_conf,
target_groups=target_groups,
problem_config=problem_conf,
analyser_configs=anaylser_confs,
optimiser_config=optimiser_conf,
engine_config=engine_conf)
def optimiser_conf_from_tsumaps(self, config):
optimiser_phases = []
optimiser_phases += [UniformSamplerPhase(niterations=1000)]
if self.inject_models_from_tsumaps:
events = model.load_events(self.event_file)
event = None
for ev in events:
if ev.name == self.event_id:
event = ev
if event is None:
raise ValueError(
'No event called %s found in the given event file' %
self.event_id)
xs_inject = tsumaps.tsumaps_to_models(
lat=event.lat, lon=event.lon,
ranges=config.problem_config.ranges,
n_models=1000, cum_prob_max=1.)
optimiser_phases += [InjectionSamplerPhase(
niterations=xs_inject.shape[0], xs_inject=xs_inject)]
optimiser_phases += [DirectedSamplerPhase(
niterations=5000,
scatter_scale_begin=2.0,
scatter_scale_end=0.5)]
config.optimiser_config = HighScoreOptimiserConfig(
nbootstrap=50, sampler_phases=optimiser_phases)
return config
help='Absolute path to main directory.')
def get_config(self, *args, **kwargs):
if self.config__ is not None:
return self.config__
report_path = Path.T(
optional=True,
help='If given, directory, where Grond reports are stored.')
def __init__(self, *args, **kwargs):
ModuleConfig.__init__(self, *args, **kwargs)
def load_grond_config_from_file(self):
if self.grond_config__ is None and self.grond_config_fn is not None:
self.grond_config = read_config(self.grond_config_fn)
if self.config_path:
config = read_config(self.config_path)
else:
config = self.generate_config(*args, **kwargs)
@property
def grond_config(self):
return self.grond_config__
if self.inject_models_from_tsumaps:
config = self.optimiser_conf_from_tsumaps(config)
@grond_config.setter
def grond_config(self, grond_config):
self.grond_config__ = grond_config
self.config__ = config
def get_config(self, *args, **kwargs):
return self
return config
def get_inverter(self, *args, **kwargs):
inverter = GrondInverter(
grond_config=self.grond_config,
injection_config=self.injection_config,
threads=self.threads,
parallel=self.parallel,
base_path=self.base_path,
report_path=self.report_path,
*args, **kwargs)
return inverter
class SourceInversionConfig(ModuleConfig):
pointsource = PointSourceInversionConfig.T(
default=PointSourceInversionConfig(),
pointsource_config = InversionConfig.T(
default=InversionConfig(grond_config_fn=ps_config_fn),
help='Configurations for point source inversion')
dynamic_rupture_config = InversionConfig.T(
default=InversionConfig(grond_config_fn=ds_config_fn),
help='Configurations for dynamic rupture inversion')
# @property
# def paths(self):
# return dict(

18
src/si/invert.py

@ -42,6 +42,15 @@ class NEAMTHM18Limit(Object):
target_value = Float.T(
optional=True)
def get_target_value(self):
if self.target_value is None:
return None
if self.quantity == 'nmodels_max':
return int(self.target_value)
return self.target_value
class SourceInjectionConfig(Object):
nucleation_x = Array.T(
@ -82,7 +91,9 @@ class SourceInjectionConfig(Object):
optional=True)
neamthm18_limit = NEAMTHM18Limit.T(
default=NEAMTHM18Limit(quantity='min_gradient', target_value=0.01),
default=NEAMTHM18Limit(
quantity='probability_gradient_min',
target_value=0.01),
help='Sets the extracted models from NEAMTHM18 database.')
fault_database = StringChoice.T(
@ -155,7 +166,8 @@ class SourceInjector(Object):
def _extract_from_tsumaps(self, lat, lon):
limit = self.config.neamthm18_limit
kwargs = {} if limit is None else {limit.quantity: limit.target_value}
kwargs = {} if limit is None else {
limit.quantity: limit.get_target_value()}
fms, probs = tsumaps.get_probs(lat, lon, **kwargs)
return list(fms[:, 0]), list(fms[:, 1]), list(fms[:, 2])
@ -731,7 +743,7 @@ class GrondInverter(Inverter):
os.chdir(self.base_path)
env = Environment(config=conf, event_names=[self.event_id])
env = Environment(config=conf, event_names=conf.event_names)
core.go(
environment=env,

92
src/si/module.py

@ -2,12 +2,12 @@
#
# The Developers, 21st Century
import logging
# import os.path as op
import os.path as op
# from grond.environment import Environment
from ..module import BaseModule
from .invert import GrondInverter
# from .invert import GrondInverter
logger = logging.getLogger('ewrica.si.module')
@ -31,34 +31,82 @@ class SourceInversionModule(BaseModule):
# self.config.check_paths()
# TODO Check for event file, meta data and data, config files, paths
def initialize_inverter(self):
inv = {}
inv['grond'] = GrondInverter()
def run_point_source_inversion(
self,
problem,
force=False,
create_report=False):
self._inverter = inv
logger.info('running point source inversion ...')
def run_point_source_inversion(self, problem, force=False):
logger.info('running point source inversion')
conf = self.config.pointsource_config.get_config()
store = problem.get_parent()
if not self._inverter:
self.initialize_inverter()
conf.grond_config_fn = op.join(
problem.config_dir, 'extra',
op.basename(conf.grond_config_fn))
inv = self._inverter['grond']
inv.config = self.config.pointsource.get_config()
inv.config.set_basepath(problem.module_processing_dir(self))
conf.load_grond_config_from_file()
conf.grond_config.set_basepath('.', parent_path_prefix=store.store_dir)
conf.grond_config.path_prefix = store.store_dir
conf.grond_config.event_names = [problem.event_id]
inv.event_id = problem.event_id
inv.run(force=force)
conf.base_path = problem.module_processing_dir(self)
conf.report_path = problem.module_result_dir(self)
inv = conf.get_inverter(
problem_name='point_source',
event_id=problem.event_id)
dc = inv.grond_config.dataset_config
dc.set_basepath(
conf.grond_config.dataset_config.get_basepath(),
parent_path_prefix=store.store_dir)
inv.grond_config.dataset_config = dc
inv.run_full(force=force, create_report=create_report)
def run_ids_inversion(self):
logger.info('running IDS finite fault estimation')
pass
def run_dynamic_rupture_inversion(self):
logger.info('running pseudo dynamic ruputure inversion')
pass
def run_dynamic_rupture_inversion(
self,
problem,
force=False,
create_report=False):
logger.info('running pseudo dynamic ruputure inversion ...')
conf = self.config.dynamic_rupture_config.get_config()
store = problem.get_parent()
conf.grond_config_fn = op.join(
problem.config_dir, 'extra',
op.basename(conf.grond_config_fn))
conf.load_grond_config_from_file()
conf.grond_config.set_basepath('.', parent_path_prefix=store.store_dir)
conf.grond_config.path_prefix = store.store_dir
conf.grond_config.event_names = [problem.event_id]
def run(self, problem=None, force=False):
conf.base_path = problem.module_processing_dir(self)
conf.report_path = problem.module_result_dir(self)
inv = conf.get_inverter(
problem_name='dynamic_rupture',
event_id=problem.event_id)
dc = inv.grond_config.dataset_config
dc.set_basepath(
conf.grond_config.dataset_config.get_basepath(),
parent_path_prefix=store.store_dir)
inv.grond_config.dataset_config = dc
inv.run_full(force=force, create_report=create_report)
# TODO convert grond results to ewrica.sources
def run(self, problem=None, *args, **kwargs):
# TODO call grond
# TODO use grond results (raw, so misfit and models) for statistics
# TODO convert grond results to own source models
@ -74,10 +122,10 @@ class SourceInversionModule(BaseModule):
logger.info('running source inversion module in "%s" mode' % mode)
self.run_point_source_inversion(problem, force=force)
self.run_ids_inversion()
self.run_point_source_inversion(problem, *args, **kwargs)
self.run_dynamic_rupture_inversion()
self.run_ids_inversion()
logger.info('Done')

36
src/store.py

@ -99,6 +99,19 @@ class Problem(Object):
optional=True,
help='List of all used module configuration files')
def __init__(self, *args, **kwargs):
Object.__init__(self, *args, **kwargs)
self._parent = None
def set_parent(self, parent):
self._parent = parent
def get_parent(self):
return self._parent
def unset_parent(self):
self._parent = None
@property
def config_dir(self):
return op.join(self.run_dir, 'config')
@ -156,12 +169,17 @@ class Problem(Object):
except CannotCreate as e:
raise e
def run_problem_offline(self, force):
if op.exists(op.join(self._parent.config_dir, 'extra')):
shutil.copytree(
op.join(self._parent.config_dir, 'extra'),
op.join(self.config_dir, 'extra'))
def run_problem_offline(self, force, *args, **kwargs):
self.create_editeables(force=force)
for module in self.modules:
if module.config.run:
module.run(problem=self, force=force)
module.run(problem=self, force=force, *args, **kwargs)
# TODO include playback "realtime simulation"
# starting from t_event with pseudo messages / based on time after
@ -174,9 +192,9 @@ class Problem(Object):
# on dt, maximum gap or available stations
pass
def run(self, force=False):
def run(self, force=False, *args, **kwargs):
if self.offline:
self.run_problem_offline(force=force)
self.run_problem_offline(force=force, *args, **kwargs)
else:
self.run_problem_online()
@ -193,6 +211,8 @@ class ResultStorage(Object):
@staticmethod
def create_editeables(store_dir, force=False, modules=None):
import os.path as op
try:
putil.ensuredir(store_dir)
except Exception:
@ -201,6 +221,8 @@ class ResultStorage(Object):
for sub_dir in store_subdirs(store_dir):
remake_dir(sub_dir, force)
remake_dir(op.join(store_dir, 'config', 'extra'), force)
fns = []
if modules is not None:
for m in modules:
@ -211,6 +233,12 @@ class ResultStorage(Object):
fns.append(fn)
for fn_extra in available_module_configs[m].get_module_extra():
fn_base = op.basename(fn_extra)
shutil.copy(
fn_extra,
op.join(store_dir, 'config', 'extra', fn_base))
return fns
@staticmethod

Loading…
Cancel
Save