def post_execute(self, dummy):
        """
        Compute and store average losses from the risk_by_event dataset,
        and then loss curves and maps.
        """
        oq = self.oqparam

        # sanity check on the risk_by_event
        alt = self.datastore.read_df('risk_by_event')
        K = self.datastore['risk_by_event'].attrs.get('K', 0)
        upper_limit = self.E * self.L * (K + 1)
        size = len(alt)
        assert size <= upper_limit, (size, upper_limit)
        # sanity check on uniqueness by (agg_id, loss_id, event_id)
        arr = alt[['agg_id', 'loss_id', 'event_id']].to_numpy()
        uni = numpy.unique(arr, axis=0)
        if len(uni) < len(arr):
            raise RuntimeError('risk_by_event contains %d duplicates!' %
                               (len(arr) - len(uni)))
        if oq.avg_losses:
            for r in range(self.R):
                self.avg_losses[:, r] *= self.avg_ratio[r]
            self.datastore['avg_losses-rlzs'] = self.avg_losses
            stats.set_rlzs_stats(self.datastore,
                                 'avg_losses',
                                 asset_id=self.assetcol['id'],
                                 loss_type=oq.loss_types)

        self.build_aggcurves()
        if oq.reaggregate_by:
            post_aggregate(self.datastore.calc_id, ','.join(oq.reaggregate_by))
Beispiel #2
0
    def post_execute(self, dummy):
        """
        Compute and store average losses from the risk_by_event dataset,
        and then loss curves and maps.
        """
        oq = self.oqparam

        # sanity check on the risk_by_event
        alt = self.datastore.read_df('risk_by_event', 'event_id')
        K = self.datastore['risk_by_event'].attrs.get('K', 0)
        upper_limit = self.E * self.L * (K + 1)
        size = len(alt)
        assert size <= upper_limit, (size, upper_limit)
        if oq.avg_losses:
            for r in range(self.R):
                self.avg_losses[:, r] *= self.avg_ratio[r]
            self.datastore['avg_losses-rlzs'] = self.avg_losses
            stats.set_rlzs_stats(self.datastore,
                                 'avg_losses',
                                 asset_id=self.assetcol['id'],
                                 loss_type=oq.loss_names)

        # save agg_losses
        units = self.datastore['cost_calculator'].get_units(oq.loss_names)
        if oq.calculation_mode == 'scenario_risk':  # compute agg_losses
            alt['rlz_id'] = self.rlzs[alt.index.to_numpy()]
            agglosses = numpy.zeros((K + 1, self.R, self.L), F32)
            for (agg_id, rlz_id,
                 loss_id), df in alt.groupby(['agg_id', 'rlz_id', 'loss_id']):
                agglosses[agg_id, rlz_id,
                          loss_id] = (df.loss.sum() * self.avg_ratio[rlz_id])
            self.datastore['agg_losses-rlzs'] = agglosses
            stats.set_rlzs_stats(self.datastore,
                                 'agg_losses',
                                 agg_id=K,
                                 loss_types=oq.loss_names,
                                 units=units)
            logging.info('Total portfolio loss\n' +
                         views.view('portfolio_loss', self.datastore))
        else:  # event_based_risk, run post_risk
            prc = PostRiskCalculator(oq, self.datastore.calc_id)
            if hasattr(self, 'exported'):
                prc.exported = self.exported
            with prc.datastore:
                prc.run(exports='')

        if (oq.investigation_time or not oq.avg_losses
                or 'agg_losses-rlzs' not in self.datastore):
            return

        # sanity check on the agg_losses and sum_losses
        sumlosses = self.avg_losses.sum(axis=0)
        if not numpy.allclose(agglosses[K], sumlosses, rtol=1E-6):
            url = ('https://docs.openquake.org/oq-engine/advanced/'
                   'addition-is-non-associative.html')
            logging.warning(
                'Due to rounding errors inherent in floating-point arithmetic,'
                ' agg_losses != sum(avg_losses): %s != %s\nsee %s',
                agglosses[K].mean(), sumlosses.mean(), url)
 def post_execute(self, result):
     # NB: defined only for loss_type = 'structural'
     bcr_data = numpy.zeros((self.A, self.R), bcr_dt)
     for aid, data in result['bcr_data'].items():
         bcr_data[aid]['annual_loss_orig'] = data[:, 0]
         bcr_data[aid]['annual_loss_retro'] = data[:, 1]
         bcr_data[aid]['bcr'] = data[:, 2]
     stats.set_rlzs_stats(self.datastore, 'bcr', bcr_data)
Beispiel #4
0
 def post_execute(self, result):
     # NB: defined only for loss_type = 'structural'
     bcr_data = numpy.zeros((self.A, self.R), bcr_dt)
     for aid, data in result['bcr_data'].items():
         bcr_data[aid]['annual_loss_orig'] = data[:, 0]
         bcr_data[aid]['annual_loss_retro'] = data[:, 1]
         bcr_data[aid]['bcr'] = data[:, 2]
     stats.set_rlzs_stats(self.datastore, 'bcr', bcr_data)
Beispiel #5
0
 def execute(self):
     oq = self.oqparam
     if oq.return_periods != [0]:
         # setting return_periods = 0 disable loss curves
         eff_time = oq.investigation_time * oq.ses_per_logic_tree_path
         if eff_time < 2:
             logging.warning(
                 'eff_time=%s is too small to compute loss curves',
                 eff_time)
             return
     logging.info('Building loss tables')
     build_loss_tables(self.datastore)
     shp = self.get_shape(self.L)  # (L, T...)
     text = ' x '.join('%d(%s)' % (n, t)
                       for t, n in zip(oq.aggregate_by, shp[1:]))
     logging.info('Producing %d(loss_types) x %s loss curves', self.L, text)
     builder = get_loss_builder(self.datastore)
     self.build_datasets(builder, oq.aggregate_by, 'agg_')
     self.build_datasets(builder, [], 'app_')
     self.build_datasets(builder, [], 'tot_')
     ds = self.datastore
     if oq.aggregate_by:
         pr = post_ebrisk
         ds.swmr_on()
         smap = parallel.Starmap(pr, [(self.datastore, rlzi)
                                      for rlzi in range(self.R)],
                                 h5=self.datastore.hdf5)
     else:
         # do everything in process since it is really fast
         elt = ds.read_df('losses_by_event', ['event_id', 'rlzi'])
         smap = []
         for rlzi, losses_df in elt.groupby('rlzi'):
             losses = numpy.array(losses_df)
             smap.append({
                 'tot_curves': builder.build_curves(losses, rlzi),
                 'tot_losses': losses.sum(axis=0) * oq.ses_ratio,
                 'rlzi': rlzi
             })
     for dic in smap:
         if not dic:
             continue
         r = dic['rlzi']
         ds['tot_curves-rlzs'][:, r] = dic['tot_curves']  # PL
         ds['tot_losses-rlzs'][:, r] = dic['tot_losses']  # L
         if oq.aggregate_by:
             ds['agg_curves-rlzs'][:, r] = dic['agg_curves']  # PLT..
             ds['agg_losses-rlzs'][:, r] = dic['agg_losses']  # LT...
         if 'app_curves' in dic:
             ds['app_curves-rlzs'][:, r] = dic['app_curves']  # PL
     if self.R > 1:
         logging.info('Computing aggregate statistics')
         set_rlzs_stats(self.datastore, 'app_curves')
         set_rlzs_stats(self.datastore, 'tot_curves')
         set_rlzs_stats(self.datastore, 'tot_losses')
         if oq.aggregate_by:
             set_rlzs_stats(self.datastore, 'agg_curves')
             set_rlzs_stats(self.datastore, 'agg_losses')
