def _collect_curve_keys_per_quantile(keys): quantile_values = {} while len(keys) > 0: quantile_key = keys.pop() curr_qv = tokens.quantile_value_from_hazard_curve_key(quantile_key) if curr_qv not in quantile_values: quantile_values[curr_qv] = [] quantile_values[curr_qv].append(quantile_key) return quantile_values
def _collect_curve_keys_per_quantile(keys): quantile_values = {} while len(keys) > 0: quantile_key = keys.pop() curr_qv = tokens.quantile_value_from_hazard_curve_key(quantile_key) if curr_qv not in quantile_values: quantile_values[curr_qv] = [] quantile_values[curr_qv].append(quantile_key) return quantile_values
def write_hazardcurve_file(self, curve_keys): """Generate a NRML file with hazard curves for a collection of hazard curves from KVS, identified through their KVS keys. curve_keys is a list of KVS keys of the hazard curves to be serialized. The hazard curve file can be written (1) for a set of hazard curves belonging to the same realization (= endBranchLabel) and a set of sites. (2) for a mean hazard curve at a set of sites (3) for a quantile hazard curve at a set of sites Mixing of these three cases is not allowed, i.e., all hazard curves from the set of curve_keys have to be either for the same realization, mean, or quantile. """ if _is_mean_hazard_curve_key(curve_keys[0]): hc_attrib_update = {'statistics': 'mean'} filename_part = 'mean' curve_mode = 'mean' elif _is_quantile_hazard_curve_key(curve_keys[0]): # get quantile value from KVS key quantile_value = tokens.quantile_value_from_hazard_curve_key( curve_keys[0]) hc_attrib_update = {'statistics': 'quantile', 'quantileValue': quantile_value} filename_part = "quantile-%.2f" % quantile_value curve_mode = 'quantile' elif _is_realization_hazard_curve_key(curve_keys[0]): realization_reference_str = \ tokens.realization_value_from_hazard_curve_key(curve_keys[0]) hc_attrib_update = {'endBranchLabel': realization_reference_str} filename_part = realization_reference_str curve_mode = 'realization' else: error_msg = "no valid hazard curve type found in KVS key" raise RuntimeError(error_msg) nrml_file = "%s-%s.xml" % (HAZARD_CURVE_FILENAME_PREFIX, filename_part) nrml_path = os.path.join(self['BASE_PATH'], self['OUTPUT_DIR'], nrml_file) iml_list = [float(param) for param in self.params['INTENSITY_MEASURE_LEVELS'].split(",")] LOG.debug("Generating NRML hazard curve file for mode %s, "\ "%s hazard curves: %s" % (curve_mode, len(curve_keys), nrml_file)) LOG.debug("IML: %s" % iml_list) xmlwriter = hazard_output.HazardCurveXMLWriter(nrml_path) hc_data = [] for hc_key in curve_keys: if curve_mode == 'mean' and not _is_mean_hazard_curve_key(hc_key): error_msg = "non-mean hazard curve key found in mean mode" raise RuntimeError(error_msg) elif curve_mode == 'quantile': if not _is_quantile_hazard_curve_key(hc_key): error_msg = "non-quantile hazard curve key found in "\ "quantile mode" raise RuntimeError(error_msg) elif tokens.quantile_value_from_hazard_curve_key(hc_key) != \ quantile_value: error_msg = "quantile value must be the same for all "\ "hazard curves in an instance file" raise ValueError(error_msg) elif curve_mode == 'realization': if not _is_realization_hazard_curve_key(hc_key): error_msg = "non-realization hazard curve key found in "\ "realization mode" raise RuntimeError(error_msg) elif tokens.realization_value_from_hazard_curve_key( hc_key) != realization_reference_str: error_msg = "realization value must be the same for all "\ "hazard curves in an instance file" raise ValueError(error_msg) hc = kvs.get_value_json_decoded(hc_key) site_obj = shapes.Site(float(hc['site_lon']), float(hc['site_lat'])) # use hazard curve ordinate values (PoE) from KVS # NOTE(fab): At the moment, the IMLs are stored along with the # PoEs in KVS. However, we are using the IML list from config. # The IMLs from KVS are ignored. Note that IMLs from KVS are # in logarithmic form, but the ones from config are not. # The way of storing the HC data in KVS is not very # efficient, we should store the abscissae and ordinates # separately as lists and not make pairs of them curve_poe = [] for curve_pair in hc['curve']: curve_poe.append(float(curve_pair['y'])) hc_attrib = {'investigationTimeSpan': self.params['INVESTIGATION_TIME'], 'IMLValues': iml_list, 'IMT': self.params['INTENSITY_MEASURE_TYPE'], 'PoEValues': curve_poe} hc_attrib.update(hc_attrib_update) hc_data.append((site_obj, hc_attrib)) xmlwriter.serialize(hc_data) return nrml_path
def write_hazardcurve_file(self, curve_keys): """Generate a NRML file with hazard curves for a collection of hazard curves from KVS, identified through their KVS keys. curve_keys is a list of KVS keys of the hazard curves to be serialized. The hazard curve file can be written (1) for a set of hazard curves belonging to the same realization (= endBranchLabel) and a set of sites. (2) for a mean hazard curve at a set of sites (3) for a quantile hazard curve at a set of sites Mixing of these three cases is not allowed, i.e., all hazard curves from the set of curve_keys have to be either for the same realization, mean, or quantile. """ if _is_mean_hazard_curve_key(curve_keys[0]): hc_attrib_update = {'statistics': 'mean'} filename_part = 'mean' curve_mode = 'mean' elif _is_quantile_hazard_curve_key(curve_keys[0]): # get quantile value from KVS key quantile_value = tokens.quantile_value_from_hazard_curve_key( curve_keys[0]) hc_attrib_update = { 'statistics': 'quantile', 'quantileValue': quantile_value } filename_part = "quantile-%.2f" % quantile_value curve_mode = 'quantile' elif _is_realization_hazard_curve_key(curve_keys[0]): realization_reference_str = \ tokens.realization_value_from_hazard_curve_key(curve_keys[0]) hc_attrib_update = {'endBranchLabel': realization_reference_str} filename_part = realization_reference_str curve_mode = 'realization' else: error_msg = "no valid hazard curve type found in KVS key" raise RuntimeError(error_msg) nrml_file = "%s-%s.xml" % (HAZARD_CURVE_FILENAME_PREFIX, filename_part) nrml_path = os.path.join(self['BASE_PATH'], self['OUTPUT_DIR'], nrml_file) iml_list = [ float(param) for param in self.params['INTENSITY_MEASURE_LEVELS'].split(",") ] LOG.debug("Generating NRML hazard curve file for mode %s, "\ "%s hazard curves: %s" % (curve_mode, len(curve_keys), nrml_file)) LOG.debug("IML: %s" % iml_list) xmlwriter = hazard_output.HazardCurveXMLWriter(nrml_path) hc_data = [] for hc_key in curve_keys: if curve_mode == 'mean' and not _is_mean_hazard_curve_key(hc_key): error_msg = "non-mean hazard curve key found in mean mode" raise RuntimeError(error_msg) elif curve_mode == 'quantile': if not _is_quantile_hazard_curve_key(hc_key): error_msg = "non-quantile hazard curve key found in "\ "quantile mode" raise RuntimeError(error_msg) elif tokens.quantile_value_from_hazard_curve_key(hc_key) != \ quantile_value: error_msg = "quantile value must be the same for all "\ "hazard curves in an instance file" raise ValueError(error_msg) elif curve_mode == 'realization': if not _is_realization_hazard_curve_key(hc_key): error_msg = "non-realization hazard curve key found in "\ "realization mode" raise RuntimeError(error_msg) elif tokens.realization_value_from_hazard_curve_key( hc_key) != realization_reference_str: error_msg = "realization value must be the same for all "\ "hazard curves in an instance file" raise ValueError(error_msg) hc = kvs.get_value_json_decoded(hc_key) site_obj = shapes.Site(float(hc['site_lon']), float(hc['site_lat'])) # use hazard curve ordinate values (PoE) from KVS # NOTE(fab): At the moment, the IMLs are stored along with the # PoEs in KVS. However, we are using the IML list from config. # The IMLs from KVS are ignored. Note that IMLs from KVS are # in logarithmic form, but the ones from config are not. # The way of storing the HC data in KVS is not very # efficient, we should store the abscissae and ordinates # separately as lists and not make pairs of them curve_poe = [] for curve_pair in hc['curve']: curve_poe.append(float(curve_pair['y'])) hc_attrib = { 'investigationTimeSpan': self.params['INVESTIGATION_TIME'], 'IMLValues': iml_list, 'IMT': self.params['INTENSITY_MEASURE_TYPE'], 'PoEValues': curve_poe } hc_attrib.update(hc_attrib_update) hc_data.append((site_obj, hc_attrib)) xmlwriter.serialize(hc_data) return nrml_path
def execute(self): results = [] source_model_generator = random.Random() source_model_generator.seed( self.params.get('SOURCE_MODEL_LT_RANDOM_SEED', None)) gmpe_generator = random.Random() gmpe_generator.seed(self.params.get('GMPE_LT_RANDOM_SEED', None)) realizations = int(self.params['NUMBER_OF_LOGIC_TREE_SAMPLES']) # tally and log the total number of sites # TODO (LB): with a large number of sites, this could get expensive # and we might want to change this total_sites = 0 for site_list in self.site_list_generator(): total_sites += len(site_list) LOG.info('Going to run classical PSHA hazard for %s realizations '\ 'and %s sites' % (realizations, total_sites)) for realization in xrange(0, realizations): LOG.info('Calculating hazard curves for realization %s' % realization) pending_tasks = [] results_per_realization = [] self.store_source_model(source_model_generator.getrandbits(32)) self.store_gmpe_map(source_model_generator.getrandbits(32)) for site_list in self.site_list_generator(): pending_tasks.append(tasks.compute_hazard_curve.delay( self.id, site_list, realization)) for task in pending_tasks: task.wait() if task.status != 'SUCCESS': raise Exception(task.result) results_per_realization.extend(task.result) self.write_hazardcurve_file(results_per_realization) results.extend(results_per_realization) del results_per_realization # compute and serialize mean and quantile hazard curves pending_tasks_mean = [] results_mean = [] pending_tasks_quantile = [] results_quantile = [] LOG.info('Computing mean and quantile hazard curves') for site_list in self.site_list_generator(): pending_tasks_quantile.append(tasks.compute_quantile_curves.delay( self.id, site_list)) if self.params['COMPUTE_MEAN_HAZARD_CURVE'].lower() == 'true': pending_tasks_mean.append(tasks.compute_mean_curves.delay( self.id, site_list)) for task in pending_tasks_mean: task.wait() if task.status != 'SUCCESS': raise Exception(task.result) results_mean.extend(task.result) for task in pending_tasks_quantile: task.wait() if task.status != 'SUCCESS': raise Exception(task.result) results_quantile.extend(task.result) if self.params['COMPUTE_MEAN_HAZARD_CURVE'].lower() == 'true': LOG.info('Serializing mean hazard curves') self.write_hazardcurve_file(results_mean) del results_mean # collect hazard curve keys per quantile value quantile_values = {} while len(results_quantile) > 0: quantile_key = results_quantile.pop() curr_qv = tokens.quantile_value_from_hazard_curve_key( quantile_key) if curr_qv not in quantile_values: quantile_values[curr_qv] = [] quantile_values[curr_qv].append(quantile_key) LOG.info('Serializing quantile hazard curves for %s quantile values' \ % len(quantile_values)) for key_list in quantile_values.values(): self.write_hazardcurve_file(key_list) return results