def test_conditional_loss_duplicates(self): # we feed compute_conditional_loss with some duplicated data to see if # it's handled correctly loss_ratios1, poes1 = zip(*[ (0.21, 0.131), (0.24, 0.108), (0.27, 0.089), (0.30, 0.066), ]) # duplicated y values, different x values, (0.19, 0.131), (0.20, 0.131) # should be skipped loss_ratios2, poes2 = zip(*[ (0.19, 0.131), (0.20, 0.131), (0.21, 0.131), (0.24, 0.108), (0.27, 0.089), (0.30, 0.066), ]) numpy.testing.assert_allclose( scientific.conditional_loss_ratio(loss_ratios1, poes1, 0.1), scientific.conditional_loss_ratio(loss_ratios2, poes2, 0.1))
def individual_outputs(units, conditional_loss_poes, poes_disagg, profile): """ See `do_classical` for a description of the params :returns: an instance of `AssetsIndividualOutputs` """ loss_curve_matrix = [] loss_maps = [] fractions = [] for unit in units: with profile('getting hazard'): assets, hazard_curves = unit.getter() with profile('computing individual risk'): curves = unit.calc(hazard_curves) loss_curve_matrix.append(curves) loss_maps.append([[conditional_loss_ratio(losses, poes, poe) for losses, poes in curves] for poe in conditional_loss_poes]) fractions.append([[conditional_loss_ratio(losses, poes, poe) for losses, poes in curves] for poe in poes_disagg]) return AssetsIndividualOutputs( assets, numpy.array(loss_curve_matrix), numpy.array(loss_maps), numpy.array(fractions))
def statistics(outputs, weights, params): """ :param outputs: An instance of `AssetsIndividualOutputs` See `classical` for a description of `params` :returns: an instance of `StatisticalOutputs` It makes use of `..base.statistics` to compute curves and maps """ ret = [] # traverse the curve matrix on the second dimension (the assets) # accumulating results in `ret`, then return `ret` unzipped for loss_ratio_curves in outputs.curve_matrix.transpose(1, 0, 2, 3): # get the loss ratios only from the first curve loss_ratios, _poes = loss_ratio_curves[0] curves_poes = [poes for _losses, poes in loss_ratio_curves] mean_curve, quantile_curves, mean_maps, quantile_maps = ( base.asset_statistics( loss_ratios, curves_poes, params.quantiles, weights, params.conditional_loss_poes)) # compute also mean and quantile loss fractions mean_fractions = [ conditional_loss_ratio(mean_curve[0], mean_curve[1], poe) for poe in params.poes_disagg] quantile_fractions = [[ conditional_loss_ratio(quantile_curve[0], quantile_curve[1], poe) for poe in params.poes_disagg] for quantile_curve in quantile_curves] ret.append((mean_curve, mean_maps, mean_fractions, quantile_curves, quantile_maps, quantile_fractions)) (mean_curve, mean_maps, mean_fractions, quantile_curves, quantile_maps, quantile_fractions) = zip(*ret) # now all the lists keep N items # transpose maps and fractions to have P/F/Q items of N-sized lists mean_maps = numpy.array(mean_maps).transpose() mean_fractions = numpy.array(mean_fractions).transpose() quantile_curves = numpy.array(quantile_curves).transpose(1, 0, 2, 3) quantile_maps = numpy.array(quantile_maps).transpose(2, 1, 0) quantile_fractions = numpy.array(quantile_fractions).transpose(2, 1, 0) return StatisticalOutputs( outputs.assets, mean_curve, mean_maps, mean_fractions, quantile_curves, quantile_maps, quantile_fractions)
def test_mean_based(self): vulnerability_function_rm = ( scientific.VulnerabilityFunction( [0.001, 0.2, 0.3, 0.5, 0.7], [0.01, 0.1, 0.2, 0.4, 0.8], [0.0, 0.0, 0.0, 0.0, 0.0], "LN")) vulnerability_function_rc = ( scientific.VulnerabilityFunction( [0.001, 0.2, 0.3, 0.5, 0.7], [0.0035, 0.07, 0.14, 0.28, 0.56], [0.0, 0.0, 0.0, 0.0, 0.0], "LN")) calculator_rm = api.ProbabilisticEventBased( vulnerability_function_rm, 50, 50) calculator_rc = api.ProbabilisticEventBased( vulnerability_function_rc, 50, 50) loss_ratios, curves_rm = calculator_rm(gmf[0:2]) loss_ratios, [curve_rc] = calculator_rc([gmf[2]]) asset_values_rm = 3000, 1000 for i, curve_rm in enumerate(curves_rm): conditional_loss = scientific.conditional_loss_ratio( curve_rm, CONDITIONAL_LOSS_POE) self.assertAlmostEqual( mb.expected_loss_map[i], conditional_loss * asset_values_rm[i], delta=0.05 * mb.expected_loss_map[i]) numpy.testing.assert_allclose( mb.expected_poes, curve_rm.ordinates, rtol=10E-4) numpy.testing.assert_allclose( mb.expected_losses[i], curve_rm.abscissae * asset_values_rm[i], rtol=10E-4) asset_value_rc = 2000 numpy.testing.assert_allclose( mb.expected_losses[2], curve_rc.abscissae * asset_value_rc) self.assertAlmostEqual( mb.expected_loss_map[2], scientific.conditional_loss_ratio( curve_rc, CONDITIONAL_LOSS_POE) * asset_value_rc, delta=0.05 * mb.expected_loss_map[2]) numpy.testing.assert_allclose( mb.expected_poes, curve_rc.ordinates, rtol=10E-4) numpy.testing.assert_allclose( mb.expected_losses[2], curve_rc.abscissae * asset_value_rc, rtol=10E-5)
def asset_statistics(losses, curves_poes, quantiles, weights, poes): """ Compute output statistics (mean/quantile loss curves and maps) for a single asset :param losses: the losses on which the loss curves are defined :param curves_poes: a numpy matrix suitable to be used with :func:`openquake.engine.calculators.post_processing` :param list quantiles: an iterable over the quantile levels to be considered for quantile outputs :param list weights: the weights associated with each realization. If all the elements are `None`, implicit weights are taken into account :param list poes: the poe taken into account for computing loss maps :returns: a tuple with 1) mean loss curve 2) a list of quantile curves """ montecarlo = weights[0] is not None quantile_curves = [] for quantile in quantiles: if montecarlo: q_curve = post_processing.weighted_quantile_curve( curves_poes, weights, quantile) else: q_curve = post_processing.quantile_curve(curves_poes, quantile) quantile_curves.append((losses, q_curve)) # then mean loss curve mean_curve_poes = post_processing.mean_curve(curves_poes, weights) mean_curve = (losses, mean_curve_poes) mean_map = [ scientific.conditional_loss_ratio(losses, mean_curve_poes, poe) for poe in poes ] quantile_maps = [[ scientific.conditional_loss_ratio(losses, poes, poe) for losses, poes in quantile_curves ] for poe in poes] return (mean_curve, quantile_curves, mean_map, quantile_maps)
def get_loss_maps(dstore, kind): """ :param dstore: a DataStore instance :param kind: 'rlzs' or 'stats' """ oq = dstore['oqparam'] name = 'rcurves-%s' % kind if name in dstore: # event_based risk values = dstore['assetcol'].values() _, loss_maps_dt = scientific.build_loss_dtypes( {lt: len(oq.loss_ratios[lt]) for lt in oq.loss_ratios}, oq.conditional_loss_poes, oq.insured_losses) rcurves = dstore[name].value # to support Ubuntu 14 A, R, I = rcurves.shape ins = ['', '_ins'] loss_maps = numpy.zeros((A, R), loss_maps_dt) for ltype, lratios in oq.loss_ratios.items(): for (a, r, i) in indices(A, R, I): rcurve = rcurves[ltype][a, r, i] losses = numpy.array(lratios) * values[ltype][a] tup = tuple( scientific.conditional_loss_ratio(losses, rcurve, poe) for poe in oq.conditional_loss_poes) loss_maps[ltype + ins[i]][a, r] = tup return loss_maps name = 'loss_curves-%s' % kind if name in dstore: # classical_risk loss_curves = dstore[name] loss_maps = scientific.broadcast( scientific.loss_maps, loss_curves, oq.conditional_loss_poes) return loss_maps
def test_beta_distribution(self): loss_ratio_curve = scientific.classical( scientific.VulnerabilityFunction('VF', 'PGA', [0.1, 0.2, 0.3, 0.45, 0.6], [0.05, 0.1, 0.2, 0.4, 0.8], [0.5, 0.4, 0.3, 0.2, 0.1], "BT"), self.hazard_imls, self.hazard_curve, steps=5) poes = [ 0.039334753367700, 0.039125428171600, 0.037674168943300, 0.034759710983600, 0.031030531006800, 0.027179528786300, 0.023629919279000, 0.020549508446100, 0.017953286405900, 0.015789769371500, 0.013989999469800, 0.011228361585000, 0.009252778235140, 0.007776981119440, 0.006618721902640, 0.005678492205870, 0.004293209819490, 0.003423791350520, 0.002851589502850, 0.002371116350380, 0.001901538687150, 0.001145930527350, 0.000834074579570, 0.000755265952955, 0.000655382394929, 0.000422046545856, 0.000266286103069, 0.000124036890130, 3.28497166702e-05, 2.178664466e-06, 0.0 ] numpy.testing.assert_allclose(self.loss_ratios, loss_ratio_curve[0]) numpy.testing.assert_allclose(poes, loss_ratio_curve[1]) asset_value = 2. self.assertAlmostEqual( 0.264870863283, scientific.conditional_loss_ratio(self.loss_ratios, poes, 0.01) * asset_value)
def test_beta_distribution(self): loss_ratio_curve = scientific.classical( scientific.VulnerabilityFunction( [0.1, 0.2, 0.3, 0.45, 0.6], [0.05, 0.1, 0.2, 0.4, 0.8], [0.5, 0.4, 0.3, 0.2, 0.1], "BT"), self.hazard_curve, steps=5) poes = [ 0.039334753367700, 0.039125428171600, 0.037674168943300, 0.034759710983600, 0.031030531006800, 0.027179528786300, 0.023629919279000, 0.020549508446100, 0.017953286405900, 0.015789769371500, 0.013989999469800, 0.011228361585000, 0.009252778235140, 0.007776981119440, 0.006618721902640, 0.005678492205870, 0.004293209819490, 0.003423791350520, 0.002851589502850, 0.002371116350380, 0.001901538687150, 0.001145930527350, 0.000834074579570, 0.000755265952955, 0.000655382394929, 0.000422046545856, 0.000266286103069, 0.000124036890130, 3.28497166702e-05, 2.178664466e-06, 0.0] numpy.testing.assert_allclose(self.loss_ratios, loss_ratio_curve[0]) numpy.testing.assert_allclose(poes, loss_ratio_curve[1]) asset_value = 2. self.assertAlmostEqual( 0.264870863283, scientific.conditional_loss_ratio( self.loss_ratios, poes, 0.01) * asset_value)
def test_conditional_loss_second(self): loss_ratios1, poes1 = zip(*[(0.21, 0.131), (0.24, 0.108), (0.27, 0.089), (0.30, 0.066)]) numpy.testing.assert_allclose( 0.2113043478, scientific.conditional_loss_ratio(loss_ratios1, poes1, 0.13))
def test_conditional_loss_last(self): loss_ratios1, poes1 = zip(*[(0.21, 0.131), (0.24, 0.108), (0.27, 0.089), (0.30, 0.066)]) numpy.testing.assert_allclose( 0.29869565217391303, scientific.conditional_loss_ratio(loss_ratios1, poes1, 0.067))
def test_conditional_loss_last_exact(self): loss_ratios1, poes1 = zip(*[ (0.21, 0.131), (0.24, 0.108), (0.27, 0.089), (0.30, 0.066), ]) numpy.testing.assert_allclose( 0.30, scientific.conditional_loss_ratio(loss_ratios1, poes1, 0.066))
def test_loss_is_zero_if_probability_is_too_high(self): loss_curve = Curve([ (0.21, 0.131), (0.24, 0.108), (0.27, 0.089), (0.30, 0.066), ]) self.assertAlmostEqual( 0.0, scientific.conditional_loss_ratio(loss_curve, 0.200))
def test_conditional_loss_duplicates(self): # we feed compute_conditional_loss with some duplicated data to see if # it's handled correctly loss1 = scientific.conditional_loss_ratio(Curve([ (0.21, 0.131), (0.24, 0.108), (0.27, 0.089), (0.30, 0.066), ]), 0.100) # duplicated y values, different x values, (0.19, 0.131), (0.20, 0.131) # should be skipped loss2 = scientific.conditional_loss_ratio(Curve([ (0.19, 0.131), (0.20, 0.131), (0.21, 0.131), (0.24, 0.108), (0.27, 0.089), (0.30, 0.066), ]), 0.100) numpy.testing.assert_allclose(loss1, loss2)
def test_conditional_loss_computation(self): loss_ratios, poes = zip(*[(0.21, 0.131), (0.24, 0.108), (0.27, 0.089), (0.30, 0.066)]) self.assertAlmostEqual( 0.25263157, scientific.conditional_loss_ratio(loss_ratios, poes, 0.1))
def test_conditional_loss_computation(self): loss_curve = Curve([ (0.21, 0.131), (0.24, 0.108), (0.27, 0.089), (0.30, 0.066), ]) self.assertAlmostEqual(0.2526, scientific.conditional_loss_ratio( loss_curve, 0.100), 4)
def test_mean_based(self): epsilons = scientific.make_epsilons([gmf[0]], seed=1, correlation=0) vulnerability_function_rm = ( scientific.VulnerabilityFunction( 'RM', 'PGA', [0.001, 0.2, 0.3, 0.5, 0.7], [0.01, 0.1, 0.2, 0.4, 0.8], [0.0, 0.0, 0.0, 0.0, 0.0])) vulnerability_function_rc = ( scientific.VulnerabilityFunction( 'RC', 'PGA', [0.001, 0.2, 0.3, 0.5, 0.7], [0.0035, 0.07, 0.14, 0.28, 0.56], [0.0, 0.0, 0.0, 0.0, 0.0])) cr = 50 # curve resolution curve_rm_1 = scientific.event_based( vulnerability_function_rm.apply_to( [gmf[0]], epsilons)[0], 1, cr) curve_rm_2 = scientific.event_based( vulnerability_function_rm.apply_to( [gmf[1]], epsilons)[0], 1, cr) curve_rc = scientific.event_based( vulnerability_function_rc.apply_to( [gmf[2]], epsilons)[0], 1, cr) for i, curve_rm in enumerate([curve_rm_1, curve_rm_2]): conditional_loss = scientific.conditional_loss_ratio( curve_rm[0], curve_rm[1], 0.8) self.assertAlmostEqual([0.0490311, 0.0428061][i], conditional_loss) self.assertAlmostEqual( [0.070219108, 0.04549904][i], scientific.average_loss(curve_rm)) conditional_loss = scientific.conditional_loss_ratio( curve_rc[0], curve_rc[1], 0.8) self.assertAlmostEqual(0.0152273, conditional_loss) self.assertAlmostEqual( 0.0152393, scientific.average_loss(curve_rc))
def test_mean_based(self): epsilons = scientific.make_epsilons([gmf[0]], seed=1, correlation=0) vulnerability_function_rm = ( scientific.VulnerabilityFunction( 'RM', 'PGA', [0.001, 0.2, 0.3, 0.5, 0.7], [0.01, 0.1, 0.2, 0.4, 0.8], [0.0, 0.0, 0.0, 0.0, 0.0])) vulnerability_function_rc = ( scientific.VulnerabilityFunction( 'RC', 'PGA', [0.001, 0.2, 0.3, 0.5, 0.7], [0.0035, 0.07, 0.14, 0.28, 0.56], [0.0, 0.0, 0.0, 0.0, 0.0])) cr = 50 # curve resolution curve_rm_1 = scientific.event_based( vulnerability_function_rm.apply_to( [gmf[0]], epsilons)[0], 50, 50, cr) curve_rm_2 = scientific.event_based( vulnerability_function_rm.apply_to( [gmf[1]], epsilons)[0], 50, 50, cr) curve_rc = scientific.event_based( vulnerability_function_rc.apply_to( [gmf[2]], epsilons)[0], 50, 50, cr) for i, curve_rm in enumerate([curve_rm_1, curve_rm_2]): conditional_loss = scientific.conditional_loss_ratio( curve_rm[0], curve_rm[1], 0.8) self.assertAlmostEqual([0.0490311, 0.0428061][i], conditional_loss) self.assertAlmostEqual( [0.070219108, 0.04549904][i], scientific.average_loss(curve_rm)) conditional_loss = scientific.conditional_loss_ratio( curve_rc[0], curve_rc[1], 0.8) self.assertAlmostEqual(0.0152273, conditional_loss) self.assertAlmostEqual( 0.0152393, scientific.average_loss(curve_rc))
def test_conditional_loss_computation(self): loss_ratios, poes = zip(*[ (0.21, 0.131), (0.24, 0.108), (0.27, 0.089), (0.30, 0.066), ]) self.assertAlmostEqual( 0.25263157, scientific.conditional_loss_ratio(loss_ratios, poes, 0.1))
def test_mean_based(self): vulnerability_function_rm = ( scientific.VulnerabilityFunction( [0.001, 0.2, 0.3, 0.5, 0.7], [0.01, 0.1, 0.2, 0.4, 0.8], [0.0, 0.0, 0.0, 0.0, 0.0], "LN")) vulnerability_function_rc = ( scientific.VulnerabilityFunction( [0.001, 0.2, 0.3, 0.5, 0.7], [0.0035, 0.07, 0.14, 0.28, 0.56], [0.0, 0.0, 0.0, 0.0, 0.0], "LN")) curve_rm_1 = scientific.event_based( scientific.vulnerability_function_applier( vulnerability_function_rm, [gmf[0]])[0], 50, 50) curve_rm_2 = scientific.event_based( scientific.vulnerability_function_applier( vulnerability_function_rm, [gmf[1]])[0], 50, 50) curve_rc = scientific.event_based( scientific.vulnerability_function_applier( vulnerability_function_rc, [gmf[2]])[0], 50, 50) for i, curve_rm in enumerate([curve_rm_1, curve_rm_2]): conditional_loss = scientific.conditional_loss_ratio( curve_rm[0], curve_rm[1], 0.8) self.assertAlmostEqual([0.0490311, 0.0428061][i], conditional_loss) self.assertAlmostEqual( [0.070219108, 0.04549904][i], scientific.average_loss(curve_rm[0], curve_rm[1])) conditional_loss = scientific.conditional_loss_ratio( curve_rc[0], curve_rc[1], 0.8) self.assertAlmostEqual(0.0152273, conditional_loss) self.assertAlmostEqual( 0.0152393, scientific.average_loss(curve_rc[0], curve_rc[1]))
def test_lognormal_distribution(self): calculator = api.Classical( scientific.VulnerabilityFunction( [0.1, 0.2, 0.3, 0.45, 0.6], [0.05, 0.1, 0.2, 0.4, 0.8], [0.5, 0.4, 0.3, 0.2, 0.1], "LN"), steps=5) # api.ConditionalLosses(, # asset_value = 2 [loss_ratio_curve] = calculator([self.hazard_curve]) poes = [ 0.039334753367700, 0.039319630829000, 0.038454063967300, 0.035355568337500, 0.031080935951500, 0.026921966116900, 0.023309185424900, 0.020254928647300, 0.017692604455300, 0.015561622176500, 0.013804482989300, 0.011159985044500, 0.009272778209290, 0.007803862103290, 0.006601047489540, 0.005621048101030, 0.004262944952210, 0.003478101875460, 0.002916428961850, 0.002375461660340, 0.001854772287220, 0.001133190711620, 0.000862358303705, 0.000784269030443, 0.000660062215754, 0.000374938542785, 0.000230249004393, 0.000122823654476, 5.72790058705e-05, 2.35807221322e-05, 8.66392324535e-06] self.assertEqual( curve.Curve(zip(self.loss_ratios, poes)), loss_ratio_curve) asset_value = 2. conditional_losses = dict([ (poe, scientific.conditional_loss_ratio( loss_ratio_curve, poe) * asset_value) for poe in [0.01, 0.02, 0.05]]) self.assertAlmostEqual(0.264586283238, conditional_losses[0.01]) self.assertAlmostEqual(0.141989823521, conditional_losses[0.02]) self.assertAlmostEqual(0.0, conditional_losses[0.05])
def individual_outputs(loss_type, unit, params, profile): event_loss_table = collections.Counter() p = profile('getting gmvs and ruptures') assets, (ground_motion_values, rupture_ids) = unit.getter(p) with profile('computing losses, loss curves and maps'): loss_matrix, curves = unit.calc(ground_motion_values) maps = [[scientific.conditional_loss_ratio(losses, poes, poe) for losses, poes in curves] for poe in params.conditional_loss_poes] for i, asset in enumerate(assets): for j, rupture_id in enumerate(rupture_ids): event_loss_table[rupture_id] += ( loss_matrix[i][j] * asset.value(loss_type)) return UnitOutputs( assets, loss_matrix, rupture_ids, curves, maps, event_loss_table)
def test_lognormal_distribution(self): loss_ratio_curve = scientific.classical( scientific.VulnerabilityFunction('VF', 'PGA', [0.1, 0.2, 0.3, 0.45, 0.6], [0.05, 0.1, 0.2, 0.4, 0.8], [0.5, 0.4, 0.3, 0.2, 0.1]), self.hazard_imls, self.hazard_curve, steps=5) poes = [ 0.039334753367700, 0.039319630829000, 0.038454063967300, 0.035355568337500, 0.031080935951500, 0.026921966116900, 0.023309185424900, 0.020254928647300, 0.017692604455300, 0.015561622176500, 0.013804482989300, 0.011159985044500, 0.009272778209290, 0.007803862103290, 0.006601047489540, 0.005621048101030, 0.004262944952210, 0.003478101875460, 0.002916428961850, 0.002375461660340, 0.001854772287220, 0.001133190711620, 0.000862358303705, 0.000784269030443, 0.000660062215754, 0.000374938542785, 0.000230249004393, 0.000122823654476, 5.72790058705e-05, 2.35807221322e-05, 8.66392324535e-06 ] numpy.testing.assert_allclose(self.loss_ratios, loss_ratio_curve[0]) numpy.testing.assert_allclose(poes, loss_ratio_curve[1]) asset_value = 2. conditional_losses = dict([ (poe, scientific.conditional_loss_ratio(self.loss_ratios, poes, poe) * asset_value) for poe in [0.01, 0.02, 0.05] ]) self.assertAlmostEqual(0.264586283238, conditional_losses[0.01]) self.assertAlmostEqual(0.141989823521, conditional_losses[0.02]) self.assertAlmostEqual(0.0, conditional_losses[0.05])
def single_map(curve, poe): losses, poes = curve return scientific.conditional_loss_ratio(losses, poes, poe)
def event_based(job_id, hazard, seed, vulnerability_function, output_containers, conditional_loss_poes, insured_losses, time_span, tses, loss_curve_resolution, asset_correlation, hazard_montecarlo_p): """ Celery task for the event based risk calculator. :param job_id: the id of the current :class:`openquake.engine.db.models.OqJob` :param dict hazard: A dictionary mapping IDs of :class:`openquake.engine.db.models.Output` (with output_type set to 'gmf_collection') to a tuple where the first element is an instance of :class:`..hazard_getters.GroundMotionValuesGetter`, and the second element is the corresponding weight. :param seed: the seed used to initialize the rng :param dict output_containers: a dictionary mapping hazard Output ID to a list (a, b, c, d) where a is the ID of the :class:`openquake.engine.db.models.LossCurve` output container used to store the computed loss curves; b is the dictionary poe->ID of the :class:`openquake.engine.db.models.LossMap` output container used to store the computed loss maps; c is the same as a but for insured losses; d is the ID of the :class:`openquake.engine.db.models.AggregateLossCurve` output container used to store the computed loss curves :param conditional_loss_poes: The poes taken into accout to compute the loss maps :param bool insured_losses: True if insured losses should be computed :param time_span: the time span considered :param tses: time of the stochastic event set :param loss_curve_resolution: the curve resolution, i.e. the number of points which defines the loss curves :param float asset_correlation: a number ranging from 0 to 1 representing the correlation between the generated loss ratios """ loss_ratio_curves = OrderedDict() event_loss_table = dict() for hazard_output_id, hazard_data in hazard.items(): hazard_getter, _ = hazard_data (loss_curve_id, loss_map_ids, mean_loss_curve_id, quantile_loss_curve_ids, insured_curve_id, aggregate_loss_curve_id) = ( output_containers[hazard_output_id]) # FIXME(lp). We should not pass the exact same seed for # different hazard calculator = api.ProbabilisticEventBased( vulnerability_function, curve_resolution=loss_curve_resolution, time_span=time_span, tses=tses, seed=seed, correlation=asset_correlation) with logs.tracing('getting input data from db'): assets, gmvs_ruptures, missings = hazard_getter() if len(assets): ground_motion_values = numpy.array(gmvs_ruptures)[:, 0] rupture_id_matrix = numpy.array(gmvs_ruptures)[:, 1] else: # we are relying on the fact that if all the hazard_getter # in this task will either return some results or they all # return an empty result set. logs.LOG.info("Exit from task as no asset could be processed") base.signal_task_complete( job_id=job_id, event_loss_table=dict(), num_items=len(missings)) return with logs.tracing('computing risk'): loss_ratio_matrix, loss_ratio_curves[hazard_output_id] = ( calculator(ground_motion_values)) with logs.tracing('writing results'): with db.transaction.commit_on_success(using='reslt_writer'): for i, loss_ratio_curve in enumerate( loss_ratio_curves[hazard_output_id]): asset = assets[i] # loss curves general.write_loss_curve( loss_curve_id, asset, loss_ratio_curve) # loss maps for poe in conditional_loss_poes: general.write_loss_map_data( loss_map_ids[poe], asset, scientific.conditional_loss_ratio( loss_ratio_curve, poe)) # insured losses if insured_losses: insured_loss_curve = scientific.event_based( scientific.insured_losses( loss_ratio_matrix[i], asset.value, asset.deductible, asset.ins_limit), tses, time_span, loss_curve_resolution) insured_loss_curve.abscissae = ( insured_loss_curve.abscissae / asset.value) general.write_loss_curve( insured_curve_id, asset, insured_loss_curve) # update the event loss table of this task for i, asset in enumerate(assets): for j, rupture_id in enumerate(rupture_id_matrix[i]): loss = loss_ratio_matrix[i][j] * asset.value event_loss_table[rupture_id] = ( event_loss_table.get(rupture_id, 0) + loss) # update the aggregate losses aggregate_losses = sum( loss_ratio_matrix[i] * asset.value for i, asset in enumerate(assets)) general.update_aggregate_losses( aggregate_loss_curve_id, aggregate_losses) # compute mean and quantile loss curves if multiple hazard # realizations are computed if len(hazard) > 1 and (mean_loss_curve_id or quantile_loss_curve_ids): weights = [data[1] for _, data in hazard.items()] with logs.tracing('writing curve statistics'): with db.transaction.commit_on_success(using='reslt_writer'): loss_ratio_curve_matrix = loss_ratio_curves.values() # here we are relying on the fact that assets do not # change across different logic tree realizations (as # the hazard grid does not change, so the hazard # getters always returns the same assets) for i, asset in enumerate(assets): general.curve_statistics( asset, loss_ratio_curve_matrix[i], weights, mean_loss_curve_id, quantile_loss_curve_ids, hazard_montecarlo_p, assume_equal="image") base.signal_task_complete(job_id=job_id, num_items=len(assets) + len(missings), event_loss_table=event_loss_table)
def test_loss_is_max_if_probability_is_too_low(self): self.assertAlmostEqual( 0.30, scientific.conditional_loss_ratio( [0.21, 0.24, 0.27, 0.30], [0.131, 0.108, 0.089, 0.066], .01))
def test_loss_is_zero_if_probability_is_too_high(self): self.assertAlmostEqual( 0.00, scientific.conditional_loss_ratio( [0.21, 0.24, 0.27, 0.30], [0.131, 0.108, 0.089, 0.066], .200))
def classical(job_id, hazard, vulnerability_function, output_containers, lrem_steps_per_interval, conditional_loss_poes, hazard_montecarlo_p): """ Celery task for the classical risk calculator. Instantiates risklib calculators, computes losses for the given assets and stores the results to db in a single transaction. :param int job_id: ID of the currently running job :param dict hazard: A dictionary mapping IDs of :class:`openquake.engine.db.models.Output` (with output_type set to 'hazard_curve') to a tuple where the first element is an instance of :class:`..hazard_getters.HazardCurveGetter`, and the second element is the corresponding weight. :param dict output_containers: A dictionary mapping hazard Output ID to a tuple (a, b) where a is the ID of the :class:`openquake.engine.db.models.LossCurve` output container used to store the computed loss curves and b is a dictionary that maps poe to ID of the :class:`openquake.engine.db.models.LossMap` used to store the loss maps :param int lrem_steps_per_interval: Steps per interval used to compute the Loss Ratio Exceedance matrix :param conditional_loss_poes: The poes taken into account to compute the loss maps :param bool hazard_montecarlo_p: (meaningful only if curve statistics are computed). Wheter or not the hazard calculation is montecarlo based """ asset_outputs = OrderedDict() calculator = api.Classical( vulnerability_function, lrem_steps_per_interval) for hazard_output_id, hazard_data in hazard.items(): # the second item of the tuple is the weight of the hazard (at # this moment we are not interested in it) hazard_getter, _ = hazard_data (loss_curve_id, loss_map_ids, mean_loss_curve_id, quantile_loss_curve_ids) = ( output_containers[hazard_output_id]) with logs.tracing('getting hazard'): assets, hazard_curves, missings = hazard_getter() with logs.tracing('computing risk over %d assets' % len(assets)): asset_outputs[hazard_output_id] = calculator(hazard_curves) with logs.tracing('writing results'): with transaction.commit_on_success(using='reslt_writer'): for i, loss_ratio_curve in enumerate( asset_outputs[hazard_output_id]): asset = assets[i] # Write Loss Curves general.write_loss_curve( loss_curve_id, asset, loss_ratio_curve) # Then conditional loss maps for poe in conditional_loss_poes: general.write_loss_map_data( loss_map_ids[poe], asset, scientific.conditional_loss_ratio( loss_ratio_curve, poe)) if len(hazard) > 1 and (mean_loss_curve_id or quantile_loss_curve_ids): weights = [data[1] for _, data in hazard.items()] with logs.tracing('writing curve statistics'): with transaction.commit_on_success(using='reslt_writer'): loss_ratio_curve_matrix = asset_outputs.values() for i, asset in enumerate(assets): general.curve_statistics( asset, loss_ratio_curve_matrix[i], weights, mean_loss_curve_id, quantile_loss_curve_ids, hazard_montecarlo_p, assume_equal="support") base.signal_task_complete(job_id=job_id, num_items=len(assets) + len(missings))