示例#1
0
 def setUpClass(cls):
     assets = [
         asset('a1', 101),
         asset('a2', 151),
         asset('a3', 91),
         asset('a4', 81)
     ]
     asset_refs = [a.id for a in assets]
     outputs = []
     weights = [0.3, 0.7]
     baselosses = numpy.array([.10, .14, .17, .20, .21])
     for i, w in enumerate(weights):
         lc = loss_curves(assets, baselosses, i)
         out = scientific.Output(asset_refs,
                                 'structural',
                                 weight=w,
                                 loss_curves=lc,
                                 insured_curves=None,
                                 average_losses=[.1, .12, .13, .9],
                                 average_insured_losses=None)
         outputs.append(out)
     cls.builder = scientific.StatsBuilder(
         quantiles=[0.1, 0.9],
         conditional_loss_poes=[0.35, 0.24, 0.13],
         poes_disagg=[],
         curve_resolution=len(baselosses))
     cls.stats = cls.builder.build(outputs)
示例#2
0
    def __call__(self,
                 loss_type,
                 assets,
                 hazard_curve,
                 _epsilons=None,
                 _eids=None):
        """
        :param loss_type: the loss type
        :param assets: a list of N assets of the same taxonomy
        :param hazard_curve: an hazard curve array
        :returns: an array of N assets and an array of N x D elements

        where N is the number of points and D the number of damage states.
        """
        ffl = self.risk_functions[loss_type]
        hazard_imls = self.hazard_imtls[ffl.imt]
        damage = scientific.classical_damage(
            ffl,
            hazard_imls,
            hazard_curve,
            investigation_time=self.investigation_time,
            risk_investigation_time=self.risk_investigation_time)
        return scientific.Output(assets,
                                 loss_type,
                                 damages=[a.number * damage for a in assets])
示例#3
0
    def __call__(self, loss_type, assets, gmfs, epsilons, event_ids):
        self.assets = assets

        original_loss_curves = utils.numpy_map(
            self.curves, self.vf_orig[loss_type].apply_to(gmfs, epsilons))
        retrofitted_loss_curves = utils.numpy_map(
            self.curves, self.vf_retro[loss_type].apply_to(gmfs, epsilons))

        eal_original = utils.numpy_map(scientific.average_loss,
                                       original_loss_curves)
        eal_retrofitted = utils.numpy_map(scientific.average_loss,
                                          retrofitted_loss_curves)

        bcr_results = [
            scientific.bcr(eal_original[i], eal_retrofitted[i],
                           self.interest_rate, self.asset_life_expectancy,
                           asset.value(loss_type),
                           asset.retrofitted(loss_type))
            for i, asset in enumerate(assets)
        ]

        return scientific.Output(assets,
                                 loss_type,
                                 data=list(
                                     zip(eal_original, eal_retrofitted,
                                         bcr_results)))
示例#4
0
 def _collect_all_data(self):
     # return a list of list of outputs
     if 'rcurves-rlzs' not in self.datastore:
         return []
     all_data = []
     assets = self.assetcol['asset_ref']
     rlzs = self.rlzs_assoc.realizations
     avg_losses = self.datastore['avg_losses-rlzs'].value
     r_curves = self.datastore['rcurves-rlzs'].value
     insured_losses = self.oqparam.insured_losses
     i_curves = (self.datastore['icurves-rlzs'].value
                 if insured_losses else None)
     for loss_type, cbuilder in zip(self.riskmodel.loss_types,
                                    self.riskmodel.curve_builders):
         avglosses = avg_losses[loss_type]
         rcurves = r_curves[loss_type]
         asset_values = self.assetcol[loss_type]
         data = []
         for rlz in rlzs:
             average_losses = avglosses[:, rlz.ordinal]
             out = scientific.Output(
                 assets,
                 loss_type,
                 rlz.ordinal,
                 rlz.weight,
                 loss_curves=old_loss_curves(asset_values, rcurves,
                                             rlz.ordinal, cbuilder.ratios),
                 insured_curves=old_loss_curves(
                     asset_values, i_curves[loss_type], rlz.ordinal,
                     cbuilder.ratios) if i_curves else None,
                 average_losses=average_losses[:, 0],
                 average_insured_losses=average_losses[:, 1])
             data.append(out)
         all_data.append(data)
     return all_data