Beispiel #6
0
 def execute(self):
     oq = self.oqparam
     if oq.return_periods != [0]:
         # setting return_periods = 0 disable loss curves
         eff_time = oq.investigation_time * oq.ses_per_logic_tree_path
         if eff_time < 2:
             logging.warning(
                 'eff_time=%s is too small to compute loss curves',
                 eff_time)
             return
     logging.info('Building loss tables')
     build_loss_tables(self.datastore)
     shp = self.get_shape(self.L)  # (L, T...)
     text = ' x '.join('%d(%s)' % (n, t)
                       for t, n in zip(oq.aggregate_by, shp[1:]))
     logging.info('Producing %d(loss_types) x %s loss curves', self.L, text)
     builder = get_loss_builder(self.datastore)
     if oq.aggregate_by:
         self.build_datasets(builder, oq.aggregate_by, 'agg_')
     self.build_datasets(builder, [], 'app_')
     self.build_datasets(builder, [], 'tot_')
     ds = self.datastore
     if oq.aggregate_by:
         aggkeys = list(ds['event_loss_table'])
         ds.swmr_on()
         smap = parallel.Starmap(post_ebrisk, [(self.datastore, aggkey)
                                               for aggkey in aggkeys],
                                 h5=self.datastore.hdf5)
     else:
         smap = ()
     # do everything in process since it is really fast
     elt = ds.read_df('losses_by_event', ['event_id', 'rlzi'])
     for r, curves, losses in builder.gen_curves_by_rlz(elt, oq.ses_ratio):
         ds['tot_curves-rlzs'][:, r] = curves  # PL
         ds['tot_losses-rlzs'][:, r] = losses  # L
     for res in smap:
         if not res:
             continue
         for r, dic in res.items():
             if oq.aggregate_by:
                 ds['agg_curves-rlzs'][(slice(None), r, slice(None)) +
                                       dic['idx']  # PRLT..
                                       ] = dic['agg_curves']
                 ds['agg_losses-rlzs'][(slice(None), r) +
                                       dic['idx']  # LRT...
                                       ] = dic['agg_losses']
                 ds['app_curves-rlzs'][:, r] += dic['agg_curves']  # PL
     if self.R > 1:
         logging.info('Computing aggregate statistics')
         set_rlzs_stats(self.datastore, 'app_curves')
         set_rlzs_stats(self.datastore, 'tot_curves')
         set_rlzs_stats(self.datastore, 'tot_losses')
         if oq.aggregate_by:
             set_rlzs_stats(self.datastore, 'agg_curves')
             set_rlzs_stats(self.datastore, 'agg_losses')
     return oq.aggregate_by
Beispiel #7
0
    def postproc(self):
        """
        Build aggregate loss curves and run EbrPostCalculator
        """
        dstore = self.datastore
        self.before_export()  # set 'realizations'
        oq = self.oqparam
        eff_time = oq.investigation_time * oq.ses_per_logic_tree_path
        if eff_time < 2:
            logging.warn('eff_time=%s is too small to compute agg_curves',
                         eff_time)
            return
        stats = oq.risk_stats()
        # store avg_losses-stats
        if oq.avg_losses:
            set_rlzs_stats(self.datastore, 'avg_losses')
        b = get_loss_builder(dstore)
        if 'ruptures' in dstore:
            logging.info('Building loss tables')
            with self.monitor('building loss tables', measuremem=True):
                rlt, lbr = build_loss_tables(dstore)
                dstore['rup_loss_table'] = rlt
                dstore['losses_by_rlzi'] = lbr
                ridx = [rlt[:, lti].argmax() for lti in range(self.L)]
                dstore.set_attrs('rup_loss_table', ridx=ridx)
        logging.info('Building aggregate loss curves')
        with self.monitor('building agg_curves', measuremem=True):
            array, arr_stats = b.build(dstore['losses_by_event'].value, stats)
        self.datastore['agg_curves-rlzs'] = array
        units = self.assetcol.units(loss_types=array.dtype.names)
        self.datastore.set_attrs('agg_curves-rlzs',
                                 return_periods=b.return_periods,
                                 units=units)
        if arr_stats is not None:
            self.datastore['agg_curves-stats'] = arr_stats
            self.datastore.set_attrs(
                'agg_curves-stats',
                return_periods=b.return_periods,
                stats=[encode(name) for (name, func) in stats],
                units=units)

        if 'all_loss_ratios' in self.datastore:
            self.datastore.save_vlen('all_loss_ratios/indices', [
                numpy.array(self.indices[aid], riskinput.indices_dt)
                for aid in range(self.A)
            ])
            self.datastore.set_attrs('all_loss_ratios',
                                     loss_types=' '.join(
                                         self.riskmodel.loss_types))
            dset = self.datastore['all_loss_ratios/data']
            nbytes = dset.size * dset.dtype.itemsize
            self.datastore.set_attrs('all_loss_ratios/data',
                                     nbytes=nbytes,
                                     bytes_per_asset=nbytes / self.A)
            EbrPostCalculator(self).run(close=False)
Beispiel #8
0
 def post_execute(self, dummy):
     oq = self.oqparam
     time_ratio = oq.time_ratio / len(self.datastore['weights'])
     A, L, Dc = self.dmgcsq.shape
     D = len(self.crmodel.damage_states)
     # fix no_damage distribution for events with zero damage
     number = self.assetcol['number']
     for li in range(L):
         self.dmgcsq[:, li, 0] = (number * self.E -
                                  self.dmgcsq[:, li, 1:D].sum(axis=1))
     self.dmgcsq /= self.E
     self.datastore['damages-rlzs'] = self.dmgcsq.reshape((A, 1, L, Dc))
     set_rlzs_stats(self.datastore,
                    'damages',
                    asset_id=self.assetcol['id'],
                    rlz=[0],
                    loss_type=oq.loss_names,
                    dmg_state=['no_damage'] + self.crmodel.get_dmg_csq())
     size = self.datastore.getsize('risk_by_event')
     logging.info('Building aggregated curves from %s of risk_by_event',
                  general.humansize(size))
     alt_df = self.datastore.read_df('risk_by_event')
     del alt_df['event_id']
     dic = general.AccumDict(accum=[])
     columns = sorted(
         set(alt_df.columns) - {'agg_id', 'loss_id', 'variance'})
     periods = [0] + list(self.builder.return_periods)
     wdd = {'agg_id': [], 'loss_id': [], 'event_id': []}
     for col in columns[:D - 1]:
         wdd[col] = []
     for (agg_id,
          loss_id), df in alt_df.groupby([alt_df.agg_id, alt_df.loss_id]):
         worst_dmgdist(df, agg_id, loss_id, wdd)
         tots = [df[col].sum() * time_ratio for col in columns]
         curves = [
             self.builder.build_curve(df[col].to_numpy()) for col in columns
         ]
         for p, period in enumerate(periods):
             dic['agg_id'].append(agg_id)
             dic['loss_id'].append(loss_id)
             dic['return_period'].append(period)
             if p == 0:
                 for col, tot in zip(columns, tots):
                     dic[col].append(tot)
             else:
                 for col, curve in zip(columns, curves):
                     dic[col].append(curve[p - 1])
     fix_dic(dic, columns)
     fix_dic(wdd, columns[:D - 1])
     ls = ' '.join(self.crmodel.damage_states[1:])
     self.datastore.create_df('worst_dmgdist', wdd.items(), limit_states=ls)
     self.datastore.create_df('aggcurves', dic.items(), limit_states=ls)
     self.sanity_check(time_ratio)
