def test_compute_quantile_curve(self): expected_curve = numpy.array([ 9.9178000e-01, 9.8892000e-01, 9.6903000e-01, 9.4030000e-01, 8.8405000e-01, 7.8782000e-01, 6.4897250e-01, 4.8284250e-01, 3.4531500e-01, 3.2337000e-01, 1.8880500e-01, 9.5574000e-02, 4.3707250e-02, 1.9643000e-02, 8.1923000e-03, 2.9157000e-03, 7.9955000e-04, 1.5233000e-04, 1.5582000e-05]) quantile = 0.75 curves = [ [9.8161000e-01, 9.7837000e-01, 9.5579000e-01, 9.2555000e-01, 8.7052000e-01, 7.8214000e-01, 6.5708000e-01, 5.0526000e-01, 3.7044000e-01, 3.4740000e-01, 2.0502000e-01, 1.0506000e-01, 4.6531000e-02, 1.7548000e-02, 5.4791000e-03, 1.3377000e-03, 2.2489000e-04, 2.2345000e-05, 4.2696000e-07], [9.7309000e-01, 9.6857000e-01, 9.3853000e-01, 9.0089000e-01, 8.3673000e-01, 7.4057000e-01, 6.1272000e-01, 4.6467000e-01, 3.3694000e-01, 3.1536000e-01, 1.8340000e-01, 9.2412000e-02, 4.0202000e-02, 1.4900000e-02, 4.5924000e-03, 1.1126000e-03, 1.8647000e-04, 1.8882000e-05, 4.7123000e-07], [9.9178000e-01, 9.8892000e-01, 9.6903000e-01, 9.4030000e-01, 8.8405000e-01, 7.8782000e-01, 6.4627000e-01, 4.7537000e-01, 3.3168000e-01, 3.0827000e-01, 1.7279000e-01, 8.8360000e-02, 4.2766000e-02, 1.9643000e-02, 8.1923000e-03, 2.9157000e-03, 7.9955000e-04, 1.5233000e-04, 1.5582000e-05], [9.8885000e-01, 9.8505000e-01, 9.5972000e-01, 9.2494000e-01, 8.6030000e-01, 7.5574000e-01, 6.1009000e-01, 4.4217000e-01, 3.0543000e-01, 2.8345000e-01, 1.5760000e-01, 8.0225000e-02, 3.8681000e-02, 1.7637000e-02, 7.2685000e-03, 2.5474000e-03, 6.8347000e-04, 1.2596000e-04, 1.2853000e-05], [9.9178000e-01, 9.8892000e-01, 9.6903000e-01, 9.4030000e-01, 8.8405000e-01, 7.8782000e-01, 6.4627000e-01, 4.7537000e-01, 3.3168000e-01, 3.0827000e-01, 1.7279000e-01, 8.8360000e-02, 4.2766000e-02, 1.9643000e-02, 8.1923000e-03, 2.9157000e-03, 7.9955000e-04, 1.5233000e-04, 1.5582000e-05], ] actual_curve = scientific.quantile_curve(curves, quantile) # TODO(LB): Check with our hazard experts to see if this is reasonable # tolerance. Better yet, get a fresh set of test data. (This test data # was just copied verbatim from from some old tests in # `tests/hazard_test.py`. numpy.testing.assert_allclose(expected_curve, actual_curve, atol=0.005) # Since this implementation is an optimized but equivalent version of # scipy's `mquantiles`, compare algorithms just to prove they are the # same: scipy_curve = mstats.mquantiles(curves, prob=quantile, axis=0)[0] numpy.testing.assert_allclose(scipy_curve, actual_curve)
def test_compute_weighted_quantile_curve_case1(self): expected_curve = numpy.array([0.69909, 0.60859, 0.50328]) quantile = 0.3 curves = [ [9.9996e-01, 9.9962e-01, 9.9674e-01], [6.9909e-01, 6.0859e-01, 5.0328e-01], [1.0000e+00, 9.9996e-01, 9.9947e-01], ] weights = [0.5, 0.3, 0.2] actual_curve = scientific.quantile_curve(curves, quantile, weights) numpy.testing.assert_allclose(expected_curve, actual_curve)
def test_compute_weighted_quantile_curve_case2(self): expected_curve = numpy.array([0.89556, 0.83045, 0.73646]) quantile = 0.3 curves = [ [9.2439e-01, 8.6700e-01, 7.7785e-01], [8.9556e-01, 8.3045e-01, 7.3646e-01], [9.1873e-01, 8.6697e-01, 7.8992e-01], ] weights = [0.2, 0.3, 0.5] actual_curve = scientific.quantile_curve(curves, quantile, weights) numpy.testing.assert_allclose(expected_curve, actual_curve)
def post_execute(self, curves_by_trt_gsim): """ Collect the hazard curves by realization and export them. :param curves_by_trt_gsim: a dictionary (trt_id, gsim) -> hazard curves """ self.curves_by_trt_gsim = curves_by_trt_gsim oq = self.oqparam zc = zero_curves(len(self.sitecol), oq.imtls) curves_by_rlz = self.rlzs_assoc.combine_curves( curves_by_trt_gsim, agg_curves, zc) rlzs = self.rlzs_assoc.realizations nsites = len(self.sitecol) if oq.individual_curves: for rlz, curves in curves_by_rlz.iteritems(): self.store_curves('rlz-%d' % rlz.ordinal, curves) if len(rlzs) == 1: # cannot compute statistics [self.mean_curves] = curves_by_rlz.values() return weights = (None if oq.number_of_logic_tree_samples else [rlz.weight for rlz in rlzs]) mean = oq.mean_hazard_curves if mean: self.mean_curves = numpy.array(zc) for imt in oq.imtls: self.mean_curves[imt] = scientific.mean_curve( [curves_by_rlz[rlz][imt] for rlz in rlzs], weights) self.quantile = {} for q in oq.quantile_hazard_curves: self.quantile[q] = qc = numpy.array(zc) for imt in oq.imtls: curves = [curves_by_rlz[rlz][imt] for rlz in rlzs] qc[imt] = scientific.quantile_curve( curves, q, weights).reshape((nsites, -1)) if mean: self.store_curves('mean', self.mean_curves) for q in self.quantile: self.store_curves('quantile-%s' % q, self.quantile[q])
def save_curves(self, curves_by_rlz): """ Save the dictionary curves_by_rlz """ oq = self.oqparam rlzs = self.rlzs_assoc.realizations nsites = len(self.sitecol) if oq.individual_curves: with self.monitor('save curves_by_rlz', autoflush=True): for rlz, curves in curves_by_rlz.items(): self.store_curves('rlz-%03d' % rlz.ordinal, curves, rlz) if len(rlzs) == 1: # cannot compute statistics [self.mean_curves] = curves_by_rlz.values() return with self.monitor('compute and save statistics', autoflush=True): weights = (None if oq.number_of_logic_tree_samples else [rlz.weight for rlz in rlzs]) # mean curves are always computed but stored only on request zc = zero_curves(nsites, oq.imtls) self.mean_curves = numpy.array(zc) for imt in oq.imtls: self.mean_curves[imt] = scientific.mean_curve( [curves_by_rlz.get(rlz, zc)[imt] for rlz in rlzs], weights) self.quantile = {} for q in oq.quantile_hazard_curves: self.quantile[q] = qc = numpy.array(zc) for imt in oq.imtls: curves = [curves_by_rlz[rlz][imt] for rlz in rlzs] qc[imt] = scientific.quantile_curve(curves, q, weights).reshape( (nsites, -1)) if oq.mean_hazard_curves: self.store_curves('mean', self.mean_curves) for q in self.quantile: self.store_curves('quantile-%s' % q, self.quantile[q])
def save_curves(self, curves_by_rlz): """ Save the dictionary curves_by_rlz """ oq = self.oqparam rlzs = self.rlzs_assoc.realizations nsites = len(self.sitecol) if oq.individual_curves: with self.monitor('save curves_by_rlz', autoflush=True): for rlz, curves in curves_by_rlz.items(): self.store_curves('rlz-%03d' % rlz.ordinal, curves, rlz) if len(rlzs) == 1: # cannot compute statistics [self.mean_curves] = curves_by_rlz.values() return with self.monitor('compute and save statistics', autoflush=True): weights = (None if oq.number_of_logic_tree_samples else [rlz.weight for rlz in rlzs]) # mean curves are always computed but stored only on request zc = zero_curves(nsites, oq.imtls) self.mean_curves = numpy.array(zc) for imt in oq.imtls: self.mean_curves[imt] = scientific.mean_curve( [curves_by_rlz.get(rlz, zc)[imt] for rlz in rlzs], weights) self.quantile = {} for q in oq.quantile_hazard_curves: self.quantile[q] = qc = numpy.array(zc) for imt in oq.imtls: curves = [curves_by_rlz[rlz][imt] for rlz in rlzs] qc[imt] = scientific.quantile_curve( curves, q, weights).reshape((nsites, -1)) if oq.mean_hazard_curves: self.store_curves('mean', self.mean_curves) for q in self.quantile: self.store_curves('quantile-%s' % q, self.quantile[q])
def do_aggregate_post_proc(self): """ Grab hazard data for all realizations and sites from the database and compute mean and/or quantile aggregates (depending on which options are enabled in the calculation). Post-processing results will be stored directly into the database. """ num_rlzs = len(self._realizations) if not num_rlzs: logs.LOG.warn('No realizations for hazard_calculation_id=%d', self.job.id) return elif num_rlzs == 1 and self.quantile_hazard_curves: logs.LOG.warn( 'There is only one realization, the configuration parameter ' 'quantile_hazard_curves should not be set') return weights = (None if self.oqparam.number_of_logic_tree_samples else [rlz.weight for rlz in self._realizations]) if self.oqparam.mean_hazard_curves: # create a new `HazardCurve` 'container' record for mean # curves (virtual container for multiple imts) models.HazardCurve.objects.create( output=models.Output.objects.create_output( self.job, "mean-curves-multi-imt", "hazard_curve_multi"), statistics="mean", imt=None, investigation_time=self.oqparam.investigation_time) for quantile in self.quantile_hazard_curves: # create a new `HazardCurve` 'container' record for quantile # curves (virtual container for multiple imts) models.HazardCurve.objects.create( output=models.Output.objects.create_output( self.job, 'quantile(%s)-curves' % quantile, "hazard_curve_multi"), statistics="quantile", imt=None, quantile=quantile, investigation_time=self.oqparam.investigation_time) for imt, imls in self.oqparam.imtls.items(): im_type, sa_period, sa_damping = from_string(imt) # prepare `output` and `hazard_curve` containers in the DB: container_ids = dict() if self.oqparam.mean_hazard_curves: mean_output = self.job.get_or_create_output( display_name='Mean Hazard Curves %s' % imt, output_type='hazard_curve' ) mean_hc = models.HazardCurve.objects.create( output=mean_output, investigation_time=self.oqparam.investigation_time, imt=im_type, imls=imls, sa_period=sa_period, sa_damping=sa_damping, statistics='mean' ) self._hazard_curves.append(mean_hc) container_ids['mean'] = mean_hc.id for quantile in self.quantile_hazard_curves: q_output = self.job.get_or_create_output( display_name=( '%s quantile Hazard Curves %s' % (quantile, imt)), output_type='hazard_curve') q_hc = models.HazardCurve.objects.create( output=q_output, investigation_time=self.oqparam.investigation_time, imt=im_type, imls=imls, sa_period=sa_period, sa_damping=sa_damping, statistics='quantile', quantile=quantile ) self._hazard_curves.append(q_hc) container_ids['q%s' % quantile] = q_hc.id # num_rlzs * num_sites * num_levels # NB: different IMTs can have different num_levels all_curves_for_imt = numpy.array(self.curves_by_imt[imt]) del self.curves_by_imt[imt] # save memory inserter = writer.CacheInserter( models.HazardCurveData, max_cache_size=10000) # curve_poes below is an array num_rlzs * num_levels for i, site in enumerate(self.site_collection): wkt = site.location.wkt2d curve_poes = numpy.array( [c_by_rlz[i] for c_by_rlz in all_curves_for_imt]) # calc quantiles first for quantile in self.quantile_hazard_curves: q_curve = scientific.quantile_curve( curve_poes, quantile, weights) inserter.add( models.HazardCurveData( hazard_curve_id=( container_ids['q%s' % quantile]), poes=q_curve.tolist(), location=wkt)) # then means if self.mean_hazard_curves and len(curve_poes): m_curve = scientific.mean_curve(curve_poes, weights) inserter.add( models.HazardCurveData( hazard_curve_id=container_ids['mean'], poes=m_curve.tolist(), location=wkt)) inserter.flush()
def post_execute(self, curves_by_trt_gsim): """ Collect the hazard curves by realization and export them. :param curves_by_trt_gsim: a dictionary (trt_id, gsim) -> hazard curves """ # save calculation time per source try: calc_times = curves_by_trt_gsim.pop('calc_times') except KeyError: pass else: sources = self.csm.get_sources() info = [] for i, dt in calc_times: src = sources[i] info.append((src.trt_model_id, src.source_id, dt)) info.sort(key=operator.itemgetter(2), reverse=True) self.source_info = numpy.array(info, source_info_dt) # save curves_by_trt_gsim for sm in self.rlzs_assoc.csm_info.source_models: group = self.datastore.hdf5.create_group( 'curves_by_sm/' + '_'.join(sm.path)) group.attrs['source_model'] = sm.name for tm in sm.trt_models: for gsim in tm.gsims: try: curves = curves_by_trt_gsim[tm.id, gsim] except KeyError: # no data for the trt_model pass else: ts = '%03d-%s' % (tm.id, gsim) group[ts] = curves group[ts].attrs['trt'] = tm.trt oq = self.oqparam zc = zero_curves(len(self.sitecol.complete), oq.imtls) curves_by_rlz = self.rlzs_assoc.combine_curves( curves_by_trt_gsim, agg_curves, zc) rlzs = self.rlzs_assoc.realizations nsites = len(self.sitecol) if oq.individual_curves: for rlz, curves in curves_by_rlz.items(): self.store_curves('rlz-%03d' % rlz.ordinal, curves, rlz) if len(rlzs) == 1: # cannot compute statistics [self.mean_curves] = curves_by_rlz.values() return weights = (None if oq.number_of_logic_tree_samples else [rlz.weight for rlz in rlzs]) mean = oq.mean_hazard_curves if mean: self.mean_curves = numpy.array(zc) for imt in oq.imtls: self.mean_curves[imt] = scientific.mean_curve( [curves_by_rlz[rlz][imt] for rlz in rlzs], weights) self.quantile = {} for q in oq.quantile_hazard_curves: self.quantile[q] = qc = numpy.array(zc) for imt in oq.imtls: curves = [curves_by_rlz[rlz][imt] for rlz in rlzs] qc[imt] = scientific.quantile_curve( curves, q, weights).reshape((nsites, -1)) if mean: self.store_curves('mean', self.mean_curves) for q in self.quantile: self.store_curves('quantile-%s' % q, self.quantile[q])
def post_execute(self, curves_by_trt_gsim): """ Collect the hazard curves by realization and export them. :param curves_by_trt_gsim: a dictionary (trt_id, gsim) -> hazard curves """ with self.monitor('save curves_by_trt_gsim', autoflush=True): for sm in self.rlzs_assoc.csm_info.source_models: group = self.datastore.hdf5.create_group( 'curves_by_sm/' + '_'.join(sm.path)) group.attrs['source_model'] = sm.name for tm in sm.trt_models: for i, gsim in enumerate(tm.gsims): try: curves = curves_by_trt_gsim[tm.id, gsim] except KeyError: # no data for the trt_model pass else: ts = '%03d-%d' % (tm.id, i) if nonzero(curves): group[ts] = curves group[ts].attrs['trt'] = tm.trt group[ts].attrs['nbytes'] = curves.nbytes group[ts].attrs['gsim'] = str(gsim) self.datastore.set_nbytes(group.name) self.datastore.set_nbytes('curves_by_sm') oq = self.oqparam with self.monitor('combine and save curves_by_rlz', autoflush=True): zc = zero_curves(len(self.sitecol.complete), oq.imtls) curves_by_rlz = self.rlzs_assoc.combine_curves( curves_by_trt_gsim, agg_curves, zc) rlzs = self.rlzs_assoc.realizations nsites = len(self.sitecol) if oq.individual_curves: for rlz, curves in curves_by_rlz.items(): self.store_curves('rlz-%03d' % rlz.ordinal, curves, rlz) if len(rlzs) == 1: # cannot compute statistics [self.mean_curves] = curves_by_rlz.values() return with self.monitor('compute and save statistics', autoflush=True): weights = (None if oq.number_of_logic_tree_samples else [rlz.weight for rlz in rlzs]) # mean curves are always computed but stored only on request self.mean_curves = numpy.array(zc) for imt in oq.imtls: self.mean_curves[imt] = scientific.mean_curve( [curves_by_rlz[rlz][imt] for rlz in rlzs], weights) self.quantile = {} for q in oq.quantile_hazard_curves: self.quantile[q] = qc = numpy.array(zc) for imt in oq.imtls: curves = [curves_by_rlz[rlz][imt] for rlz in rlzs] qc[imt] = scientific.quantile_curve( curves, q, weights).reshape((nsites, -1)) if oq.mean_hazard_curves: self.store_curves('mean', self.mean_curves) for q in self.quantile: self.store_curves('quantile-%s' % q, self.quantile[q])
def post_execute(self, curves_by_trt_gsim): """ Collect the hazard curves by realization and export them. :param curves_by_trt_gsim: a dictionary (trt_id, gsim) -> hazard curves """ with self.monitor('save curves_by_trt_gsim', autoflush=True): for sm in self.rlzs_assoc.csm_info.source_models: group = self.datastore.hdf5.create_group('curves_by_sm/' + '_'.join(sm.path)) group.attrs['source_model'] = sm.name for tm in sm.trt_models: for i, gsim in enumerate(tm.gsims): try: curves = curves_by_trt_gsim[tm.id, gsim] except KeyError: # no data for the trt_model pass else: ts = '%03d-%d' % (tm.id, i) if nonzero(curves): group[ts] = curves group[ts].attrs['trt'] = tm.trt group[ts].attrs['nbytes'] = curves.nbytes group[ts].attrs['gsim'] = str(gsim) self.datastore.set_nbytes(group.name) self.datastore.set_nbytes('curves_by_sm') oq = self.oqparam with self.monitor('combine and save curves_by_rlz', autoflush=True): zc = zero_curves(len(self.sitecol.complete), oq.imtls) curves_by_rlz = self.rlzs_assoc.combine_curves( curves_by_trt_gsim, agg_curves, zc) rlzs = self.rlzs_assoc.realizations nsites = len(self.sitecol) if oq.individual_curves: for rlz, curves in curves_by_rlz.items(): self.store_curves('rlz-%03d' % rlz.ordinal, curves, rlz) if len(rlzs) == 1: # cannot compute statistics [self.mean_curves] = curves_by_rlz.values() return with self.monitor('compute and save statistics', autoflush=True): weights = (None if oq.number_of_logic_tree_samples else [rlz.weight for rlz in rlzs]) # mean curves are always computed but stored only on request self.mean_curves = numpy.array(zc) for imt in oq.imtls: self.mean_curves[imt] = scientific.mean_curve( [curves_by_rlz[rlz][imt] for rlz in rlzs], weights) self.quantile = {} for q in oq.quantile_hazard_curves: self.quantile[q] = qc = numpy.array(zc) for imt in oq.imtls: curves = [curves_by_rlz[rlz][imt] for rlz in rlzs] qc[imt] = scientific.quantile_curve(curves, q, weights).reshape( (nsites, -1)) if oq.mean_hazard_curves: self.store_curves('mean', self.mean_curves) for q in self.quantile: self.store_curves('quantile-%s' % q, self.quantile[q])
def post_execute(self, curves_by_trt_gsim): """ Collect the hazard curves by realization and export them. :param curves_by_trt_gsim: a dictionary (trt_id, gsim) -> hazard curves """ # save calculation time per source calc_times = getattr(curves_by_trt_gsim, 'calc_times', []) sources = self.csm.get_sources() infodict = collections.defaultdict(float) weight = {} for src_idx, dt in calc_times: src = sources[src_idx] weight[src.trt_model_id, src.source_id] = src.weight infodict[src.trt_model_id, src.source_id] += dt infolist = [key + (dt, weight[key]) for key, dt in infodict.items()] infolist.sort(key=operator.itemgetter(1), reverse=True) if infolist: self.source_info = numpy.array(infolist, source_info_dt) with self.monitor('save curves_by_trt_gsim', autoflush=True): for sm in self.rlzs_assoc.csm_info.source_models: group = self.datastore.hdf5.create_group( 'curves_by_sm/' + '_'.join(sm.path)) group.attrs['source_model'] = sm.name for tm in sm.trt_models: for i, gsim in enumerate(tm.gsims): try: curves = curves_by_trt_gsim[tm.id, gsim] except KeyError: # no data for the trt_model pass else: ts = '%03d-%d' % (tm.id, i) if nonzero(curves): group[ts] = curves group[ts].attrs['trt'] = tm.trt group[ts].attrs['nbytes'] = curves.nbytes group[ts].attrs['gsim'] = str(gsim) self.datastore.set_nbytes(group.name) self.datastore.set_nbytes('curves_by_sm') oq = self.oqparam with self.monitor('combine and save curves_by_rlz', autoflush=True): zc = zero_curves(len(self.sitecol.complete), oq.imtls) curves_by_rlz = self.rlzs_assoc.combine_curves( curves_by_trt_gsim, agg_curves, zc) rlzs = self.rlzs_assoc.realizations nsites = len(self.sitecol) if oq.individual_curves: for rlz, curves in curves_by_rlz.items(): self.store_curves('rlz-%03d' % rlz.ordinal, curves, rlz) if len(rlzs) == 1: # cannot compute statistics [self.mean_curves] = curves_by_rlz.values() return with self.monitor('compute and save statistics', autoflush=True): weights = (None if oq.number_of_logic_tree_samples else [rlz.weight for rlz in rlzs]) mean = oq.mean_hazard_curves if mean: self.mean_curves = numpy.array(zc) for imt in oq.imtls: self.mean_curves[imt] = scientific.mean_curve( [curves_by_rlz[rlz][imt] for rlz in rlzs], weights) self.quantile = {} for q in oq.quantile_hazard_curves: self.quantile[q] = qc = numpy.array(zc) for imt in oq.imtls: curves = [curves_by_rlz[rlz][imt] for rlz in rlzs] qc[imt] = scientific.quantile_curve( curves, q, weights).reshape((nsites, -1)) if mean: self.store_curves('mean', self.mean_curves) for q in self.quantile: self.store_curves('quantile-%s' % q, self.quantile[q])
def do_aggregate_post_proc(self): """ Grab hazard data for all realizations and sites from the database and compute mean and/or quantile aggregates (depending on which options are enabled in the calculation). Post-processing results will be stored directly into the database. """ num_rlzs = len(self._realizations) if not num_rlzs: logs.LOG.warn('No realizations for hazard_calculation_id=%d', self.job.id) return elif num_rlzs == 1 and self.quantile_hazard_curves: logs.LOG.warn( 'There is only one realization, the configuration parameter ' 'quantile_hazard_curves should not be set') return weights = (None if self.oqparam.number_of_logic_tree_samples else [rlz.weight for rlz in self._realizations]) if self.oqparam.mean_hazard_curves: # create a new `HazardCurve` 'container' record for mean # curves (virtual container for multiple imts) models.HazardCurve.objects.create( output=models.Output.objects.create_output( self.job, "mean-curves-multi-imt", "hazard_curve_multi"), statistics="mean", imt=None, investigation_time=self.oqparam.investigation_time) for quantile in self.quantile_hazard_curves: # create a new `HazardCurve` 'container' record for quantile # curves (virtual container for multiple imts) models.HazardCurve.objects.create( output=models.Output.objects.create_output( self.job, 'quantile(%s)-curves' % quantile, "hazard_curve_multi"), statistics="quantile", imt=None, quantile=quantile, investigation_time=self.oqparam.investigation_time) for imt, imls in self.oqparam.imtls.items(): im_type, sa_period, sa_damping = from_string(imt) # prepare `output` and `hazard_curve` containers in the DB: container_ids = dict() if self.oqparam.mean_hazard_curves: mean_output = self.job.get_or_create_output( display_name='Mean Hazard Curves %s' % imt, output_type='hazard_curve') mean_hc = models.HazardCurve.objects.create( output=mean_output, investigation_time=self.oqparam.investigation_time, imt=im_type, imls=imls, sa_period=sa_period, sa_damping=sa_damping, statistics='mean') self._hazard_curves.append(mean_hc) container_ids['mean'] = mean_hc.id for quantile in self.quantile_hazard_curves: q_output = self.job.get_or_create_output( display_name=('%s quantile Hazard Curves %s' % (quantile, imt)), output_type='hazard_curve') q_hc = models.HazardCurve.objects.create( output=q_output, investigation_time=self.oqparam.investigation_time, imt=im_type, imls=imls, sa_period=sa_period, sa_damping=sa_damping, statistics='quantile', quantile=quantile) self._hazard_curves.append(q_hc) container_ids['q%s' % quantile] = q_hc.id # num_rlzs * num_sites * num_levels # NB: different IMTs can have different num_levels all_curves_for_imt = numpy.array(self.curves_by_imt[imt]) del self.curves_by_imt[imt] # save memory inserter = writer.CacheInserter(models.HazardCurveData, max_cache_size=10000) # curve_poes below is an array num_rlzs * num_levels for i, site in enumerate(self.site_collection): wkt = site.location.wkt2d curve_poes = numpy.array( [c_by_rlz[i] for c_by_rlz in all_curves_for_imt]) # calc quantiles first for quantile in self.quantile_hazard_curves: q_curve = scientific.quantile_curve( curve_poes, quantile, weights) inserter.add( models.HazardCurveData( hazard_curve_id=(container_ids['q%s' % quantile]), poes=q_curve.tolist(), location=wkt)) # then means if self.mean_hazard_curves: m_curve = scientific.mean_curve(curve_poes, weights) inserter.add( models.HazardCurveData( hazard_curve_id=container_ids['mean'], poes=m_curve.tolist(), location=wkt)) inserter.flush()