示例#5
0
    def __call__(self, loss_type, assets, hazard, _eps=None, _tags=None):
        self.assets = assets

        original_loss_curves = utils.numpy_map(self.curves_orig[loss_type],
                                               hazard)
        retrofitted_loss_curves = utils.numpy_map(self.curves_retro[loss_type],
                                                  hazard)

        eal_original = utils.numpy_map(scientific.average_loss,
                                       original_loss_curves)

        eal_retrofitted = utils.numpy_map(scientific.average_loss,
                                          retrofitted_loss_curves)

        bcr_results = [
            scientific.bcr(eal_original[i], eal_retrofitted[i],
                           self.interest_rate, self.asset_life_expectancy,
                           asset.value(loss_type),
                           asset.retrofitted(loss_type))
            for i, asset in enumerate(assets)
        ]

        return scientific.Output(assets,
                                 loss_type,
                                 data=list(
                                     zip(eal_original, eal_retrofitted,
                                         bcr_results)))
示例#6
0
 def build_stats(self, loss_curve_key):
     """
     Compute all statistics for the specified assets starting from the
     stored loss curves. Yield a statistical output object for each
     loss type.
     """
     oq = self.oqparam
     rlzs = self.rlzs_assoc.realizations
     stats = scientific.StatsBuilder(
         oq.quantile_loss_curves, oq.conditional_loss_poes, [],
         scientific.normalize_curves_eb)
     # NB: should we encounter memory issues in the future, the easy
     # solution is to split the specific assets in blocks and perform
     # the computation one block at the time
     for loss_type in self.riskmodel.get_loss_types():
         outputs = []
         for rlz in rlzs:
             key = '%s-rlzs/%s' % (loss_curve_key, rlz.uid)
             lcs = self.datastore[key][loss_type]
             assets = [None] if key.startswith('agg') else self.assets
             losses_poes = numpy.array(  # -> shape (N, 2, C)
                 [lcs['losses'], lcs['poes']]).transpose(1, 0, 2)
             out = scientific.Output(
                 assets, loss_type, rlz.ordinal, rlz.weight,
                 loss_curves=losses_poes, insured_curves=None)
             outputs.append(out)
         yield stats.build(outputs)
示例#7
0
    def __call__(self, loss_type, assets, ground_motion_values, epsilons,
                 event_ids):
        """
        :param str loss_type: the loss type considered

        :param assets:
           assets is an iterator over
           :class:`openquake.risklib.scientific.Asset` instances

        :param ground_motion_values:
           a numpy array with ground_motion_values of shape N x R

        :param epsilons:
           a numpy array with stochastic values of shape N x R

        :param event_ids:
           a numpy array of R event ID (integer)

        :returns:
            a :class:
            `openquake.risklib.scientific.ProbabilisticEventBased.Output`
            instance.
        """
        n = len(assets)
        loss_matrix = self.risk_functions[loss_type].apply_to(
            ground_motion_values, epsilons)
        # sum on ruptures; compute the fractional losses
        average_losses = loss_matrix.sum(axis=1) * self.ses_ratio
        values = get_values(loss_type, assets)
        ela = loss_matrix.T * values  # matrix with T x N elements
        cb = self.riskmodel.curve_builders[self.riskmodel.lti[loss_type]]
        # FIXME: ugly workaround for qa_tests.event_based_test; in Ubuntu 12.04
        # MagicMock does not work well, so len(cb.ratios) gives an error
        nratios = 1 if isinstance(cb, mock.Mock) else len(cb.ratios)
        if self.insured_losses and loss_type != 'fatalities':
            deductibles = numpy.array(
                [a.deductible(loss_type) for a in assets])
            limits = numpy.array(
                [a.insurance_limit(loss_type) for a in assets])
            ilm = utils.numpy_map(scientific.insured_losses, loss_matrix,
                                  deductibles, limits)
            icounts = cb.build_counts(ilm)
        else:  # build a NaN matrix of size N x T
            T = len(ground_motion_values[0])
            ilm = numpy.empty((n, T))
            ilm.fill(numpy.nan)
            icounts = numpy.empty((n, nratios))
            icounts.fill(numpy.nan)
        ila = ilm.T * values
        average_insured_losses = ilm.sum(axis=1) * self.ses_ratio
        return scientific.Output(assets,
                                 loss_type,
                                 event_loss_per_asset=ela,
                                 insured_loss_per_asset=ila,
                                 average_losses=average_losses,
                                 average_insured_losses=average_insured_losses,
                                 counts_matrix=cb.build_counts(loss_matrix),
                                 insured_counts_matrix=icounts,
                                 tags=event_ids)