Beispiel #9
0
    def post_execute(self, result):
        """
        Compute stats for the aggregated distributions and save
        the results on the datastore.
        """
        loss_dt = self.oqparam.loss_dt()
        L = len(loss_dt.names)
        dtlist = [('event_id', U32), ('loss', (F32, (L,)))]
        R = self.R
        with self.monitor('saving outputs'):
            A = len(self.assetcol)

            # agg losses
            res = result['agg']
            E, L = res.shape
            agglosses = numpy.zeros((R, L), stat_dt)
            for r in range(R):
                mean, std = scientific.mean_std(res[self.rlzs == r])
                agglosses[r]['mean'] = mean
                agglosses[r]['stddev'] = std

            # avg losses
            losses_by_asset = numpy.zeros((A, R, L), F64)
            for (l, r, aid, avg) in result['avg']:
                losses_by_asset[aid, r, l] = avg

            self.datastore['avg_losses-rlzs'] = losses_by_asset
            set_rlzs_stats(self.datastore, 'avg_losses',
                           asset_id=self.assetcol['id'],
                           loss_type=self.oqparam.loss_names)
            self.datastore['agglosses'] = agglosses

            # losses by event
            lbe = numpy.zeros(E, dtlist)
            lbe['event_id'] = range(E)
            lbe['loss'] = res
            self.datastore['event_loss_table/,'] = lbe
            loss_types = self.oqparam.loss_dt().names
            self.datastore.set_attrs(
                'event_loss_table/,', loss_types=loss_types)

            # sanity check
            totlosses = losses_by_asset.sum(axis=0)
            msg = ('%s, rlz=%d: the total loss %s is different from the sum '
                   'of the average losses %s')
            for r in range(R):
                for l, name in enumerate(loss_dt.names):
                    totloss = totlosses[r, l]
                    aggloss = agglosses[r, l]['mean']
                    if not numpy.allclose(totloss, aggloss, rtol=1E-6):
                        logging.warning(msg, name, r, totloss, aggloss)
        logging.info('Mean portfolio loss\n' +
                     views.view('portfolio_loss', self.datastore))
    def post_execute(self, result):
        """
        Export the result in CSV format.

        :param result:
            a dictionary (l, r) -> asset_ordinal -> fractions per damage state
        """
        damages_dt = numpy.dtype([(ds, numpy.float32)
                                  for ds in self.riskmodel.damage_states])
        damages = numpy.zeros((self.A, self.R, self.L), damages_dt)
        for l, r in result:
            for aid, fractions in result[l, r].items():
                damages[aid, r, l] = tuple(fractions)
        stats.set_rlzs_stats(self.datastore, 'damages', damages)
Beispiel #11
0
 def execute(self):
     oq = self.oqparam
     if oq.return_periods != [0]:
         # setting return_periods = 0 disable loss curves
         eff_time = oq.investigation_time * oq.ses_per_logic_tree_path
         if eff_time < 2:
             logging.warning(
                 'eff_time=%s is too small to compute loss curves',
                 eff_time)
             return
     logging.info('Building loss tables')
     build_loss_tables(self.datastore)
     shp = self.get_shape(self.L)  # (L, T...)
     text = ' x '.join('%d(%s)' % (n, t)
                       for t, n in zip(oq.aggregate_by, shp[1:]))
     logging.info('Producing %d(loss_types) x %s loss curves', self.L, text)
     builder = get_loss_builder(self.datastore)
     self.build_datasets(builder, oq.aggregate_by, 'agg_')
     self.build_datasets(builder, [], 'app_')
     self.build_datasets(builder, [], 'tot_')
     if oq.aggregate_by:
         pr = post_ebrisk
     else:
         pr = post_risk
     self.datastore.swmr_on()
     smap = parallel.Starmap(pr, [(self.datastore, rlzi)
                                  for rlzi in range(self.R)],
                             h5=self.datastore.hdf5)
     ds = self.datastore
     for dic in smap:
         if not dic:
             continue
         r = dic['rlzi']
         ds['tot_curves-rlzs'][:, r] = dic['tot_curves']  # PL
         ds['tot_losses-rlzs'][:, r] = dic['tot_losses']  # L
         if oq.aggregate_by:
             ds['agg_curves-rlzs'][:, r] = dic['agg_curves']  # PLT..
             ds['agg_losses-rlzs'][:, r] = dic['agg_losses']  # LT...
         if 'app_curves' in dic:
             ds['app_curves-rlzs'][:, r] = dic['app_curves']  # PL
     if self.R > 1:
         logging.info('Computing aggregate statistics')
         set_rlzs_stats(self.datastore, 'app_curves')
         set_rlzs_stats(self.datastore, 'tot_curves')
         set_rlzs_stats(self.datastore, 'tot_losses')
         if oq.aggregate_by:
             set_rlzs_stats(self.datastore, 'agg_curves')
             set_rlzs_stats(self.datastore, 'agg_losses')
Beispiel #12
0
    def post_execute(self, result):
        """
        Export the result in CSV format.

        :param result:
            a dictionary asset_ordinal -> array(R, L, D)
        """
        D = len(self.crmodel.damage_states)
        damages = numpy.zeros((self.A, self.R, self.L, D), numpy.float32)
        for a in result:
            damages[a] = result[a]
        self.datastore['damages-rlzs'] = damages
        stats.set_rlzs_stats(self.datastore, 'damages',
                             assets=self.assetcol['id'],
                             loss_types=self.oqparam.loss_names,
                             dmg_state=self.crmodel.damage_states)
Beispiel #13
0
    def post_execute(self, result):
        """
        Export the result in CSV format.

        :param result:
            a dictionary (l, r) -> asset_ordinal -> fractions per damage state
        """
        D = len(self.crmodel.damage_states)
        damages = numpy.zeros((self.A, self.R, self.L, D), numpy.float32)
        for l, r in result:
            for aid, fractions in result[l, r].items():
                damages[aid, r, l] = fractions
        self.datastore['damages-rlzs'] = damages
        stats.set_rlzs_stats(self.datastore, 'damages',
                             assets=self.assetcol['id'],
                             loss_types=self.oqparam.loss_names,
                             dmg_state=self.crmodel.damage_states)
Beispiel #14
0
 def postproc(self):
     """
     Build aggregate loss curves in process
     """
     dstore = self.datastore
     self.before_export()  # set 'realizations'
     oq = self.oqparam
     stats = self.param['stats']
     # store avg_losses-stats
     if oq.avg_losses:
         set_rlzs_stats(self.datastore, 'avg_losses')
     try:
         b = self.param['builder']
     except KeyError:  # don't build auxiliary tables
         return
     if dstore.parent:
         dstore.parent.open('r')  # to read the ruptures
     if 'ruptures' in self.datastore and len(self.datastore['ruptures']):
         logging.info('Building loss tables')
         with self.monitor('building loss tables', measuremem=True):
             rlt, lbr = build_loss_tables(dstore)
             dstore['rup_loss_table'] = rlt
             dstore['losses_by_rlzi'] = lbr
             ridx = [rlt[:, lti].argmax() for lti in range(self.L)]
             dstore.set_attrs('rup_loss_table', ridx=ridx)
     logging.info('Building aggregate loss curves')
     with self.monitor('building agg_curves', measuremem=True):
         lbr = group_array(dstore['losses_by_event'][()], 'rlzi')
         dic = {r: arr['loss'] for r, arr in lbr.items()}
         array, arr_stats = b.build(dic, stats)
     loss_types = ' '.join(oq.loss_dt().names)
     units = self.datastore['cost_calculator'].get_units(loss_types.split())
     if oq.individual_curves or self.R == 1:
         self.datastore['agg_curves-rlzs'] = array  # shape (P, R, L)
         self.datastore.set_attrs('agg_curves-rlzs',
                                  return_periods=b.return_periods,
                                  loss_types=loss_types,
                                  units=units)
     if arr_stats is not None:
         self.datastore['agg_curves-stats'] = arr_stats  # shape (P, S, L)
         self.datastore.set_attrs(
             'agg_curves-stats',
             return_periods=b.return_periods,
             stats=[encode(name) for (name, func) in stats],
             loss_types=loss_types,
             units=units)
Beispiel #15
0
    def post_execute(self, result):
        """
        Compute stats for the aggregated distributions and save
        the results on the datastore.
        """
        loss_dt = self.oqparam.loss_dt()
        L = len(loss_dt.names)
        dtlist = [('event_id', U32), ('loss', (F32, (L,)))]
        R = self.R
        with self.monitor('saving outputs'):
            A = len(self.assetcol)

            # agg losses
            res = result['agg']
            E, L = res.shape
            agglosses = numpy.zeros((R, L), stat_dt)
            for r in range(R):
                mean, std = scientific.mean_std(res[self.rlzs == r])
                agglosses[r]['mean'] = F32(mean)
                agglosses[r]['stddev'] = F32(std)

            # avg losses
            losses_by_asset = numpy.zeros((A, R, L), F32)
            for (l, r, aid, avg) in result['avg']:
                losses_by_asset[aid, r, l] = avg

            self.datastore['avg_losses-rlzs'] = losses_by_asset
            set_rlzs_stats(self.datastore, 'avg_losses',
                           asset_id=self.assetcol['id'],
                           loss_type=self.oqparam.loss_names)
            self.datastore['agglosses'] = agglosses

            # losses by event
            lbe = numpy.zeros(E, dtlist)
            lbe['event_id'] = range(E)
            lbe['loss'] = res
            self.datastore['losses_by_event'] = lbe
            loss_types = self.oqparam.loss_dt().names
            self.datastore.set_attrs('losses_by_event', loss_types=loss_types)

            # sanity check
            numpy.testing.assert_allclose(
                losses_by_asset.sum(axis=0), agglosses['mean'], rtol=1E-4)
        logging.info('Mean portfolio loss\n' +
                     views.view('portfolio_loss', self.datastore))
