Пример #1
0
def extract_agg_curves(dstore, what):
    """
    Aggregate loss curves of the given loss type and tags for
    event based risk calculations. Use it as
    /extract/agg_curves/structural?taxonomy=RC&zipcode=20126
    :returns:
        array of shape (S, P), being P the number of return periods
        and S the number of statistics
    """
    from openquake.calculators.export.loss_curves import get_loss_builder
    oq = dstore['oqparam']
    loss_type, tags = get_loss_type_tags(what)
    if 'curves-stats' in dstore:  # event_based_risk
        losses = _get_curves(dstore['curves-stats'], oq.lti[loss_type])
        stats = dstore['curves-stats'].attrs['stats']
    elif 'curves-rlzs' in dstore:  # event_based_risk, 1 rlz
        losses = _get_curves(dstore['curves-rlzs'], oq.lti[loss_type])
        assert losses.shape[1] == 1, 'There must be a single realization'
        stats = [b'mean']  # suitable to be stored as hdf5 attribute
    else:
        raise KeyError('No curves found in %s' % dstore)
    res = _filter_agg(dstore['assetcol'], losses, tags, stats)
    cc = dstore['cost_calculator']
    res.units = cc.get_units(loss_types=[loss_type])
    res.return_periods = get_loss_builder(dstore).return_periods
    return res
Пример #2
0
def extract_agg_curves(dstore, what):
    """
    Aggregate loss curves of the given loss type and tags for
    event based risk calculations. Use it as
    /extract/agg_curves/structural?taxonomy=RC&zipcode=20126
    :returns:
        array of shape (S, P), being P the number of return periods
        and S the number of statistics
    """
    from openquake.calculators.export.loss_curves import get_loss_builder
    oq = dstore['oqparam']
    loss_type, tags = get_loss_type_tags(what)
    if 'curves-stats' in dstore:  # event_based_risk
        losses = _get_curves(dstore['curves-stats'], oq.lti[loss_type])
        stats = dstore['curves-stats'].attrs['stats']
    elif 'curves-rlzs' in dstore:  # event_based_risk, 1 rlz
        losses = _get_curves(dstore['curves-rlzs'], oq.lti[loss_type])
        assert losses.shape[1] == 1, 'There must be a single realization'
        stats = [b'mean']  # suitable to be stored as hdf5 attribute
    else:
        raise KeyError('No curves found in %s' % dstore)
    res = _filter_agg(dstore['assetcol'], losses, tags, stats)
    cc = dstore['cost_calculator']
    res.units = cc.get_units(loss_types=[loss_type])
    res.return_periods = get_loss_builder(dstore).return_periods
    return res
Пример #3
0
 def post_execute(self, times):
     """
     Compute and store average losses from the losses_by_event dataset,
     and then loss curves and maps.
     """
     self.datastore.set_attrs('task_info/start_ebrisk', times=times)
     oq = self.oqparam
     elt_length = len(self.datastore['losses_by_event'])
     builder = get_loss_builder(self.datastore)
     self.build_datasets(builder)
     mon = performance.Monitor(hdf5=hdf5.File(self.datastore.hdf5cache()))
     smap = parallel.Starmap(compute_loss_curves_maps, monitor=mon)
     self.datastore.close()
     acc = []
     ct = oq.concurrent_tasks or 1
     for elt_slice in general.split_in_slices(elt_length, ct):
         smap.submit(self.datastore.filename, elt_slice,
                     oq.conditional_loss_poes, oq.individual_curves)
     acc = smap.reduce(acc=[])
     # copy performance information from the cache to the datastore
     pd = mon.hdf5['performance_data'].value
     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'].value)
     with self.monitor('saving loss_curves and maps', autoflush=True):
         for name, idx, arr in acc:
             for ij, val in numpy.ndenumerate(arr):
                 self.datastore[name][ij + idx] = val
Пример #4
0
 def __init__(self, calc):
     self.datastore = calc.datastore
     self.oqparam = calc.oqparam
     self._monitor = calc._monitor
     self.riskmodel = calc.riskmodel
     self.loss_builder = get_loss_builder(calc.datastore)
     P = len(self.oqparam.conditional_loss_poes)
     self.loss_maps_dt = self.oqparam.loss_dt((F32, (P,)))