示例#8
0
    def __call__(self,
                 loss_type,
                 assets,
                 hazard_curve,
                 _epsilons=None,
                 _eids=None):
        """
        :param str loss_type:
            the loss type considered
        :param assets:
            assets is an iterator over N
            :class:`openquake.risklib.scientific.Asset` instances
        :param hazard_curve:
            an array of poes
        :param _epsilons:
            ignored, here only for API compatibility with other calculators
        :returns:
            a :class:`openquake.risklib.scientific.Classical.Output` instance.
        """
        n = len(assets)
        vf = self.risk_functions[loss_type]
        imls = self.hazard_imtls[vf.imt]
        curves = [
            scientific.classical(vf, imls, hazard_curve,
                                 self.lrem_steps_per_interval)
        ] * n
        average_losses = utils.numpy_map(scientific.average_loss, curves)
        maps = scientific.loss_map_matrix(self.conditional_loss_poes, curves)
        values = get_values(loss_type, assets)

        if self.insured_losses and loss_type != 'occupants':
            deductibles = [a.deductible(loss_type) for a in assets]
            limits = [a.insurance_limit(loss_type) for a in assets]

            insured_curves = rescale(
                utils.numpy_map(scientific.insured_loss_curve, curves,
                                deductibles, limits), values)
            average_insured_losses = utils.numpy_map(scientific.average_loss,
                                                     insured_curves)
        else:
            insured_curves = None
            average_insured_losses = None

        return scientific.Output(assets,
                                 loss_type,
                                 loss_curves=rescale(numpy.array(curves),
                                                     values),
                                 average_losses=values * average_losses,
                                 insured_curves=insured_curves,
                                 average_insured_losses=average_insured_losses,
                                 loss_maps=values * maps)
示例#9
0
    def __call__(self, loss_type, assets, ground_motion_values, epsilons,
                 eids):
        """
        :param str loss_type: the loss type considered

        :param assets:
           a list with a single asset

        :param ground_motion_values:
           an array of E ground_motion_values

        :param epsilons:
           a list with a single array of E stochastic values

        :param eids:
           a numpy array of E rupture IDs

        :returns:
            a :class:
            `openquake.risklib.scientific.ProbabilisticEventBased.Output`
            instance.
        """
        E = len(eids)
        I = self.insured_losses + 1
        loss_ratios = numpy.zeros((E, I), F32)
        asset = assets[0]  # the only one
        loss_ratios[:, 0] = ratios = self.risk_functions[loss_type].apply_to(
            [ground_motion_values], epsilons)[0]  # shape E
        cb = self.compositemodel.curve_builders[
            self.compositemodel.lti[loss_type]]
        if self.insured_losses and loss_type != 'occupants':
            deductible = asset.deductible(loss_type)
            limit = asset.insurance_limit(loss_type)
            ilm = scientific.insured_losses(ratios, deductible, limit)
            loss_ratios[:, 1] = ilm
            icounts = cb.build_counts(ilm)
        else:
            # FIXME: ugly workaround for qa_tests.event_based_test; in Ubuntu
            # 12.04 MagicMock does not work well, so len(cb.ratios) gives error
            nratios = 1 if isinstance(cb, mock.Mock) else len(cb.ratios)
            icounts = numpy.empty(nratios)
            icounts.fill(numpy.nan)
        return scientific.Output(assets,
                                 loss_type,
                                 losses=loss_ratios * asset.value(loss_type),
                                 average_loss=loss_ratios.sum(axis=0) *
                                 self.ses_ratio,
                                 counts_matrix=cb.build_counts(loss_ratios),
                                 insured_counts_matrix=icounts,
                                 eids=eids)
示例#10
0
    def __call__(self, loss_type, assets, gmfs, _epsilons=None, _tags=None):
        """
        :param loss_type: the loss type
        :param assets: a list of N assets of the same taxonomy
        :param gmfs: an array of N x E elements
        :returns: an array of N assets and an array of N x E x D elements

        where N is the number of points, E the number of events
        and D the number of damage states.
        """
        ffs = self.risk_functions[loss_type]
        damages = numpy.array(
            [[scientific.scenario_damage(ffs, gmv) for gmv in gmvs]
             for gmvs in gmfs])
        return scientific.Output(assets, loss_type, damages=damages)