Beispiel #16
0
    def post_execute(self, result):
        """
        Export the result in CSV format.

        :param result:
            a dictionary asset_ordinal -> array(R, L, D)
        """
        D = len(self.crmodel.damage_states)
        damages = numpy.zeros((self.A, self.R, self.L, D), numpy.float32)
        for a in result:
            damages[a] = result[a]
        self.datastore['damages-rlzs'] = damages
        stats.set_rlzs_stats(self.datastore, 'damages',
                             assets=self.assetcol['id'],
                             loss_type=self.oqparam.loss_names,
                             dmg_state=self.crmodel.damage_states)
        dmg = views.view('portfolio_damage', self.datastore)
        logging.info('\n' + views.text_table(dmg, ext='org'))
 def postproc(self):
     """
     Build aggregate loss curves in process
     """
     dstore = self.datastore
     self.before_export()  # set 'realizations'
     oq = self.oqparam
     stats = self.param['stats']
     # store avg_losses-stats
     if oq.avg_losses:
         set_rlzs_stats(self.datastore, 'avg_losses')
     try:
         b = self.param['builder']
     except KeyError:  # don't build auxiliary tables
         return
     if dstore.parent:
         dstore.parent.open('r')  # to read the ruptures
     if 'ruptures' in self.datastore and len(self.datastore['ruptures']):
         logging.info('Building loss tables')
         with self.monitor('building loss tables', measuremem=True):
             rlt, lbr = build_loss_tables(dstore)
             dstore['rup_loss_table'] = rlt
             dstore['losses_by_rlzi'] = lbr
             ridx = [rlt[:, lti].argmax() for lti in range(self.L)]
             dstore.set_attrs('rup_loss_table', ridx=ridx)
     logging.info('Building aggregate loss curves')
     with self.monitor('building agg_curves', measuremem=True):
         lbr = group_array(dstore['losses_by_event'][()], 'rlzi')
         dic = {r: arr['loss'] for r, arr in lbr.items()}
         array, arr_stats = b.build(dic, stats)
     loss_types = ' '.join(oq.loss_dt().names)
     units = self.datastore['cost_calculator'].get_units(loss_types.split())
     if oq.individual_curves or self.R == 1:
         self.datastore['agg_curves-rlzs'] = array
         self.datastore.set_attrs(
             'agg_curves-rlzs',
             return_periods=b.return_periods,
             loss_types=loss_types, units=units)
     if arr_stats is not None:
         self.datastore['agg_curves-stats'] = arr_stats
         self.datastore.set_attrs(
             'agg_curves-stats', return_periods=b.return_periods,
             stats=[encode(name) for (name, func) in stats],
             loss_types=loss_types, units=units)
Beispiel #18
0
 def postproc(self):
     """
     Build aggregate loss curves in process
     """
     dstore = self.datastore
     oq = self.oqparam
     stats = self.param['stats']
     # store avg_losses-stats
     if oq.avg_losses:
         set_rlzs_stats(self.datastore, 'avg_losses')
     try:
         b = self.param['builder']
     except KeyError:  # don't build auxiliary tables
         return
     if dstore.parent:
         dstore.parent.open('r')  # to read the ruptures
     logging.info('Building loss tables')
     build_loss_tables(dstore)
     logging.info('Building aggregate loss curves')
     with self.monitor('building agg_curves', measuremem=True):
         lbr = group_array(dstore['losses_by_event'][()], 'rlzi')
         dic = {r: arr['loss'] for r, arr in lbr.items()}
         array, arr_stats = b.build(dic, stats)
     loss_types = oq.loss_dt().names
     units = self.datastore['cost_calculator'].get_units(loss_types)
     if oq.individual_curves or self.R == 1:
         self.datastore['agg_curves-rlzs'] = array  # shape (P, R, L)
         self.datastore.set_attrs(
             'agg_curves-rlzs',
             shape_descr=['return_periods', 'rlzs', 'loss_types'],
             return_periods=b.return_periods,
             rlzs=numpy.arange(self.R),
             loss_types=loss_types,
             units=units)
     if arr_stats is not None:
         self.datastore['agg_curves-stats'] = arr_stats  # shape (P, S, L)
         self.datastore.set_attrs(
             'agg_curves-stats',
             shape_descr=['return_periods', 'stats', 'loss_types'],
             return_periods=b.return_periods,
             stats=[encode(name) for (name, func) in stats],
             loss_types=loss_types,
             units=units)
 def post_execute(self, result):
     """
     Save risk data and build the aggregate loss curves
     """
     oq = self.oqparam
     loss_types = oq.loss_dt().names
     logging.info('Saving event loss table')
     elt_dt = numpy.dtype([('event_id', U32), ('rlzi', U16),
                           ('loss', (F32, (self.L, )))])
     with self.monitor('saving event loss table', measuremem=True):
         agglosses = numpy.fromiter(
             ((eid, rlz, losses)
              for (eid, rlz), losses in zip(self.events, self.agglosses)
              if losses.any()), elt_dt)
         self.datastore['losses_by_event'] = agglosses
         self.datastore.set_attrs('losses_by_event', loss_types=loss_types)
     if oq.avg_losses:
         set_rlzs_stats(self.datastore, 'avg_losses')
     post_risk.PostRiskCalculator(oq, self.datastore.calc_id).run()
 def post_execute(self, dummy):
     oq = self.oqparam
     A, L, Dc = self.dmgcsq.shape
     dmgcsq = self.dmgcsq * oq.time_ratio
     self.datastore['damages-rlzs'] = dmgcsq.reshape((A, 1, L, Dc))
     set_rlzs_stats(self.datastore,
                    'damages',
                    asset_id=self.assetcol['id'],
                    loss_type=oq.loss_names,
                    dmg_state=['no_damage'] + self.crmodel.get_dmg_csq())
     size = self.datastore.getsize('risk_by_event')
     logging.info('Building aggregated curves from %s of risk_by_event',
                  general.humansize(size))
     alt_df = self.datastore.read_df('risk_by_event')
     del alt_df['event_id']
     dic = general.AccumDict(accum=[])
     columns = sorted(
         set(alt_df.columns) - {'agg_id', 'loss_id', 'variance'})
     periods = [0] + list(self.builder.return_periods)
     for (agg_id,
          loss_id), df in alt_df.groupby([alt_df.agg_id, alt_df.loss_id]):
         tots = [df[col].sum() * oq.time_ratio for col in columns]
         curves = [
             self.builder.build_curve(df[col].to_numpy()) for col in columns
         ]
         for p, period in enumerate(periods):
             dic['agg_id'].append(agg_id)
             dic['loss_id'].append(loss_id)
             dic['return_period'].append(period)
             if p == 0:
                 for col, tot in zip(columns, tots):
                     dic[col].append(tot)
             else:
                 for col, curve in zip(columns, curves):
                     dic[col].append(curve[p - 1])
     fix_dtype(dic, U16, ['agg_id'])
     fix_dtype(dic, U8, ['loss_id'])
     fix_dtype(dic, U32, ['return_period'])
     fix_dtype(dic, F32, columns)
     ls = ' '.join(self.crmodel.damage_states[1:])
     self.datastore.create_df('aggcurves', dic.items(), limit_states=ls)
     self.sanity_check(dmgcsq)
 def postproc(self):
     """
     Build aggregate loss curves in process
     """
     dstore = self.datastore
     self.before_export()  # set 'realizations'
     oq = self.oqparam
     stats = oq.risk_stats()
     # store avg_losses-stats
     if oq.avg_losses:
         set_rlzs_stats(self.datastore, 'avg_losses')
     try:
         b = self.param['builder']
     except KeyError:  # don't build auxiliary tables
         return
     if dstore.parent:
         dstore.parent.open('r')  # to read the ruptures
     if 'ruptures' in self.datastore and len(self.datastore['ruptures']):
         logging.info('Building loss tables')
         with self.monitor('building loss tables', measuremem=True):
             rlt, lbr = build_loss_tables(dstore)
             dstore['rup_loss_table'] = rlt
             dstore['losses_by_rlzi'] = lbr
             ridx = [rlt[:, lti].argmax() for lti in range(self.L)]
             dstore.set_attrs('rup_loss_table', ridx=ridx)
     logging.info('Building aggregate loss curves')
     with self.monitor('building agg_curves', measuremem=True):
         array, arr_stats = b.build(dstore['losses_by_event'].value, stats)
     units = self.assetcol.cost_calculator.get_units(
         loss_types=array.dtype.names)
     if oq.individual_curves:
         self.datastore['agg_curves-rlzs'] = array
         self.datastore.set_attrs('agg_curves-rlzs',
                                  return_periods=b.return_periods,
                                  units=units)
     if arr_stats is not None:
         self.datastore['agg_curves-stats'] = arr_stats
         self.datastore.set_attrs(
             'agg_curves-stats',
             return_periods=b.return_periods,
             stats=[encode(name) for (name, func) in stats],
             units=units)
