def _parse_fragility(content): """ Parse the fragility XML file and return fragility_model, fragility_functions, and damage_states for usage in get_risk_models. """ iterparse = iter(parsers.FragilityModelParser(content)) fmt, limit_states = iterparse.next() damage_states = ['no_damage'] + limit_states fragility_functions = collections.defaultdict(dict) tax_imt = dict() for taxonomy, iml, params, no_damage_limit in iterparse: tax_imt[taxonomy] = iml['IMT'] if fmt == "discrete": if no_damage_limit is None: fragility_functions[taxonomy] = [ scientific.FragilityFunctionDiscrete( iml['imls'], poes, iml['imls'][0]) for poes in params ] else: fragility_functions[taxonomy] = [ scientific.FragilityFunctionDiscrete( [no_damage_limit] + iml['imls'], [0.0] + poes, no_damage_limit) for poes in params ] else: fragility_functions[taxonomy] = [ scientific.FragilityFunctionContinuous(*mean_stddev) for mean_stddev in params ] risk_models = dict((tax, dict(damage=RiskModel(tax_imt[tax], None, ffs))) for tax, ffs in fragility_functions.items()) return damage_states, risk_models
def test_parse_discrete(self): p = iter(parsers.FragilityModelParser(get_example('fragm_d.xml'))) fmt, limit_states = p.next() self.assertEqual(fmt, 'discrete') self.assertEqual(limit_states, ['minor', 'moderate', 'severe', 'collapse']) ffs1, ffs2 = list(p) self.assertEqual(ffs1, ('RC/DMRF-D/LR', { 'IMT': "MMI", 'imls': [7.0, 8.0, 9.0, 10.0, 11.0] }, [[0.0, 0.09, 0.56, 0.91, 0.98], [0.0, 0.0, 0.04, 0.78, 0.96], [0.0, 0.0, 0.0, 0.29, 0.88], [0.0, 0.0, 0.0, 0.03, 0.63]], 5.0)) self.assertEqual(ffs2, ('RC/DMRF-D/HR', { 'IMT': "MMI", 'imls': [7.0, 8.0, 9.0, 10.0, 11.0] }, [[0.0, 0.09, 0.56, 0.92, 0.99], [0.0, 0.0, 0.04, 0.79, 0.97], [0.0, 0.0, 0.0, 0.3, 0.89], [0.0, 0.0, 0.0, 0.04, 0.64]], None))
def test_parse_continuous(self): p = iter(parsers.FragilityModelParser(get_example('fragm_c.xml'))) fmt, limit_states = p.next() self.assertEqual(fmt, 'continuous') self.assertEqual(limit_states, ['slight', 'moderate', 'extensive', 'complete']) ffs1, ffs2 = list(p) self.assertEqual(ffs1, ('RC/DMRF-D/LR', { 'IMT': "PGA", 'imls': None }, [(11.19, 8.27), (27.98, 20.677), (48.05, 42.49), (108.9, 123.7)], 0.05)) self.assertEqual(ffs2, ('RC/DMRF-D/HR', { 'IMT': "PGA", 'imls': None }, [(11.18, 8.28), (27.99, 20.667), (48.06, 42.48), (108.8, 123.6)], None))
def test_damage_states_bad_ordering(self): fm_file = StringIO.StringIO('''<?xml version='1.0' encoding='utf-8'?> <nrml xmlns="http://openquake.org/xmlns/nrml/0.4"> <fragilityModel format="continuous" imlUnit="m" minIML="0.1" maxIML="9.9"> <description>Fragility model for Pavia (continuous)</description> <!-- limit states apply to the entire fragility model --> <limitStates> slight moderate extensive complete </limitStates> <!-- fragility function set, each with its own, distinct taxonomy --> <ffs noDamageLimit="0.05" type="lognormal"> <taxonomy>RC/DMRF-D/LR</taxonomy> <!-- fragility function in continuous format, 1 per limit state --> <ffc ls="slight"> <params mean="11.19" stddev="8.27" /> </ffc> <ffc ls="extensive"> <params mean="48.05" stddev="42.49" /> </ffc> <ffc ls="moderate"> <params mean="27.98" stddev="20.677" /> </ffc> <ffc ls="complete"> <params mean="108.9" stddev="123.7" /> </ffc> </ffs> </fragilityModel> </nrml> ''') self.assertRaises(ValueError, list, parsers.FragilityModelParser(fm_file))
def get_damage_states_and_risk_models(content): """ Parse the fragility XML file and return a list of damage_states and a dictionary {taxonomy: risk model} """ iterparse = iter(parsers.FragilityModelParser(content)) fmt, limit_states = iterparse.next() damage_states = ['no_damage'] + limit_states fragility_functions = collections.defaultdict(dict) tax_imt = dict() for taxonomy, iml, params, no_damage_limit in iterparse: tax_imt[taxonomy] = iml['IMT'] if fmt == "discrete": if no_damage_limit is None: fragility_functions[taxonomy] = [ scientific.FragilityFunctionDiscrete( iml['imls'], poes, iml['imls'][0]) for poes in params ] else: fragility_functions[taxonomy] = [ scientific.FragilityFunctionDiscrete( [no_damage_limit] + iml['imls'], [0.0] + poes, no_damage_limit) for poes in params ] else: fragility_functions[taxonomy] = [ scientific.FragilityFunctionContinuous(*mean_stddev) for mean_stddev in params ] risk_models = {} for taxonomy, ffs in fragility_functions.items(): dic = dict(damage=List(ffs, imt=tax_imt[taxonomy])) risk_models[taxonomy] = workflows.RiskModel(taxonomy, workflows.Damage(dic)) return damage_states, risk_models
def parse_risk_models(self): """ If any risk model is given in the hazard calculation, the computation will be driven by risk data. In this case the locations will be extracted from the exposure file (if there is one) and the imt (and levels) will be extracted from the vulnerability model (if there is one) """ hc = self.hc if hc.vulnerability_models: logs.LOG.progress("parsing risk models") hc.intensity_measure_types_and_levels = dict() hc.intensity_measure_types = list() for vf in hc.vulnerability_models: intensity_measure_types_and_levels = dict( (record['IMT'], record['IML']) for record in parsers.VulnerabilityModelParser(vf)) for imt, levels in \ intensity_measure_types_and_levels.items(): if (imt in hc.intensity_measure_types_and_levels and (set(hc.intensity_measure_types_and_levels[imt]) - set(levels))): logs.LOG.warning("The same IMT %s is associated with " "different levels" % imt) else: hc.intensity_measure_types_and_levels[imt] = levels hc.intensity_measure_types.extend( intensity_measure_types_and_levels) # remove possible duplicates if hc.intensity_measure_types is not None: hc.intensity_measure_types = list( set(hc.intensity_measure_types)) hc.save() logs.LOG.info("Got IMT and levels " "from vulnerability models: %s - %s" % (hc.intensity_measure_types_and_levels, hc.intensity_measure_types)) if 'fragility' in hc.inputs: hc.intensity_measure_types_and_levels = dict() hc.intensity_measure_types = list() parser = iter(parsers.FragilityModelParser(hc.inputs['fragility'])) hc = self.hc fragility_format, _limit_states = parser.next() if (fragility_format == "continuous" and hc.calculation_mode != "scenario"): raise NotImplementedError( "Getting IMT and levels from " "a continuous fragility model is not yet supported") hc.intensity_measure_types_and_levels = dict( (iml['IMT'], iml['imls']) for _taxonomy, iml, _params, _no_damage_limit in parser) hc.intensity_measure_types.extend( hc.intensity_measure_types_and_levels) hc.save() if 'exposure' in hc.inputs: with logs.tracing('storing exposure'): exposure.ExposureDBWriter(self.job).serialize( parsers.ExposureModelParser(hc.inputs['exposure']))