示例#11
0
    def build_agg_curve_stats(self, builder, agg_curve, loss_curve_dt):
        """
        Build and save `agg_curve-stats` in the HDF5 file.

        :param builder:
            :class:`openquake.risklib.scientific.StatsBuilder` instance
        :param agg_curve:
            array of aggregate curves, one per realization
        :param loss_curve_dt:
            numpy dtype for loss curves
        """
        rlzs = self.datastore['csm_info'].get_rlzs_assoc().realizations
        Q1 = len(builder.mean_quantiles)
        agg_curve_stats = numpy.zeros(Q1, loss_curve_dt)
        for l, loss_type in enumerate(self.riskmodel.loss_types):
            agg_curve_lt = agg_curve[loss_type]
            outputs = []
            for rlz in rlzs:
                curve = agg_curve_lt[rlz.ordinal]
                average_loss = curve['avg']
                loss_curve = (curve['losses'], curve['poes'])
                if self.oqparam.insured_losses:
                    average_insured_loss = curve['avg_ins']
                    insured_curves = [(curve['losses_ins'], curve['poes_ins'])]
                else:
                    average_insured_loss = None
                    insured_curves = None
                out = scientific.Output(
                    [None],
                    loss_type,
                    rlz.ordinal,
                    rlz.weight,
                    loss_curves=[loss_curve],
                    insured_curves=insured_curves,
                    average_losses=[average_loss],
                    average_insured_losses=[average_insured_loss])
                outputs.append(out)
            stats = builder.build(outputs)
            curves, _maps = builder.get_curves_maps(stats)  # shape (Q1, 1)
            acs = agg_curve_stats[loss_type]
            for i, statname in enumerate(builder.mean_quantiles):
                for name in acs.dtype.names:
                    acs[name][i] = curves[name][i]

        # saving agg_curve_stats
        self.datastore['agg_curve-stats'] = agg_curve_stats
        self.datastore['agg_curve-stats'].attrs['nbytes'] = (
            agg_curve_stats.nbytes)
示例#12
0
    def __call__(self, loss_type, assets, gmvs, _eps=None):
        """
        :param loss_type: the loss type
        :param assets: a list of N assets of the same taxonomy
        :param gmvs: an array of E elements
        :param _eps: dummy parameter, unused
        :returns: an array of N assets and an array of N x E x D elements

        where N is the number of points, E the number of events
        and D the number of damage states.
        """
        n = len(assets)
        ffs = self.risk_functions[loss_type]
        damages = numpy.array(
            [scientific.scenario_damage(ffs, gmv) for gmv in gmvs])
        return scientific.Output(assets, loss_type, damages=[damages] * n)
示例#13
0
    def __call__(self,
                 loss_type,
                 assets,
                 ground_motion_values,
                 epsilons,
                 _eids=None):
        values = get_values(loss_type, assets, self.time_event)
        ok = ~numpy.isnan(values)
        if not ok.any():
            # there are no assets with a value
            return
        # there may be assets without a value
        missing_value = not ok.all()
        if missing_value:
            assets = assets[ok]
            epsilons = epsilons[ok]

        # a matrix of N x E elements
        loss_ratio_matrix = self.risk_functions[loss_type].apply_to(
            [ground_motion_values] * len(assets), epsilons)
        # another matrix of N x E elements
        loss_matrix = (loss_ratio_matrix.T * values).T
        # an array of E elements
        aggregate_losses = loss_matrix.sum(axis=0)

        if self.insured_losses and loss_type != "occupants":
            deductibles = [a.deductible(loss_type) for a in assets]
            limits = [a.insurance_limit(loss_type) for a in assets]
            insured_loss_ratio_matrix = utils.numpy_map(
                scientific.insured_losses, loss_ratio_matrix, deductibles,
                limits)
            insured_loss_matrix = (insured_loss_ratio_matrix.T * values).T
        else:
            insured_loss_matrix = numpy.empty_like(loss_ratio_matrix)
            insured_loss_matrix.fill(numpy.nan)

        # aggregating per asset, getting a vector of E elements
        insured_losses = insured_loss_matrix.sum(axis=0)
        return scientific.Output(assets,
                                 loss_type,
                                 loss_matrix=loss_matrix,
                                 loss_ratio_matrix=loss_ratio_matrix,
                                 aggregate_losses=aggregate_losses,
                                 insured_loss_matrix=insured_loss_matrix,
                                 insured_losses=insured_losses)
示例#14
0
    def __call__(self, loss_type, assets, hazard, _eps=None, _eids=None):
        """
        :param loss_type: the loss type
        :param assets: a list of N assets of the same taxonomy
        :param hazard: an hazard curve
        :param _eps: dummy parameter, unused
        :param _eids: dummy parameter, unused
        :returns: a :class:`openquake.risklib.scientific.Output` instance
        """
        n = len(assets)
        self.assets = assets
        vf = self.risk_functions[loss_type]
        imls = self.hazard_imtls[vf.imt]
        vf_retro = self.retro_functions[loss_type]
        curves_orig = functools.partial(scientific.classical,
                                        vf,
                                        imls,
                                        steps=self.lrem_steps_per_interval)
        curves_retro = functools.partial(scientific.classical,
                                         vf_retro,
                                         imls,
                                         steps=self.lrem_steps_per_interval)
        original_loss_curves = utils.numpy_map(curves_orig, [hazard] * n)
        retrofitted_loss_curves = utils.numpy_map(curves_retro, [hazard] * n)

        eal_original = utils.numpy_map(scientific.average_loss,
                                       original_loss_curves)

        eal_retrofitted = utils.numpy_map(scientific.average_loss,
                                          retrofitted_loss_curves)

        bcr_results = [
            scientific.bcr(eal_original[i], eal_retrofitted[i],
                           self.interest_rate, self.asset_life_expectancy,
                           asset.value(loss_type),
                           asset.retrofitted(loss_type))
            for i, asset in enumerate(assets)
        ]

        return scientific.Output(assets,
                                 loss_type,
                                 data=list(
                                     zip(eal_original, eal_retrofitted,
                                         bcr_results)))