Beispiel #22
0
 def post_execute(self, result):
     """
     Save risk data and build the aggregate loss curves
     """
     oq = self.oqparam
     logging.info('Saving event loss table')
     with self.monitor('saving event loss table', measuremem=True):
         out = []
         for eid, losses in zip(self.events, self.agglosses):
             if losses.sum():
                 out.append((eid, 0) + tuple(losses))
         arr = numpy.array(out, oq.alt_dt())
         self.datastore.create_dframe('agg_loss_table',
                                      [(n, arr[n])
                                       for n in arr.dtype.names])
     if oq.avg_losses:
         set_rlzs_stats(self.datastore,
                        'avg_losses',
                        asset_id=self.assetcol['id'],
                        loss_type=oq.loss_names)
     post_risk.PostRiskCalculator(oq, self.datastore.calc_id).run()
Beispiel #23
0
    def post_execute(self, result):
        """
        Compute stats for the aggregated distributions and save
        the results on the datastore.
        """
        loss_dt = self.oqparam.loss_dt()
        L = len(loss_dt.names)
        dtlist = [('event_id', U32), ('rlzi', U16), ('loss', (F32, (L,)))]
        R = self.R
        with self.monitor('saving outputs'):
            A = len(self.assetcol)

            # agg losses
            res = result['agg']
            E, L = res.shape
            agglosses = numpy.zeros((R, L), stat_dt)
            for r in range(R):
                mean, std = scientific.mean_std(res[self.event_slice(r)])
                agglosses[r]['mean'] = F32(mean)
                agglosses[r]['stddev'] = F32(std)

            # losses by asset
            losses_by_asset = numpy.zeros((A, R, L), F32)
            for (l, r, aid, avg) in result['avg']:
                losses_by_asset[aid, r, l] = avg
            self.datastore['avg_losses-rlzs'] = losses_by_asset
            set_rlzs_stats(self.datastore, 'avg_losses',
                           asset_id=self.assetcol['id'],
                           loss_type=self.oqparam.loss_names)
            self.datastore['agglosses'] = agglosses

            # losses by event
            lbe = numpy.zeros(E, dtlist)
            lbe['event_id'] = range(E)
            lbe['rlzi'] = (lbe['event_id'] //
                           self.oqparam.number_of_ground_motion_fields)
            lbe['loss'] = res
            self.datastore['losses_by_event'] = lbe
            loss_types = self.oqparam.loss_dt().names
            self.datastore.set_attrs('losses_by_event', loss_types=loss_types)
Beispiel #24
0
    def post_execute(self, dummy):
        """
        Compute and store average losses from the losses_by_event dataset,
        and then loss curves and maps.
        """
        oq = self.oqparam
        if oq.avg_losses:
            self.datastore['avg_losses-stats'].attrs['stats'] = [b'mean']
        logging.info('Building loss tables')
        build_loss_tables(self.datastore)
        self.datastore.flush()  # just to be sure
        shp = self.get_shape(self.L)  # (L, T...)
        text = ' x '.join('%d(%s)' % (n, t)
                          for t, n in zip(oq.aggregate_by, shp[1:]))
        logging.info('Producing %d(loss_types) x %s loss curves', self.L, text)
        builder = get_loss_builder(self.datastore)
        self.build_datasets(builder)
        self.datastore.swmr_on()
        args = [(self.datastore.filename, builder, oq.ses_ratio, rlzi)
                for rlzi in range(self.R)]
        acc = list(parallel.Starmap(postprocess, args, h5=self.datastore.hdf5))
        for r, (curves, maps), agg_losses in acc:
            if len(curves):  # some realization can give zero contribution
                self.datastore['agg_curves-rlzs'][:, r] = curves
            if len(maps):  # conditional_loss_poes can be empty
                self.datastore['agg_maps-rlzs'][:, r] = maps
            self.datastore['agg_losses-rlzs'][:, r] = agg_losses
        if self.R > 1:
            logging.info('Computing aggregate statistics')
            set_rlzs_stats(self.datastore, 'agg_curves')
            set_rlzs_stats(self.datastore, 'agg_losses')
            if oq.conditional_loss_poes:
                set_rlzs_stats(self.datastore, 'agg_maps')

        # sanity check with the asset_loss_table
        if oq.asset_loss_table and len(oq.aggregate_by) == 1:
            alt = self.datastore['asset_loss_table'][()]
            if alt.sum() == 0:  # nothing was saved
                return
            logging.info('Checking the loss curves')
            tags = getattr(self.assetcol.tagcol, oq.aggregate_by[0])[1:]
            T = len(tags)
            P = len(builder.return_periods)
            # sanity check on the loss curves for simple tag aggregation
            arr = self.assetcol.aggregate_by(oq.aggregate_by, alt)
            # shape (T, E, L)
            rlzs = self.datastore['events']['rlz_id']
            curves = numpy.zeros((P, self.R, self.L, T))
            for t in range(T):
                for r in range(self.R):
                    for l in range(self.L):
                        curves[:, r, l,
                               t] = losses_by_period(arr[t, rlzs == r, l],
                                                     builder.return_periods,
                                                     builder.num_events[r],
                                                     builder.eff_time)
            numpy.testing.assert_allclose(
                curves, self.datastore['agg_curves-rlzs'][()])
Beispiel #25
0
 def postproc(self):
     """
     Build aggregate loss curves
     """
     dstore = self.datastore
     self.before_export()  # set 'realizations'
     oq = self.oqparam
     eff_time = oq.investigation_time * oq.ses_per_logic_tree_path
     if eff_time < 2:
         logging.warn('eff_time=%s is too small to compute agg_curves',
                      eff_time)
         return
     stats = oq. risk_stats()
     # store avg_losses-stats
     if oq.avg_losses:
         set_rlzs_stats(self.datastore, 'avg_losses')
     b = get_loss_builder(self.datastore)
     if 'ruptures' in dstore:
         logging.info('Building loss tables')
         with self.monitor('building loss tables', measuremem=True):
             rlt, lbr = build_loss_tables(dstore)
             dstore['rup_loss_table'] = rlt
             dstore['losses_by_rlzi'] = lbr
             ridx = [rlt[:, lti].argmax() for lti in range(self.L)]
             dstore.set_attrs('rup_loss_table', ridx=ridx)
     logging.info('Building aggregate loss curves')
     with self.monitor('building agg_curves', measuremem=True):
         array, arr_stats = b.build(dstore['losses_by_event'].value, stats)
     self.datastore['agg_curves-rlzs'] = array
     units = self.assetcol.units(loss_types=array.dtype.names)
     self.datastore.set_attrs(
         'agg_curves-rlzs', return_periods=b.return_periods, units=units)
     if arr_stats is not None:
         self.datastore['agg_curves-stats'] = arr_stats
         self.datastore.set_attrs(
             'agg_curves-stats', return_periods=b.return_periods,
             stats=[encode(name) for (name, func) in stats], units=units)