Пример #5
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'][()])
Пример #6
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)
Пример #7
0
    def post_execute(self, num_events):
        """
        Save risk data and possibly execute the EbrPostCalculator
        """
        # gmv[:-2] are the total gmv per each IMT
        gmv = sum(gm[:-2].sum() for gm in self.gmdata.values())
        if not gmv:
            raise RuntimeError('No GMFs were generated, perhaps they were '
                               'all below the minimum_intensity threshold')

        if 'agg_loss_table' not in self.datastore:
            logging.warning(
                'No losses were generated: most likely there is an error in y'
                'our input files or the GMFs were below the minimum intensity')
        else:
            self.datastore.set_nbytes('agg_loss_table')
            E = sum(num_events.values())
            agglt = self.datastore['agg_loss_table']
            agglt.attrs['nonzero_fraction'] = len(agglt) / E

        # build aggregate loss curves
        self.before_export()  # set 'realizations'
        oq = self.oqparam
        b = get_loss_builder(self.datastore)
        alt = self.datastore['agg_loss_table']
        stats = oq.risk_stats()
        array, array_stats = b.build(alt, 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 array_stats is not None:
            self.datastore['agg_curves-stats'] = array_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)
Пример #8
0
    def pre_execute(self):
        oq = self.oqparam
        super().pre_execute('event_based')
        parent = self.datastore.parent
        if not self.oqparam.ground_motion_fields:
            return  # this happens in the reportwriter

        self.L = len(self.riskmodel.lti)
        self.T = len(self.assetcol.tagcol)
        self.A = len(self.assetcol)
        self.I = oq.insured_losses + 1
        if parent:
            self.datastore['csm_info'] = parent['csm_info']
            self.eids = sorted(parent['events']['eid'])
        else:
            self.eids = sorted(self.datastore['events']['eid'])
        if oq.return_periods != [0]:
            # setting return_periods = 0 disable loss curves and maps
            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 loss curves',
                             eff_time)
            else:
                self.param['builder'] = get_loss_builder(
                    parent if parent else self.datastore, oq.return_periods,
                    oq.loss_dt())
        # sorting the eids is essential to get the epsilons in the right
        # order (i.e. consistent with the one used in ebr from ruptures)
        self.E = len(self.eids)
        eps = self.epsilon_getter()()
        # FIXME: commented because it can be misleading
        # if not oq.ignore_covs:
        #     logging.info('Generating %s of epsilons',
        #                  humansize(self.A * self.E * 4))
        self.riskinputs = self.build_riskinputs('gmf', eps, self.E)
        self.param['insured_losses'] = oq.insured_losses
        self.param['avg_losses'] = oq.avg_losses
        self.param['ses_ratio'] = oq.ses_ratio
        self.param['stats'] = oq.risk_stats()
        self.param['conditional_loss_poes'] = oq.conditional_loss_poes
        self.taskno = 0
        self.start = 0
        avg_losses = self.oqparam.avg_losses
        if avg_losses:
            self.dset = self.datastore.create_dset(
                'avg_losses-rlzs', F32, (self.A, self.R, self.L * self.I))
        self.agglosses = numpy.zeros((self.E, self.R, self.L * self.I), F32)
        self.num_losses = numpy.zeros((self.A, self.R), U32)
        if 'builder' in self.param:
            self.build_datasets(self.param['builder'])
        if parent:
            parent.close()  # avoid fork issues