示例#15
0
    def __call__(self, loss_type, assets, ground_motion_values, epsgetter):
        epsilons = epsgetter()
        values = get_values(loss_type, assets, self.time_event)
        ok = ~numpy.isnan(values)
        if not ok.any():
            # there are no assets with a value
            return
        # there may be assets without a value
        missing_value = not ok.all()
        if missing_value:
            assets = assets[ok]
            epsilons = epsilons[ok]

        # a matrix of N x E elements
        vf = self.risk_functions[loss_type]
        means, covs, idxs = vf.interpolate(ground_motion_values)
        loss_ratio_matrix = numpy.zeros((len(assets), len(epsilons[0])))
        for i, eps in enumerate(epsilons):
            loss_ratio_matrix[i, idxs] = vf.sample(means, covs, idxs, eps)
        # another matrix of N x E elements
        loss_matrix = (loss_ratio_matrix.T * values).T
        # an array of E elements
        aggregate_losses = loss_matrix.sum(axis=0)

        if self.insured_losses and loss_type != "occupants":
            deductibles = [a.deductible(loss_type) for a in assets]
            limits = [a.insurance_limit(loss_type) for a in assets]
            insured_loss_ratio_matrix = utils.numpy_map(
                scientific.insured_losses, loss_ratio_matrix, deductibles,
                limits)
            insured_loss_matrix = (insured_loss_ratio_matrix.T * values).T
        else:
            insured_loss_matrix = numpy.empty_like(loss_ratio_matrix)
            insured_loss_matrix.fill(numpy.nan)

        # aggregating per asset, getting a vector of E elements
        insured_losses = insured_loss_matrix.sum(axis=0)
        return scientific.Output(assets,
                                 loss_type,
                                 loss_matrix=loss_matrix,
                                 loss_ratio_matrix=loss_ratio_matrix,
                                 aggregate_losses=aggregate_losses,
                                 insured_loss_matrix=insured_loss_matrix,
                                 insured_losses=insured_losses)
示例#16
0
    def __call__(self,
                 loss_type,
                 assets,
                 hazard_curves,
                 _epsilons=None,
                 _tags=None):
        """
        :param str loss_type:
            the loss type considered
        :param assets:
            assets is an iterator over N
            :class:`openquake.risklib.scientific.Asset` instances
        :param hazard_curves:
            an iterator over N arrays with the poes
        :param _epsilons:
            ignored, here only for API compatibility with other calculators
        :returns:
            a :class:`openquake.risklib.scientific.Classical.Output` instance.
        """
        curves = utils.numpy_map(self.curves[loss_type], hazard_curves)
        average_losses = utils.numpy_map(scientific.average_loss, curves)
        maps = scientific.loss_map_matrix(self.conditional_loss_poes, curves)
        fractions = scientific.loss_map_matrix(self.poes_disagg, curves)

        if self.insured_losses and loss_type != 'fatalities':
            deductibles = [a.deductible(loss_type) for a in assets]
            limits = [a.insurance_limit(loss_type) for a in assets]

            insured_curves = utils.numpy_map(scientific.insured_loss_curve,
                                             curves, deductibles, limits)
            average_insured_losses = utils.numpy_map(scientific.average_loss,
                                                     insured_curves)
        else:
            insured_curves = None
            average_insured_losses = None

        return scientific.Output(assets,
                                 loss_type,
                                 loss_curves=curves,
                                 average_losses=average_losses,
                                 insured_curves=insured_curves,
                                 average_insured_losses=average_insured_losses,
                                 loss_maps=maps,
                                 loss_fractions=fractions)
示例#17
0
    def __call__(self,
                 loss_type,
                 assets,
                 hazard_curves,
                 _epsilons=None,
                 _tags=None):
        """
        :param loss_type: the string 'damage'
        :param assets: a list of N assets of the same taxonomy
        :param hazard_curves: an array of N x E elements
        :returns: an array of N assets and an array of N x D elements

        where N is the number of points and D the number of damage states.
        """
        fractions = utils.numpy_map(self.curves, hazard_curves)
        damages = [
            asset.number * fraction
            for asset, fraction in zip(assets, fractions)
        ]
        return scientific.Output(assets, 'damage', damages=damages)