Beispiel #26
0
 def execute(self):
     oq = self.oqparam
     if oq.return_periods != [0]:
         # setting return_periods = 0 disable loss curves
         eff_time = oq.investigation_time * oq.ses_per_logic_tree_path
         if eff_time < 2:
             logging.warning(
                 'eff_time=%s is too small to compute loss curves',
                 eff_time)
             return
     logging.info('Building loss tables')
     build_loss_tables(self.datastore)
     shp = self.get_shape(self.L)  # (L, T...)
     text = ' x '.join('%d(%s)' % (n, t)
                       for t, n in zip(oq.aggregate_by, shp[1:]))
     logging.info('Producing %d(loss_types) x %s loss curves', self.L, text)
     builder = get_loss_builder(self.datastore)
     self.build_datasets(builder, oq.aggregate_by, 'agg_')
     if oq.aggregate_by:
         self.build_datasets(builder, [], 'tot_')
     self.datastore.swmr_on()
     args = [(self.datastore, builder, oq.ses_ratio, rlzi)
             for rlzi in range(self.R)]
     acc = list(parallel.Starmap(post_risk, args, h5=self.datastore.hdf5))
     for dic in acc:
         r = dic['rlzi']
         curves = dic['agg_curves']
         agg_losses = dic['agg_losses']
         if len(curves):  # some realization can give zero contribution
             self.datastore['agg_curves-rlzs'][:, r] = curves
         self.datastore['agg_losses-rlzs'][:, r] = agg_losses
         if oq.aggregate_by:
             curves = dic['tot_curves']
             tot_losses = dic['tot_losses']
             if len(curves):  # some realization can give zero contribution
                 self.datastore['tot_curves-rlzs'][:, r] = curves
             self.datastore['tot_losses-rlzs'][:, r] = tot_losses
     if self.R > 1:
         logging.info('Computing aggregate statistics')
         set_rlzs_stats(self.datastore, 'agg_curves')
         set_rlzs_stats(self.datastore, 'agg_losses')
         if oq.aggregate_by:
             set_rlzs_stats(self.datastore, 'tot_curves')
             set_rlzs_stats(self.datastore, 'tot_losses')
Beispiel #27
0
    def post_execute(self, result):
        """
        Compute stats for the aggregated distributions and save
        the results on the datastore.
        """
        if not result:
            self.collapsed()
            return
        dstates = self.crmodel.damage_states
        ltypes = self.crmodel.loss_types
        L = self.L = len(ltypes)
        R = self.R
        D = len(dstates)
        A = len(self.assetcol)
        E = len(self.datastore['events'])

        # reduction factor
        _, msg1 = get_nbytes_msg(dict(A=A, E=E, L=L))
        _, msg2 = get_nbytes_msg(
            dict(nrows=len(self.datastore['dd_data/eid']), ncols=D + 2))
        logging.info('Using %s\ninstead of %s', msg2, msg1)

        # avg_ratio = ratio used when computing the averages
        oq = self.oqparam
        if oq.investigation_time:  # event_based_damage
            avg_ratio = numpy.array([oq.ses_ratio] * R)
        else:  # scenario_damage
            avg_ratio = 1. / self.param['num_events']

        # damage by asset
        d_asset = numpy.zeros((A, R, L, D), F32)
        for (l, r, a, tot) in result['d_asset']:
            d_asset[a, r, l] = tot * avg_ratio[r]
        self.datastore['damages-rlzs'] = d_asset
        set_rlzs_stats(self.datastore,
                       'damages',
                       asset_id=self.assetcol['id'],
                       loss_type=oq.loss_names,
                       dmg_state=dstates)
        self.sanity_check()

        # damage by event: make sure the sum of the buildings is consistent
        tot = self.assetcol['number'].sum()
        dt = F32 if self.param['approx_ddd'] else U32
        dbe = numpy.zeros((self.E, L, D), dt)  # shape E, L, D
        dbe[:, :, 0] = tot
        for e, dmg_by_lt in result['d_event'].items():
            for l, dmg in enumerate(dmg_by_lt):
                dbe[e, l, 0] = tot - dmg.sum()
                dbe[e, l, 1:] = dmg
        self.datastore['dmg_by_event'] = dbe

        # consequence distributions
        del result['d_asset']
        del result['d_event']
        dtlist = [('event_id', U32), ('rlz_id', U16), ('loss', (F32, (L, )))]
        rlz = self.datastore['events']['rlz_id']
        for name, csq in result.items():
            if name.startswith('avg_'):
                c_asset = numpy.zeros((A, R, L), F32)
                for (l, r, a, stat) in result[name]:
                    c_asset[a, r, l] = stat * avg_ratio[r]
                self.datastore[name + '-rlzs'] = c_asset
                set_rlzs_stats(self.datastore,
                               name,
                               asset_id=self.assetcol['id'],
                               loss_type=oq.loss_names)
            elif name.endswith('_by_event'):
                arr = numpy.zeros(len(csq), dtlist)
                for i, (eid, loss) in enumerate(csq.items()):
                    arr[i] = (eid, rlz[eid], loss)
                self.datastore[name] = arr
    def post_execute(self, result):
        """
        Compute stats for the aggregated distributions and save
        the results on the datastore.
        """
        if not result:
            self.collapsed()
            return
        dstates = self.crmodel.damage_states
        ltypes = self.crmodel.loss_types
        L = len(ltypes)
        R = self.R
        D = len(dstates)
        A = len(self.assetcol)
        indices = self.datastore['dd_data/indices'][()]
        if not len(self.datastore['dd_data/data']):
            logging.warning('There is no damage at all!')
        events_per_asset = (indices[:, 1] - indices[:, 0]).mean()
        logging.info('Found ~%d dmg distributions per asset', events_per_asset)

        # avg_ratio = ratio used when computing the averages
        oq = self.oqparam
        if oq.investigation_time:  # event_based_damage
            avg_ratio = oq.ses_ratio
        else:  # scenario_damage
            avg_ratio = 1. / oq.number_of_ground_motion_fields

        # damage by asset
        d_asset = numpy.zeros((A, R, L, D), F32)
        for (l, r, a, tot) in result['d_asset']:
            d_asset[a, r, l] = tot
        self.datastore['avg_damages-rlzs'] = d_asset * avg_ratio
        set_rlzs_stats(self.datastore,
                       'avg_damages',
                       asset_id=self.assetcol['id'],
                       loss_type=oq.loss_names,
                       dmg_state=dstates)

        # damage by event: make sure the sum of the buildings is consistent
        tot = self.assetcol['number'].sum()
        dt = F32 if self.param['approx_ddd'] else U32
        dbe = numpy.zeros((self.E, L, D), dt)  # shape E, L, D
        dbe[:, :, 0] = tot
        for e, dmg_by_lt in result['d_event'].items():
            for l, dmg in enumerate(dmg_by_lt):
                dbe[e, l, 0] = tot - dmg.sum()
                dbe[e, l, 1:] = dmg
        self.datastore['dmg_by_event'] = dbe

        # consequence distributions
        del result['d_asset']
        del result['d_event']
        dtlist = [('event_id', U32), ('rlz_id', U16), ('loss', (F32, (L, )))]
        rlz = self.datastore['events']['rlz_id']
        for name, csq in result.items():
            if name.startswith('avg_'):
                c_asset = numpy.zeros((A, R, L), F32)
                for (l, r, a, stat) in result[name]:
                    c_asset[a, r, l] = stat
                self.datastore[name + '-rlzs'] = c_asset * avg_ratio
                set_rlzs_stats(self.datastore,
                               name,
                               asset_id=self.assetcol['id'],
                               loss_type=oq.loss_names)
            elif name.endswith('_by_event'):
                arr = numpy.zeros(len(csq), dtlist)
                for i, (eid, loss) in enumerate(csq.items()):
                    arr[i] = (eid, rlz[eid], loss)
                self.datastore[name] = arr