Пример #9
0
    def pre_execute(self):
        oq = self.oqparam
        super().pre_execute()
        parent = self.datastore.parent
        if not oq.ground_motion_fields:
            return  # this happens in the reportwriter

        self.L = len(self.crmodel.lti)
        self.T = len(self.assetcol.tagcol)
        self.A = len(self.assetcol)
        if parent:
            self.datastore['csm_info'] = parent['csm_info']
            self.events = parent['events'][('id', 'rlz_id')]
            logging.info('There are %d ruptures and %d events',
                         len(parent['ruptures']), len(self.events))
        else:
            self.events = self.datastore['events'][('id', 'rlz_id')]
        if oq.return_periods != [0]:
            # setting return_periods = 0 disable loss curves and maps
            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)
            else:
                self.param['builder'] = get_loss_builder(
                    parent if parent else self.datastore, oq.return_periods,
                    oq.loss_dt())
        # sorting the eids is essential to get the epsilons in the right
        # order (i.e. consistent with the one used in ebr from ruptures)
        self.riskinputs = self.build_riskinputs('gmf')
        self.param['tempname'] = riskinput.cache_epsilons(
            self.datastore, oq, self.assetcol, self.crmodel, self.E)
        self.param['avg_losses'] = oq.avg_losses
        self.param['ses_ratio'] = oq.ses_ratio
        self.param['stats'] = list(oq.hazard_stats().items())
        self.param['conditional_loss_poes'] = oq.conditional_loss_poes
        self.taskno = 0
        self.start = 0
        avg_losses = oq.avg_losses
        if avg_losses:
            self.dset = self.datastore.create_dset('avg_losses-rlzs', F32,
                                                   (self.A, self.R, self.L))
        self.agglosses = numpy.zeros((self.E, self.L), F32)
        if 'builder' in self.param:
            logging.warning(
                'Building the loss curves and maps for each asset is '
                'deprecated: consider building the aggregate curves and '
                'maps with the ebrisk calculator instead')
            self.build_datasets(self.param['builder'])
        if parent:
            parent.close()  # avoid concurrent reading issues
Пример #10
0
    def pre_execute(self):
        oq = self.oqparam
        super().pre_execute()
        parent = self.datastore.parent
        if not oq.ground_motion_fields:
            return  # this happens in the reportwriter

        self.L = len(self.riskmodel.lti)
        self.T = len(self.assetcol.tagcol)
        self.A = len(self.assetcol)
        if parent:
            self.datastore['csm_info'] = parent['csm_info']
            self.events = parent['events'][('id', 'rlz')]
        else:
            self.events = self.datastore['events'][('id', 'rlz')]
        if oq.return_periods != [0]:
            # setting return_periods = 0 disable loss curves and maps
            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)
            else:
                self.param['builder'] = get_loss_builder(
                    parent if parent else self.datastore,
                    oq.return_periods, oq.loss_dt())
        # sorting the eids is essential to get the epsilons in the right
        # order (i.e. consistent with the one used in ebr from ruptures)
        self.riskinputs = self.build_riskinputs('gmf')
        self.param['epspath'] = riskinput.cache_epsilons(
            self.datastore, oq, self.assetcol, self.riskmodel, self.E)
        self.param['avg_losses'] = oq.avg_losses
        self.param['ses_ratio'] = oq.ses_ratio
        self.param['stats'] = list(oq.hazard_stats().items())
        self.param['conditional_loss_poes'] = oq.conditional_loss_poes
        self.taskno = 0
        self.start = 0
        avg_losses = oq.avg_losses
        if avg_losses:
            self.dset = self.datastore.create_dset(
                'avg_losses-rlzs', F32, (self.A, self.R, self.L))
        self.agglosses = numpy.zeros((self.E, self.L), F32)
        if 'builder' in self.param:
            logging.warning(
                'Building the loss curves and maps for each asset is '
                'deprecated: consider building the aggregate curves and '
                'maps with the ebrisk calculator instead')
            self.build_datasets(self.param['builder'])
        if parent:
            parent.close()  # avoid concurrent reading issues
Пример #11
0
    def post_execute(self, result):
        """
        Call the EbrPostCalculator to compute the aggregate loss curves
        """
        if 'losses_by_event' not in self.datastore:
            logging.warning(
                'No losses were generated: most likely there is an error '
                'in your input files or the GMFs were below the minimum '
                'intensity')
        else:
            self.datastore.set_nbytes('losses_by_event')
            E = sum(result.values())
            agglt = self.datastore['losses_by_event']
            agglt.attrs['nonzero_fraction'] = len(agglt) / E

        self.param = dict(builder=get_loss_builder(self.datastore))
        self.postproc()