示例#18
0
 def _collect_all_data(self):
     # return a list of list of outputs
     if 'rcurves-rlzs' not in self.datastore:
         return []
     all_data = []
     assets = self.datastore['asset_refs'].value[self.assetcol.array['idx']]
     rlzs = self.rlzs_assoc.realizations
     insured = self.oqparam.insured_losses
     if self.oqparam.avg_losses:
         avg_losses = self.datastore['avg_losses-rlzs'].value
     else:
         avg_losses = self.avg_losses
     r_curves = self.datastore['rcurves-rlzs'].value
     for loss_type, cbuilder in zip(self.riskmodel.loss_types,
                                    self.riskmodel.curve_builders):
         rcurves = r_curves[loss_type]
         asset_values = self.vals[loss_type]
         data = []
         for rlz in rlzs:
             average_losses = avg_losses[loss_type][:, rlz.ordinal]
             average_insured_losses = (avg_losses[loss_type +
                                                  '_ins'][:, rlz.ordinal]
                                       if insured else None)
             loss_curves = _old_loss_curves(asset_values,
                                            rcurves[:, rlz.ordinal,
                                                    0], cbuilder.ratios)
             insured_curves = _old_loss_curves(
                 asset_values, rcurves[:, rlz.ordinal, 1],
                 cbuilder.ratios) if insured else None
             out = scientific.Output(
                 assets,
                 loss_type,
                 rlz.ordinal,
                 rlz.weight,
                 loss_curves=loss_curves,
                 insured_curves=insured_curves,
                 average_losses=average_losses,
                 average_insured_losses=average_insured_losses)
             data.append(out)
         all_data.append(data)
     return all_data
示例#19
0
    def build_specific_stats(self, builder):
        """
        Compute all statistics for the specified assets starting from the
        stored loss curves. Yield a statistical output object for each
        loss type.
        """
        if not self.oqparam.specific_assets:
            return []

        specific_assets = set(self.oqparam.specific_assets)
        assetcol = self.assetcol
        specific_ids = []
        for i, a in enumerate(self.assetcol):
            if a['asset_ref'] in specific_assets:
                specific_ids.append(i)

        assets = assetcol['asset_ref']
        rlzs = self.rlzs_assoc.realizations
        stats = []
        for loss_type in self.riskmodel.loss_types:
            group = self.datastore['/specific-loss_curves-rlzs/%s' % loss_type]
            data = []
            for rlz, dataset in zip(rlzs, group.values()):
                dkey = 'avg_losses-rlzs/%s/%s' % (loss_type, rlz.uid)
                average_losses = self.datastore[dkey][specific_ids]
                lcs = dataset.value
                losses_poes = numpy.array(  # -> shape (N, 2, C)
                    [lcs['losses'], lcs['poes']]).transpose(1, 0, 2)
                out = scientific.Output(
                    assets,
                    loss_type,
                    rlz.ordinal,
                    rlz.weight,
                    loss_curves=losses_poes,
                    insured_curves=None,
                    average_losses=average_losses[:, 0],
                    average_insured_losses=average_losses[:, 1])
                data.append(out)
            stats.append(builder.build(data, prefix='specific-'))
        return stats
示例#20
0
    def __call__(self,
                 loss_type,
                 assets,
                 ground_motion_values,
                 epsilons,
                 _tags=None):
        # FIXME: remove this when the engine calculator will be removed
        engine = hasattr(assets[0], 'asset_ref')
        values = get_values(loss_type, assets, self.time_event)

        # a matrix of N x E elements
        loss_ratio_matrix = self.risk_functions[loss_type].apply_to(
            ground_motion_values, epsilons)
        # another matrix of N x E elements
        loss_matrix = (loss_ratio_matrix.T * values).T
        # an array of E elements
        aggregate_losses = loss_matrix.sum(axis=0)

        if self.insured_losses and loss_type != "fatalities":
            deductibles = [a.deductible(loss_type) for a in assets]
            limits = [a.insurance_limit(loss_type) for a in assets]
            insured_loss_ratio_matrix = utils.numpy_map(
                scientific.insured_losses, loss_ratio_matrix, deductibles,
                limits)
            insured_loss_matrix = (insured_loss_ratio_matrix.T * values).T
        else:
            insured_loss_matrix = numpy.empty_like(loss_ratio_matrix)
            insured_loss_matrix.fill(numpy.nan)

        # aggregating per asset, getting a vector of E elements
        insured_losses = insured_loss_matrix.sum(axis=0)
        return scientific.Output(assets,
                                 loss_type,
                                 loss_matrix=loss_matrix,
                                 loss_ratio_matrix=loss_ratio_matrix,
                                 aggregate_losses=aggregate_losses,
                                 insured_loss_matrix=NoneOr(
                                     engine, insured_loss_matrix),
                                 insured_losses=NoneOr(engine, insured_losses))