Beispiel #29
0
    def execute(self):
        oq = self.oqparam
        if oq.return_periods != [0]:
            # setting return_periods = 0 disable loss curves
            eff_time = oq.investigation_time * oq.ses_per_logic_tree_path
            if eff_time < 2:
                logging.warning(
                    'eff_time=%s is too small to compute loss curves',
                    eff_time)
                return
        if 'source_info' in self.datastore:  # missing for gmf_ebrisk
            logging.info('Building src_loss_table')
            source_ids, losses = get_src_loss_table(self.datastore, self.L)
            self.datastore['src_loss_table'] = losses
            self.datastore.set_shape_attrs('src_loss_table',
                                           source=source_ids,
                                           loss_type=oq.loss_names)
        shp = self.get_shape(self.L)  # (L, T...)
        text = ' x '.join('%d(%s)' % (n, t)
                          for t, n in zip(oq.aggregate_by, shp[1:]))
        logging.info('Producing %d(loss_types) x %s loss curves', self.L, text)
        builder = get_loss_builder(self.datastore)
        if oq.aggregate_by:
            self.build_datasets(builder, oq.aggregate_by, 'agg_')
        self.build_datasets(builder, [], 'app_')
        self.build_datasets(builder, [], 'tot_')
        ds = self.datastore
        if oq.aggregate_by:
            aggkeys = list(ds['event_loss_table'])
            ds.swmr_on()
            smap = parallel.Starmap(post_ebrisk, [(self.datastore, aggkey)
                                                  for aggkey in aggkeys],
                                    h5=self.datastore.hdf5)
        else:
            smap = ()
        # do everything in process since it is really fast
        elt = ds.read_df('losses_by_event', ['event_id', 'rlzi'])
        for r, curves, losses in builder.gen_curves_by_rlz(elt, oq.ses_ratio):
            ds['tot_curves-rlzs'][:, r] = curves  # PL
            ds['tot_losses-rlzs'][:, r] = losses  # L
        for res in smap:
            if not res:
                continue
            for r, dic in res.items():
                if oq.aggregate_by:
                    ds['agg_curves-rlzs'][(slice(None), r, slice(None)) +
                                          dic['idx']  # PRLT..
                                          ] = dic['agg_curves']
                    ds['agg_losses-rlzs'][(slice(None), r) +
                                          dic['idx']  # LRT...
                                          ] = dic['agg_losses']
                    ds['app_curves-rlzs'][:, r] += dic['agg_curves']  # PL

        units = self.datastore['cost_calculator'].get_units(oq.loss_names)
        aggby = {
            tagname: encode(getattr(self.tagcol, tagname)[1:])
            for tagname in oq.aggregate_by
        }
        set_rlzs_stats(self.datastore,
                       'app_curves',
                       return_periods=builder.return_periods,
                       loss_types=oq.loss_names,
                       **aggby,
                       units=units)
        set_rlzs_stats(self.datastore,
                       'tot_curves',
                       return_periods=builder.return_periods,
                       loss_types=oq.loss_names,
                       **aggby,
                       units=units)
        set_rlzs_stats(self.datastore,
                       'tot_losses',
                       loss_types=oq.loss_names,
                       **aggby,
                       units=units)
        if oq.aggregate_by:
            set_rlzs_stats(self.datastore,
                           'agg_curves',
                           return_periods=builder.return_periods,
                           loss_types=oq.loss_names,
                           **aggby,
                           units=units)
            set_rlzs_stats(self.datastore,
                           'agg_losses',
                           loss_types=oq.loss_names,
                           **aggby,
                           units=units)
        return oq.aggregate_by
