Coverage for /usr/local/lib/python3.11/dist-packages/grond/targets/waveform_oac/target.py: 43%
70 statements
« prev ^ index » next coverage.py v6.5.0, created at 2023-10-26 16:25 +0000
« prev ^ index » next coverage.py v6.5.0, created at 2023-10-26 16:25 +0000
1import logging
3import numpy as num
5from pyrocko.guts import Float, Int
6from pyrocko import gf
8from ..base import (
9 MisfitTarget, TargetGroup, MisfitResult)
11from ..waveform.target import WaveformPiggybackSubtarget, \
12 WaveformPiggybackSubresult
14guts_prefix = 'grond'
15logger = logging.getLogger('grond.targets.waveform_piggyback.target')
18class WOACSubtarget(WaveformPiggybackSubtarget):
20 def evaluate(
21 self, tr_proc_obs, trspec_proc_obs, tr_proc_syn, trspec_proc_syn):
23 a_obs = num.sqrt(num.mean(num.abs(tr_proc_obs.ydata**2)))
24 a_syn = num.sqrt(num.mean(num.abs(tr_proc_syn.ydata**2)))
26 res = WOACSubresult(
27 piggy_id=self.piggy_id,
28 amplitude_obs=float(a_obs),
29 amplitude_syn=float(a_syn))
31 return res
34class WOACSubresult(WaveformPiggybackSubresult):
35 amplitude_obs = Float.T()
36 amplitude_syn = Float.T()
39class WaveformOverallAmplitudeConstraint(TargetGroup):
40 associated_path = gf.StringID.T()
41 norm_exponent = Int.T(default=2)
43 def get_targets(self, ds, event, default_path='none'):
44 logger.debug('Selecting waveform piggyback targets...')
46 target = WOACTarget(
47 path=self.path,
48 norm_exponent=self.norm_exponent,
49 associated_path=self.associated_path)
51 return [target]
54class WOACTarget(MisfitTarget):
55 associated_path = gf.StringID.T()
56 norm_exponent = Int.T(default=2)
58 can_bootstrap_weights = True
60 def __init__(self, **kwargs):
61 MisfitTarget.__init__(self, **kwargs)
62 self.piggy_ids = set()
64 def string_id(self):
65 return self.path
67 def get_plain_targets(self, engine, source):
68 return []
70 def distance_to(self, other):
71 return num.array([], dtype=float)
73 def prepare_modelling(self, engine, source, targets):
74 from ..waveform.target import WaveformMisfitTarget
75 relevant = []
76 for target in targets:
77 if isinstance(target, WaveformMisfitTarget) \
78 and target.path == self.associated_path:
80 st = WOACSubtarget()
81 self.piggy_ids.add(st.piggy_id)
82 target.add_piggyback_subtarget(st)
83 relevant.append(target)
85 return relevant
87 def finalize_modelling(
88 self, engine, source, modelling_targets, modelling_results):
90 from ..waveform.target import WaveformMisfitResult
91 amps = []
92 for mtarget, mresult in zip(modelling_targets, modelling_results):
93 if isinstance(mresult, WaveformMisfitResult):
94 for sr in list(mresult.piggyback_subresults):
95 try:
96 self.piggy_ids.remove(sr.piggy_id)
97 amps.append((sr.amplitude_obs, sr.amplitude_syn))
98 mresult.piggyback_subresults.remove(sr)
99 except KeyError:
100 logger.error(
101 'Found inconsistency while gathering piggyback '
102 'results.')
103 pass
105 amps = num.array(amps, dtype=float)
106 mask = num.all(num.isfinite(amps), axis=1)
108 amp_obs = num.median(amps[mask, 0])
109 amp_syn = num.median(amps[mask, 1])
110 m = num.abs(num.log(amp_obs / amp_syn))**self.norm_exponent
112 result = WOACMisfitResult(
113 misfits=num.array([[m, 1.]], dtype=float))
115 return result
118class WOACMisfitResult(MisfitResult):
119 pass
122__all__ = '''
123 WOACSubtarget
124 WOACSubresult
125 WaveformOverallAmplitudeConstraint
126 WOACTarget
127 WOACMisfitResult
128'''.split()