示例#21
0
 def build_stats(self, builder):
     """
     Compute all statistics for all assets starting from the
     stored loss curves. Yield a statistical output object for each
     loss type.
     """
     if 'rcurves-rlzs' not in self.datastore:
         return []
     stats = []
     # NB: should we encounter memory issues in the future, the easy
     # solution is to split the assets in blocks and perform
     # the computation one block at the time
     assets = self.assetcol['asset_ref']
     rlzs = self.rlzs_assoc.realizations
     for loss_type in self.riskmodel.loss_types:
         group = self.datastore['rcurves-rlzs/%s' % loss_type]
         asset_values = self.assetcol[loss_type]
         data = []
         for rlz, dataset in zip(rlzs, group.values()):
             dkey = 'avg_losses-rlzs/%s/%s' % (loss_type, rlz.uid)
             average_losses = self.datastore[dkey].value
             ratios = group.attrs['loss_ratios']
             lcs = []
             for avalue, poes in zip(asset_values, dataset['poes']):
                 lcs.append((avalue * ratios, poes))
             losses_poes = numpy.array(lcs)  # -> shape (N, 2, C)
             out = scientific.Output(
                 assets,
                 loss_type,
                 rlz.ordinal,
                 rlz.weight,
                 loss_curves=losses_poes,
                 insured_curves=None,
                 average_losses=average_losses[:, 0],
                 average_insured_losses=average_losses[:, 1])
             data.append(out)
         stats.append(builder.build(data))
     return stats
示例#22
0
 def __call__(self, loss_type, assets, gmvs_eids, epsgetter):
     """
     :param str loss_type:
         the loss type considered
     :param assets:
        a list of assets on the same site and with the same taxonomy
     :param gmvs_eids:
        a pair of arrays of E elements
     :param epsgetter:
        a callable returning the correct epsilons for the given gmvs
     :returns:
         a :class:
         `openquake.risklib.scientific.ProbabilisticEventBased.Output`
         instance.
     """
     gmvs, eids = gmvs_eids
     E = len(gmvs)
     I = self.insured_losses + 1
     N = len(assets)
     loss_ratios = numpy.zeros((N, E, I), F32)
     vf = self.risk_functions[loss_type]
     means, covs, idxs = vf.interpolate(gmvs)
     for i, asset in enumerate(assets):
         epsilons = epsgetter(asset.ordinal, eids)
         if epsilons is not None:
             ratios = vf.sample(means, covs, idxs, epsilons)
         else:
             ratios = means
         loss_ratios[i, idxs, 0] = ratios
         if self.insured_losses and loss_type != 'occupants':
             loss_ratios[i, idxs, 1] = scientific.insured_losses(
                 ratios, asset.deductible(loss_type),
                 asset.insurance_limit(loss_type))
     return scientific.Output(assets,
                              loss_type,
                              loss_ratios=loss_ratios,
                              eids=eids)
示例#23
0
    def _collect_specific_data(self):
        # return a list of list of outputs
        if not self.oqparam.specific_assets:
            return []

        specific_assets = set(self.oqparam.specific_assets)
        assetcol = self.assetcol
        specific_ids = []
        for i, a in enumerate(self.assetcol):
            if a['asset_ref'] in specific_assets:
                specific_ids.append(i)

        assets = assetcol['asset_ref']
        rlzs = self.rlzs_assoc.realizations
        specific_data = []
        avglosses = self.datastore['avg_losses-rlzs'][specific_ids]
        for loss_type in self.riskmodel.loss_types:
            group = self.datastore['/specific-loss_curves-rlzs/%s' % loss_type]
            data = []
            avglosses_lt = avglosses[loss_type]
            for rlz, dataset in zip(rlzs, group.values()):
                average_losses = avglosses_lt[:, rlz.ordinal]
                lcs = dataset.value
                losses_poes = numpy.array(  # -> shape (N, 2, C)
                    [lcs['losses'], lcs['poes']]).transpose(1, 0, 2)
                out = scientific.Output(
                    assets,
                    loss_type,
                    rlz.ordinal,
                    rlz.weight,
                    loss_curves=losses_poes,
                    insured_curves=None,  # FIXME: why None?
                    average_losses=average_losses[:, 0],
                    average_insured_losses=average_losses[:, 1])
                data.append(out)
            specific_data.append(data)
        return specific_data