Beispiel #30
0
 def execute(self):
     oq = self.oqparam
     if oq.return_periods != [0]:
         # setting return_periods = 0 disable loss curves
         eff_time = oq.investigation_time * oq.ses_per_logic_tree_path
         if eff_time < 2:
             logging.warning(
                 'eff_time=%s is too small to compute loss curves',
                 eff_time)
             return
     if 'source_info' in self.datastore:  # missing for gmf_ebrisk
         logging.info('Building the src_loss_table')
         with self.monitor('src_loss_table', measuremem=True):
             source_ids, losses = get_src_loss_table(self.datastore, self.L)
             self.datastore['src_loss_table'] = losses
             self.datastore.set_shape_descr('src_loss_table',
                                            source=source_ids,
                                            loss_type=oq.loss_names)
     builder = get_loss_builder(self.datastore)
     K = len(self.aggkey) if oq.aggregate_by else 0
     P = len(builder.return_periods)
     # do everything in process since it is really fast
     rlz_id = self.datastore['events']['rlz_id']
     if oq.collect_rlzs:
         rlz_id = numpy.zeros_like(rlz_id)
     alt_df = self.datastore.read_df('agg_loss_table')
     if self.reaggreate:
         idxs = numpy.concatenate([
             reagg_idxs(self.num_tags, oq.aggregate_by),
             numpy.array([K], int)
         ])
         alt_df['agg_id'] = idxs[alt_df['agg_id'].to_numpy()]
         alt_df = alt_df.groupby(['event_id', 'agg_id']).sum().reset_index()
     alt_df['rlz_id'] = rlz_id[alt_df.event_id.to_numpy()]
     units = self.datastore['cost_calculator'].get_units(oq.loss_names)
     dist = (
         'no' if os.environ.get('OQ_DISTRIBUTE') == 'no' else 'processpool'
     )  # use only the local cores
     smap = parallel.Starmap(post_risk,
                             h5=self.datastore.hdf5,
                             distribute=dist)
     # producing concurrent_tasks/2 = num_cores tasks
     blocksize = int(
         numpy.ceil((K + 1) * self.R / (oq.concurrent_tasks // 2 or 1)))
     krl_losses = []
     agg_losses = numpy.zeros((K + 1, self.R, self.L), F32)
     agg_curves = numpy.zeros((K + 1, self.R, self.L, P), F32)
     gb = alt_df.groupby([alt_df.agg_id, alt_df.rlz_id, alt_df.loss_id])
     # NB: in the future we may use multiprocessing.shared_memory
     for (k, r, lni), df in gb:
         agg_losses[k, r, lni] = df.loss.sum()
         krl_losses.append((k, r, lni, df.loss.to_numpy()))
         if len(krl_losses) >= blocksize:
             size = len(krl_losses) * 8
             logging.info('Sending %s of losses', general.humansize(size))
             smap.submit((builder, krl_losses))
             krl_losses[:] = []
     if krl_losses:
         smap.submit((builder, krl_losses))
     for krl, curve in smap.reduce().items():
         agg_curves[krl] = curve
     R = len(self.datastore['weights'])
     time_ratio = oq.time_ratio / R if oq.collect_rlzs else oq.time_ratio
     self.datastore['agg_losses-rlzs'] = agg_losses * time_ratio
     set_rlzs_stats(self.datastore,
                    'agg_losses',
                    agg_id=K + 1,
                    loss_types=oq.loss_names,
                    units=units)
     self.datastore['agg_curves-rlzs'] = agg_curves
     set_rlzs_stats(self.datastore,
                    'agg_curves',
                    agg_id=K + 1,
                    lti=self.L,
                    return_period=builder.return_periods,
                    units=units)
     return 1
Beispiel #31
0
    def post_execute(self, times):
        """
        Compute and store average losses from the losses_by_event dataset,
        and then loss curves and maps.
        """
        if len(times):
            self.datastore.set_attrs(
                'task_info/start_ebrisk', times=times,
                events_per_sid=numpy.mean(self.events_per_sid))
        oq = self.oqparam
        shp = self.get_shape(self.L)  # (L, T...)
        text = ' x '.join(
            '%d(%s)' % (n, t) for t, n in zip(oq.aggregate_by, shp[1:]))
        logging.info('Producing %d(loss_types) x %s loss curves', self.L, text)
        builder = get_loss_builder(self.datastore)
        self.build_datasets(builder)
        self.datastore.close()
        if 'losses_by_event' in self.datastore.parent:
            dstore = self.datastore.parent
        else:
            dstore = self.datastore
        allargs = [(dstore.filename, builder, rlzi) for rlzi in range(self.R)]
        mon = performance.Monitor(hdf5=hdf5.File(self.datastore.hdf5cache()))
        acc = list(parallel.Starmap(compute_loss_curves_maps, allargs, mon))
        # copy performance information from the cache to the datastore
        pd = mon.hdf5['performance_data'][()]
        hdf5.extend3(self.datastore.filename, 'performance_data', pd)
        self.datastore.open('r+')  # reopen
        self.datastore['task_info/compute_loss_curves_and_maps'] = (
            mon.hdf5['task_info/compute_loss_curves_maps'][()])
        self.datastore.open('r+')
        with self.monitor('saving loss_curves and maps', autoflush=True):
            for r, (curves, maps) in acc:
                if len(curves):  # some realization can give zero contribution
                    self.datastore['agg_curves-rlzs'][:, r] = curves
                if len(maps):  # conditional_loss_poes can be empty
                    self.datastore['agg_maps-rlzs'][:, r] = maps
        if self.R > 1:
            logging.info('Computing aggregate loss curves statistics')
            set_rlzs_stats(self.datastore, 'agg_curves')
            self.datastore.set_attrs(
                'agg_curves-stats', return_periods=builder.return_periods,
                loss_types=' '.join(self.riskmodel.loss_types))
            if oq.conditional_loss_poes:
                logging.info('Computing aggregate loss maps statistics')
                set_rlzs_stats(self.datastore, 'agg_maps')

        # sanity check with the asset_loss_table
        if oq.asset_loss_table and len(oq.aggregate_by) == 1:
            alt = self.datastore['asset_loss_table'][()]
            if alt.sum() == 0:  # nothing was saved
                return
            logging.info('Checking the loss curves')
            tags = getattr(self.assetcol.tagcol, oq.aggregate_by[0])[1:]
            T = len(tags)
            P = len(builder.return_periods)
            # sanity check on the loss curves for simple tag aggregation
            arr = self.assetcol.aggregate_by(oq.aggregate_by, alt)
            # shape (T, E, L)
            rlzs = self.datastore['events']['rlz']
            curves = numpy.zeros((P, self.R, self.L, T))
            for t in range(T):
                for r in range(self.R):
                    for l in range(self.L):
                        curves[:, r, l, t] = losses_by_period(
                            arr[t, rlzs == r, l],
                            builder.return_periods,
                            builder.num_events[r],
                            builder.eff_time)
            numpy.testing.assert_allclose(
                curves, self.datastore['agg_curves-rlzs'][()])
Beispiel #32
0
    def post_execute(self, times):
        """
        Compute and store average losses from the losses_by_event dataset,
        and then loss curves and maps.
        """
        if len(times):
            self.datastore.set_attrs('task_info/start_ebrisk',
                                     times=times,
                                     events_per_sid=numpy.mean(
                                         self.events_per_sid))
        oq = self.oqparam
        shp = self.get_shape(self.L)  # (L, T...)
        text = ' x '.join('%d(%s)' % (n, t)
                          for t, n in zip(oq.aggregate_by, shp[1:]))
        logging.info('Producing %d(loss_types) x %s loss curves', self.L, text)
        builder = get_loss_builder(self.datastore)
        self.build_datasets(builder)
        self.datastore.close()
        if 'losses_by_event' in self.datastore.parent:
            dstore = self.datastore.parent
        else:
            dstore = self.datastore
        allargs = [(dstore.filename, builder, rlzi) for rlzi in range(self.R)]
        mon = performance.Monitor(hdf5=hdf5.File(self.datastore.hdf5cache()))
        acc = list(parallel.Starmap(compute_loss_curves_maps, allargs, mon))
        # copy performance information from the cache to the datastore
        pd = mon.hdf5['performance_data'][()]
        hdf5.extend3(self.datastore.filename, 'performance_data', pd)
        self.datastore.open('r+')  # reopen
        self.datastore['task_info/compute_loss_curves_and_maps'] = (
            mon.hdf5['task_info/compute_loss_curves_maps'][()])
        self.datastore.open('r+')
        with self.monitor('saving loss_curves and maps', autoflush=True):
            for r, (curves, maps) in acc:
                if len(curves):  # some realization can give zero contribution
                    self.datastore['agg_curves-rlzs'][:, r] = curves
                if len(maps):  # conditional_loss_poes can be empty
                    self.datastore['agg_maps-rlzs'][:, r] = maps
        if self.R > 1:
            logging.info('Computing aggregate loss curves statistics')
            set_rlzs_stats(self.datastore, 'agg_curves')
            self.datastore.set_attrs('agg_curves-stats',
                                     return_periods=builder.return_periods,
                                     loss_types=' '.join(
                                         self.riskmodel.loss_types))
            if oq.conditional_loss_poes:
                logging.info('Computing aggregate loss maps statistics')
                set_rlzs_stats(self.datastore, 'agg_maps')

        # sanity check with the asset_loss_table
        if oq.asset_loss_table and len(oq.aggregate_by) == 1:
            alt = self.datastore['asset_loss_table'][()]
            if alt.sum() == 0:  # nothing was saved
                return
            logging.info('Checking the loss curves')
            tags = getattr(self.assetcol.tagcol, oq.aggregate_by[0])[1:]
            T = len(tags)
            P = len(builder.return_periods)
            # sanity check on the loss curves for simple tag aggregation
            arr = self.assetcol.aggregate_by(oq.aggregate_by, alt)
            # shape (T, E, L)
            rlzs = self.datastore['events']['rlz']
            curves = numpy.zeros((P, self.R, self.L, T))
            for t in range(T):
                for r in range(self.R):
                    for l in range(self.L):
                        curves[:, r, l,
                               t] = losses_by_period(arr[t, rlzs == r, l],
                                                     builder.return_periods,
                                                     builder.num_events[r],
                                                     builder.eff_time)
            numpy.testing.assert_allclose(
                curves, self.datastore['agg_curves-rlzs'][()])
Beispiel #33
0
    def post_execute(self, result):
        """
        Compute stats for the aggregated distributions and save
        the results on the datastore.
        """
        if not result:
            self.collapsed()
            return
        dstates = self.crmodel.damage_states
        ltypes = self.crmodel.loss_types
        L = self.L = len(ltypes)
        R = self.R
        D = len(dstates)
        A = len(self.assetcol)
        E = len(self.datastore['events'])

        # reduction factor
        matrixsize = A * E * L * 4
        realsize = self.datastore.getsize('risk_by_event')
        logging.info('Saving %s in risk_by_event (instead of %s)',
                     humansize(realsize), humansize(matrixsize))

        # avg_ratio = ratio used when computing the averages
        oq = self.oqparam
        avg_ratio = 1. / self.param['num_events']

        # damage by asset
        d_asset = numpy.zeros((A, R, L, D), F32)
        for (l, r, a, tot) in result['d_asset']:
            d_asset[a, r, l] = tot * avg_ratio[r]
        self.datastore['damages-rlzs'] = d_asset
        set_rlzs_stats(self.datastore,
                       'damages',
                       asset_id=self.assetcol['id'],
                       loss_type=oq.loss_names,
                       dmg_state=dstates)

        tot = self.assetcol['value-number'].sum()
        dt = F32 if self.param['float_dmg_dist'] else U32
        dbe = numpy.zeros((self.E, L, D), dt)  # shape E, L, D
        dbe[:, :, 0] = tot
        alt = self.datastore.read_df('risk_by_event')
        df = alt.groupby(['event_id', 'loss_id']).sum().reset_index()
        df['agg_id'] = A
        for col in df.columns:
            hdf5.extend(self.datastore['risk_by_event/' + col], df[col])
        self.datastore.set_attrs('risk_by_event', K=A)
        self.sanity_check()

        # consequence distributions
        del result['d_asset']
        del result['d_event']
        for name, csq in result.items():
            # name is something like avg_losses
            c_asset = numpy.zeros((A, R, L), F32)
            for (l, r, a, stat) in result[name]:
                c_asset[a, r, l] = stat * avg_ratio[r]
            self.datastore[name + '-rlzs'] = c_asset
            set_rlzs_stats(self.datastore,
                           name,
                           asset_id=self.assetcol['id'],
                           loss_type=oq.loss_names)