Пример #12
0
def compute_loss_curves_maps(filename, elt_slice, clp, individual_curves,
                             monitor):
    """
    :param filename: path to the datastore
    :param elt_slice: slice of the event loss table
    :param clp: conditional loss poes used to computed the maps
    :param individual_curves: if True, build the individual curves and maps
    :param monitor: a Monitor instance
    :yields:
        dictionaries with keys idx, agg_curves-rlzs, agg_curves-stats,
        agg_maps-rlzs, agg_maps-stats
    """
    with datastore.read(filename) as dstore:
        oq = dstore['oqparam']
        stats = oq.hazard_stats()
        builder = get_loss_builder(dstore)
        R = len(dstore['weights'])
        losses = [[] for _ in range(R)]
        elt = dstore['losses_by_event'][elt_slice]
        for rec in elt:
            losses[rec['rlzi']].append(rec['loss'])
    results = []
    for multi_index, _ in numpy.ndenumerate(elt[0]['loss']):
        result = {}
        thelosses = [[ls[multi_index] for ls in loss] for loss in losses]
        result['agg_curves-rlzs'], result['agg_curves-stats'] = (
            builder.build_pair(thelosses, stats))
        if R > 1 and individual_curves is False:
            del result['agg_curves-rlzs']
        if clp:
            result['agg_maps-rlzs'], result['agg_maps-stats'] = (
                builder.build_loss_maps(thelosses, clp, stats))
            if R > 1 and individual_curves is False:
                del result['agg_maps-rlzs']
        for name, arr in result.items():
            if arr is not None:
                results.append((name, multi_index, arr))
    return results
Пример #13
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)
Пример #14
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'][()])
Пример #15
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'][()])
Пример #16
0
    def pre_execute(self):
        oq = self.oqparam
        if 'gmfs' in oq.inputs:
            assert not oq.hazard_calculation_id, (
                'You cannot use --hc together with gmfs_file')
            self.pre_calculator = None
            super().pre_execute()
            parent = ()
        elif oq.hazard_calculation_id:
            super().pre_execute()
            parent = self.datastore.parent
            oqp = parent['oqparam']
            if oqp.investigation_time != oq.investigation_time:
                raise ValueError(
                    'The parent calculation was using investigation_time=%s'
                    ' != %s' % (oqp.investigation_time, oq.investigation_time))
            if oqp.minimum_intensity != oq.minimum_intensity:
                raise ValueError(
                    'The parent calculation was using minimum_intensity=%s'
                    ' != %s' % (oqp.minimum_intensity, oq.minimum_intensity))
        else:
            ebcalc = base.calculators[self.pre_calculator](self.oqparam)
            ebcalc.run(close=False)
            self.set_log_format()
            parent = self.dynamic_parent = self.datastore.parent = (
                ebcalc.datastore)
            oq.hazard_calculation_id = parent.calc_id
            self.datastore['oqparam'] = oq
            self.param = ebcalc.param
            self.sitecol = ebcalc.sitecol
            self.assetcol = ebcalc.precalc.assetcol
            self.riskmodel = ebcalc.riskmodel

        self.L = len(self.riskmodel.lti)
        self.T = len(self.assetcol.tagcol)
        self.A = len(self.assetcol)
        self.I = oq.insured_losses + 1
        if parent:
            self.datastore['csm_info'] = parent['csm_info']
            self.rlzs_assoc = parent['csm_info'].get_rlzs_assoc()
            self.eids = sorted(parent['events']['eid'])
        else:
            self.eids = sorted(self.datastore['events']['eid'])
        if oq.return_periods != [0]:
            # setting return_periods = 0 disable loss curves and maps
            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 loss curves',
                             eff_time)
            else:
                self.param['builder'] = get_loss_builder(
                    parent if parent else self.datastore, oq.return_periods,
                    oq.loss_dt())
        # sorting the eids is essential to get the epsilons in the right
        # order (i.e. consistent with the one used in ebr from ruptures)
        self.E = len(self.eids)
        eps = self.epsilon_getter()()
        self.riskinputs = self.build_riskinputs('gmf', eps, self.E)
        self.param['insured_losses'] = oq.insured_losses
        self.param['avg_losses'] = oq.avg_losses
        self.param['ses_ratio'] = oq.ses_ratio
        self.param['stats'] = oq.risk_stats()
        self.param['conditional_loss_poes'] = oq.conditional_loss_poes
        self.taskno = 0
        self.start = 0
        avg_losses = self.oqparam.avg_losses
        if avg_losses:
            self.dset = self.datastore.create_dset(
                'avg_losses-rlzs', F32, (self.A, self.R, self.L * self.I))
        self.agglosses = numpy.zeros((self.E, self.R, self.L * self.I), F32)
        self.num_losses = numpy.zeros((self.A, self.R), U32)
        if 'builder' in self.param:
            self.build_datasets(self.param['builder'])
        if parent:
            parent.close()  # avoid fork issues