示例#24
0
    def __call__(self,
                 loss_type,
                 assets,
                 hazard_curves,
                 _epsilons=None,
                 _tags=None):
        """
        :param loss_type: the loss type
        :param assets: a list of N assets of the same taxonomy
        :param hazard_curves: an array of N x E elements
        :returns: an array of N assets and an array of N x D elements

        where N is the number of points and D the number of damage states.
        """
        damages = [
            asset.number * scientific.classical_damage(
                self.risk_functions[loss_type],
                self.hazard_imls,
                curve,
                investigation_time=self.investigation_time,
                risk_investigation_time=self.risk_investigation_time)
            for asset, curve in zip(assets, hazard_curves)
        ]
        return scientific.Output(assets, loss_type, damages=damages)
示例#25
0
    def __call__(self,
                 loss_type,
                 assets,
                 ground_motion_values,
                 epsilons,
                 _tags=None):
        values = get_values(loss_type, assets, self.time_event)

        # a matrix of N x R elements
        loss_ratio_matrix = self.risk_functions[loss_type].apply_to(
            ground_motion_values, epsilons)
        # another matrix of N x R elements
        loss_matrix = (loss_ratio_matrix.T * values).T
        # an array of R elements
        aggregate_losses = loss_matrix.sum(axis=0)

        if self.insured_losses and loss_type != "fatalities":
            deductibles = [a.deductible(loss_type) for a in assets]
            limits = [a.insurance_limit(loss_type) for a in assets]
            insured_loss_ratio_matrix = utils.numpy_map(
                scientific.insured_losses, loss_ratio_matrix, deductibles,
                limits)
            insured_loss_matrix = (insured_loss_ratio_matrix.T * values).T

            # aggregating per asset, getting a vector of R elements
            insured_losses = insured_loss_matrix.sum(axis=0)
        else:
            insured_loss_matrix = None
            insured_losses = None
        return scientific.Output(assets,
                                 loss_type,
                                 loss_matrix=loss_matrix,
                                 loss_ratio_matrix=loss_ratio_matrix,
                                 aggregate_losses=aggregate_losses,
                                 insured_loss_matrix=insured_loss_matrix,
                                 insured_losses=insured_losses)
示例#26
0
    def __call__(self, loss_type, assets, ground_motion_values, epsilons,
                 event_ids):
        """
        :param str loss_type: the loss type considered

        :param assets:
           assets is an iterator over
           :class:`openquake.risklib.scientific.Asset` instances

        :param ground_motion_values:
           a numpy array with ground_motion_values of shape N x R

        :param epsilons:
           a numpy array with stochastic values of shape N x R

        :param event_ids:
           a numpy array of R event ID (integer)

        :returns:
            a :class:
            `openquake.risklib.scientific.ProbabilisticEventBased.Output`
            instance.
        """
        loss_matrix = self.risk_functions[loss_type].apply_to(
            ground_motion_values, epsilons)
        values = get_values(loss_type, assets)
        ela = loss_matrix.T * values  # matrix with T x N elements
        if self.insured_losses and loss_type != 'fatalities':
            deductibles = [a.deductible(loss_type) for a in assets]
            limits = [a.insurance_limit(loss_type) for a in assets]
            ila = utils.numpy_map(scientific.insured_losses, loss_matrix,
                                  deductibles, limits)
        else:  # build a zero matrix of size T x N
            ila = numpy.zeros((len(ground_motion_values[0]), len(assets)))
        if isinstance(assets[0].id, str):
            # in oq-lite return early, with just the losses per asset
            cb = self.riskmodel.curve_builders[self.riskmodel.lti[loss_type]]
            return scientific.Output(
                assets,
                loss_type,
                event_loss_per_asset=ela,
                insured_loss_per_asset=ila,
                counts_matrix=cb.build_counts(loss_matrix),
                insured_counts_matrix=cb.build_counts(ila),
                tags=event_ids)

        # in the engine, compute more stuff on the workers
        curves = utils.numpy_map(self.curves, loss_matrix)
        average_losses = utils.numpy_map(scientific.average_loss, curves)
        stddev_losses = numpy.std(loss_matrix, axis=1)
        maps = scientific.loss_map_matrix(self.conditional_loss_poes, curves)
        elt = self.event_loss(ela, event_ids)

        if self.insured_losses and loss_type != 'fatalities':
            insured_curves = utils.numpy_map(self.curves, ila)
            average_insured_losses = utils.numpy_map(scientific.average_loss,
                                                     insured_curves)
            stddev_insured_losses = numpy.std(ila, axis=1)
        else:
            insured_curves = None
            average_insured_losses = None
            stddev_insured_losses = None
        return scientific.Output(
            assets,
            loss_type,
            loss_matrix=loss_matrix if self.return_loss_matrix else None,
            loss_curves=curves,
            average_losses=average_losses,
            stddev_losses=stddev_losses,
            insured_curves=insured_curves,
            average_insured_losses=average_insured_losses,
            stddev_insured_losses=stddev_insured_losses,
            loss_maps=maps,
            event_loss_table=elt)