def validate_gsim(self, value): """ Checks that the value is a class name in the dictionary reported by get_available_gsims, i.e. a GSIM class. :param str value: the name of an existing GSIM class """ try: valid.gsim(value) except ValueError as e: raise NameError('%s in file %r' % (e, self.fname))
def get_gsims(oqparam): """ Return an ordered list of GSIM instances from the gsim name in the configuration file or from the gsim logic tree file. :param oqparam: an :class:`openquake.commonlib.oqvalidation.OqParam` instance """ return [valid.gsim(str(rlz)) for rlz in get_gsim_lt(oqparam)]
def test_gsim(self): class FakeGsim(object): def __init__(self, arg): self.arg = arg def __repr__(self): return '<FakeGsim(%s)>' % self.arg valid.GSIM['FakeGsim'] = FakeGsim gsim = valid.gsim('FakeGsim(0.1)') self.assertEqual(repr(gsim), '<FakeGsim(0.1)>')
def get_rlzs_assoc(self, get_weight=lambda tm: tm.num_ruptures): """ Return a RlzsAssoc with fields realizations, gsim_by_trt, rlz_idx and trt_gsims. :param get_weight: a function trt_model -> positive number """ assoc = RlzsAssoc(self.get_info()) random_seed = self.source_model_lt.seed num_samples = self.source_model_lt.num_samples idx = 0 for smodel in self.source_models: # collect the effective tectonic region types trts = set(tm.trt for tm in smodel.trt_models if get_weight(tm)) # recompute the GSIM logic tree if needed if trts != set(smodel.gsim_lt.tectonic_region_types): before = smodel.gsim_lt.get_num_paths() smodel.gsim_lt.reduce(trts) after = smodel.gsim_lt.get_num_paths() logging.warn( 'Reducing the logic tree of %s from %d to %d ' 'realizations', smodel.name, before, after) if num_samples: # sampling rnd = random.Random(random_seed + idx) rlzs = logictree.sample(smodel.gsim_lt, smodel.samples, rnd) else: # full enumeration rlzs = logictree.get_effective_rlzs(smodel.gsim_lt) if rlzs: idx = assoc._add_realizations(idx, smodel, rlzs, trts) for trt_model in smodel.trt_models: trt_model.gsims = smodel.gsim_lt.values[trt_model.trt] else: logging.warn('No realizations for %s, %s', '_'.join(smodel.path), smodel.name) if assoc.realizations: if num_samples: assert len(assoc.realizations) == num_samples for rlz in assoc.realizations: rlz.weight = 1. / num_samples else: tot_weight = sum(rlz.weight for rlz in assoc.realizations) if tot_weight == 0: raise ValueError('All realizations have zero weight??') elif abs(tot_weight - 1) > 1E-12: # allow for rounding errors logging.warn('Some source models are not contributing, ' 'weights are being rescaled') for rlz in assoc.realizations: rlz.weight = rlz.weight / tot_weight assoc.gsims_by_trt_id = groupby( assoc.rlzs_assoc, operator.itemgetter(0), lambda group: sorted(valid.gsim(gsim) for trt_id, gsim in group)) return assoc
def get_rlzs_assoc(self, get_weight=lambda tm: tm.num_ruptures): """ Return a RlzsAssoc with fields realizations, gsim_by_trt, rlz_idx and trt_gsims. :param get_weight: a function trt_model -> positive number """ assoc = RlzsAssoc(self.get_info()) random_seed = self.source_model_lt.seed num_samples = self.source_model_lt.num_samples idx = 0 for smodel in self.source_models: # collect the effective tectonic region types trts = set(tm.trt for tm in smodel.trt_models if get_weight(tm)) # recompute the GSIM logic tree if needed if trts != set(smodel.gsim_lt.tectonic_region_types): before = smodel.gsim_lt.get_num_paths() smodel.gsim_lt.reduce(trts) after = smodel.gsim_lt.get_num_paths() logging.warn('Reducing the logic tree of %s from %d to %d ' 'realizations', smodel.name, before, after) if num_samples: # sampling rnd = random.Random(random_seed + idx) rlzs = logictree.sample(smodel.gsim_lt, smodel.samples, rnd) else: # full enumeration rlzs = logictree.get_effective_rlzs(smodel.gsim_lt) if rlzs: idx = assoc._add_realizations(idx, smodel, rlzs, trts) for trt_model in smodel.trt_models: trt_model.gsims = smodel.gsim_lt.values[trt_model.trt] else: logging.warn('No realizations for %s, %s', '_'.join(smodel.path), smodel.name) if assoc.realizations: if num_samples: assert len(assoc.realizations) == num_samples for rlz in assoc.realizations: rlz.weight = 1. / num_samples else: tot_weight = sum(rlz.weight for rlz in assoc.realizations) if tot_weight == 0: raise ValueError('All realizations have zero weight??') elif abs(tot_weight - 1) > 1E-12: # allow for rounding errors logging.warn('Some source models are not contributing, ' 'weights are being rescaled') for rlz in assoc.realizations: rlz.weight = rlz.weight / tot_weight assoc.gsims_by_trt_id = groupby( assoc.rlzs_assoc, operator.itemgetter(0), lambda group: sorted(valid.gsim(gsim) for trt_id, gsim in group)) return assoc
def test_compute_gmf(self): hc = mock.Mock() hc.ground_motion_correlation_model = None hc.truncation_level = None hc.maximum_distance = 200. trt = 'Subduction Interface' gsim = valid.gsim('AkkarBommer2010') num_sites = 5 site_coll = make_site_coll(-78, 15.5, num_sites) rup_id, rup_seed = 42, 44 rup = FakeRupture(rup_id, trt) rlz = mock.Mock() rlz.id = 1 ses_coll = mock.Mock() ses_coll.ordinal = 0 ses_coll.trt_model.id = 1 calc = core.GmfCalculator( ['PGA'], [gsim], ses_coll, truncation_level=3) calc.calc_gmfs(site_coll, rup, [(rup.id, rup_seed)]) expected_rups = { ('AkkarBommer2010', 'PGA', 0): [rup_id], ('AkkarBommer2010', 'PGA', 1): [rup_id], ('AkkarBommer2010', 'PGA', 2): [rup_id], ('AkkarBommer2010', 'PGA', 3): [rup_id], ('AkkarBommer2010', 'PGA', 4): [rup_id], } expected_gmvs = { ('AkkarBommer2010', 'PGA', 0): [0.1027847118266612], ('AkkarBommer2010', 'PGA', 1): [0.02726361912605336], ('AkkarBommer2010', 'PGA', 2): [0.0862595971325641], ('AkkarBommer2010', 'PGA', 3): [0.04727148908077005], ('AkkarBommer2010', 'PGA', 4): [0.04750575818347277], } numpy.testing.assert_equal(calc.ruptures_per_site, expected_rups) for i, gmvs in expected_gmvs.iteritems(): numpy.testing.assert_allclose(gmvs, expected_gmvs[i]) # 5 curves (one per each site) for 3 levels, 1 IMT [(gname, [curves])] = calc.to_haz_curves( site_coll.sids, dict(PGA=[0.03, 0.04, 0.05]), invest_time=50., duration=500) self.assertEqual(gname, 'AkkarBommer2010') numpy.testing.assert_array_almost_equal( curves, [[0.09516258, 0.09516258, 0.09516258], # curve site1 [0.00000000, 0.00000000, 0.00000000], # curve site2 [0.09516258, 0.09516258, 0.09516258], # curve site3 [0.09516258, 0.09516258, 0.00000000], # curve site4 [0.09516258, 0.09516258, 0.00000000], # curve site5 ])
def _build_trts_branches(self): # do the parsing, called at instantiation time to populate .values trts = [] branches = [] branchsetids = set() for branching_level in self._ltnode: if len(branching_level) > 1: raise InvalidLogicTree( 'Branching level %s has multiple branchsets' % branching_level['branchingLevelID']) for branchset in branching_level: if branchset['uncertaintyType'] != 'gmpeModel': raise InvalidLogicTree( 'only uncertainties of type ' '"gmpeModel" are allowed in gmpe logic tree') bsid = branchset['branchSetID'] if bsid in branchsetids: raise InvalidLogicTree('Duplicated branchSetID %s' % bsid) else: branchsetids.add(bsid) trt = branchset.attrib.get('applyToTectonicRegionType') if trt: trts.append(trt) effective = trt in self.tectonic_region_types weights = [] for branch in branchset: weight = Decimal(branch.uncertaintyWeight.text) weights.append(weight) branch_id = branch['branchID'] uncertainty = branch.uncertaintyModel try: gsim = valid.gsim(uncertainty.text.strip(), **uncertainty.attrib) except: etype, exc, tb = sys.exc_info() raise_(etype, '%s in file %r' % (exc, self.fname), tb) self.values[trt].append(gsim) bt = BranchTuple(branchset, branch_id, gsim, weight, effective) branches.append(bt) assert sum(weights) == 1, weights if len(trts) > len(set(trts)): raise InvalidLogicTree( 'Found duplicated applyToTectonicRegionType=%s' % trts) branches.sort(key=lambda b: (b.bset['branchSetID'], b.id)) return trts, branches
def create_ruptures(self): oqparam = models.oqparam(self.job.id) self.imts = map(from_string, oqparam.imtls) self.rupture = readinput.get_rupture(oqparam) # check filtering trunc_level = oqparam.truncation_level maximum_distance = oqparam.maximum_distance self.sites = filters.filter_sites_by_distance_to_rupture( self.rupture, maximum_distance, self.site_collection) if self.sites is None: raise RuntimeError( 'All sites where filtered out! ' 'maximum_distance=%s km' % maximum_distance) # create ses output output = models.Output.objects.create( oq_job=self.job, display_name='SES Collection', output_type='ses') self.ses_coll = models.SESCollection.create(output=output) # create gmf output output = models.Output.objects.create( oq_job=self.job, display_name="GMF", output_type="gmf_scenario") self.gmf = models.Gmf.objects.create(output=output) with self.monitor('saving ruptures', autoflush=True): self.tags = ['scenario-%010d' % i for i in xrange( oqparam.number_of_ground_motion_fields)] _, self.rupids, self.seeds = create_db_ruptures( self.rupture, self.ses_coll, self.tags, self.oqparam.random_seed) correlation_model = models.get_correl_model( models.OqJob.objects.get(pk=self.job.id)) gsim = valid.gsim(oqparam.gsim) self.computer = GmfComputer( self.rupture, self.sites, oqparam.imtls, [gsim], trunc_level, correlation_model)
def _build_trts_branches(self): # do the parsing, called at instantiation time to populate .values trts = [] branches = [] branchsetids = set() for branching_level in self._ltnode: if len(branching_level) > 1: raise InvalidLogicTree( "Branching level %s has multiple branchsets" % branching_level["branchingLevelID"] ) for branchset in branching_level: if branchset["uncertaintyType"] != "gmpeModel": raise InvalidLogicTree("only uncertainties of type " '"gmpeModel" are allowed in gmpe logic tree') bsid = branchset["branchSetID"] if bsid in branchsetids: raise InvalidLogicTree("Duplicated branchSetID %s" % bsid) else: branchsetids.add(bsid) trt = branchset.attrib.get("applyToTectonicRegionType") if trt: trts.append(trt) effective = trt in self.tectonic_region_types weights = [] for branch in branchset: weight = Decimal(branch.uncertaintyWeight.text) weights.append(weight) branch_id = branch["branchID"] uncertainty = branch.uncertaintyModel try: gsim = valid.gsim(uncertainty.text.strip(), **uncertainty.attrib) except: etype, exc, tb = sys.exc_info() raise_(etype, "%s in file %r" % (exc, self.fname), tb) self.values[trt].append(gsim) bt = BranchTuple(branchset, branch_id, gsim, weight, effective) branches.append(bt) assert sum(weights) == 1, weights if len(trts) > len(set(trts)): raise InvalidLogicTree("Found duplicated applyToTectonicRegionType=%s" % trts) branches.sort(key=lambda b: (b.bset["branchSetID"], b.id)) return trts, branches
def create_ruptures(self): oqparam = models.oqparam(self.job.id) self.imts = map(from_string, oqparam.imtls) self.rupture = readinput.get_rupture(oqparam) # check filtering trunc_level = oqparam.truncation_level maximum_distance = oqparam.maximum_distance self.sites = filters.filter_sites_by_distance_to_rupture( self.rupture, maximum_distance, self.site_collection) if self.sites is None: raise RuntimeError('All sites where filtered out! ' 'maximum_distance=%s km' % maximum_distance) # create ses output output = models.Output.objects.create(oq_job=self.job, display_name='SES Collection', output_type='ses') self.ses_coll = models.SESCollection.create(output=output) # create gmf output output = models.Output.objects.create(oq_job=self.job, display_name="GMF", output_type="gmf_scenario") self.gmf = models.Gmf.objects.create(output=output) with self.monitor('saving ruptures', autoflush=True): self.tags = [ 'scenario-%010d' % i for i in xrange(oqparam.number_of_ground_motion_fields) ] _, self.rupids, self.seeds = create_db_ruptures( self.rupture, self.ses_coll, self.tags, self.oqparam.random_seed) correlation_model = models.get_correl_model( models.OqJob.objects.get(pk=self.job.id)) gsim = valid.gsim(oqparam.gsim) self.computer = GmfComputer(self.rupture, self.sites, oqparam.imtls, [gsim], trunc_level, correlation_model)
def get_gsims_by_trt_id(self): """Returns associations trt_id -> [GSIM instance, ...]""" return groupby( self.rlzs_assoc, operator.itemgetter(0), lambda group: sorted(valid.gsim(gsim) for trt_id, gsim in group))