diff --git a/openquake/hazardlib/valid.py b/openquake/hazardlib/valid.py
index 26213da1a91d..a70dd945b47d 100644
--- a/openquake/hazardlib/valid.py
+++ b/openquake/hazardlib/valid.py
@@ -1209,9 +1209,6 @@ def host_port(value=None):
# used for the exposure validation
-cost_type = Choice('structural', 'nonstructural', 'contents',
- 'business_interruption')
-
cost_type_type = Choice('aggregated', 'per_area', 'per_asset')
diff --git a/openquake/qa_tests_data/scenario/case_16/Example_Exposure.xml b/openquake/qa_tests_data/scenario/case_16/Example_Exposure.xml
index 64ba9a291d99..a75976ec26e3 100644
--- a/openquake/qa_tests_data/scenario/case_16/Example_Exposure.xml
+++ b/openquake/qa_tests_data/scenario/case_16/Example_Exposure.xml
@@ -6,8 +6,8 @@
A flexible exposure model
-
+
diff --git a/openquake/risklib/asset.py b/openquake/risklib/asset.py
index 8bf51c87befb..cf036ee51327 100644
--- a/openquake/risklib/asset.py
+++ b/openquake/risklib/asset.py
@@ -103,16 +103,10 @@ class CostCalculator(object):
The same "formula" applies to retrofitting cost.
"""
- def __init__(self, cost_types, area_types, units, tagi={'taxonomy': 0}):
- if set(cost_types) != set(area_types):
- raise ValueError('cost_types has keys %s, area_types has keys %s'
- % (sorted(cost_types), sorted(area_types)))
+ def __init__(self, cost_types, units, tagi={'taxonomy': 0}):
for ct in cost_types.values():
assert ct in ('aggregated', 'per_asset', 'per_area'), ct
- for at in area_types.values():
- assert at in ('aggregated', 'per_asset'), at
self.cost_types = cost_types
- self.area_types = area_types
self.units = units
self.tagi = tagi
@@ -142,7 +136,7 @@ def __call__(self, loss_type, assetcol):
if cost_type == "per_asset":
return cost * number
if cost_type == "per_area":
- area_type = self.area_types[loss_type]
+ area_type = self.cost_types['area']
if area_type == "aggregated":
return cost * area
elif area_type == "per_asset":
@@ -587,14 +581,7 @@ def get_other_fields(fields):
def _get_exposure(fname, stop=None):
- """
- :param fname:
- path of the XML file containing the exposure
- :param stop:
- node at which to stop parsing (or None)
- :returns:
- a pair (Exposure instance, list of asset nodes)
- """
+ # returns (Exposure instance, asset nodes)
[xml] = nrml.read(fname, stop=stop)
if not xml.tag.endswith('exposureModel'):
raise InvalidFile('%s: expected exposureModel, got %s' %
@@ -617,14 +604,6 @@ def _get_exposure(fname, stop=None):
pairs.append((node['input'], noq))
except AttributeError:
pass # no fieldmap
- try:
- area = conversions.area
- except AttributeError:
- # NB: the area type cannot be an empty string because when sending
- # around the CostCalculator object we would run into this numpy bug
- # about pickling dictionaries with empty strings:
- # https://github.com/numpy/numpy/pull/5475
- area = Node('area', dict(type='?'))
try:
occupancy_periods = xml.occupancyPeriods.text.split()
except AttributeError:
@@ -666,14 +645,12 @@ def _get_exposure(fname, stop=None):
cost_types.sort(key=operator.itemgetter(0))
cost_types = numpy.array(cost_types, cost_type_dt)
cc = CostCalculator(
- {}, {}, {}, {name: i for i, name in enumerate(tagnames)})
+ {}, {}, {name: i for i, name in enumerate(tagnames)})
for ct in cost_types:
name = ct['name'] # structural, nonstructural, ...
cc.cost_types[name] = ct['type'] # aggregated, per_asset, per_area
- cc.area_types[name] = area['type']
cc.units[name] = ct['unit']
- exp = Exposure(occupancy_periods, area.attrib, [], cc,
- TagCollection(tagnames), pairs)
+ exp = Exposure(occupancy_periods, [], cc, TagCollection(tagnames), pairs)
assets_text = xml.assets.text.strip()
if assets_text:
# the tag contains a list of file names
@@ -887,18 +864,15 @@ class Exposure(object):
"""
A class to read the exposure from XML/CSV files
"""
- fields = ['occupancy_periods', 'area', 'assets',
+ fields = ['occupancy_periods', 'assets',
'cost_calculator', 'tagcol', 'pairs']
def __toh5__(self):
cc = self.cost_calculator
loss_types = sorted(cc.cost_types)
- dt = numpy.dtype([('cost_type', hdf5.vstr),
- ('area_type', hdf5.vstr),
- ('unit', hdf5.vstr)])
+ dt = numpy.dtype([('cost_type', hdf5.vstr), ('unit', hdf5.vstr)])
array = numpy.zeros(len(loss_types), dt)
array['cost_type'] = [cc.cost_types[lt] for lt in loss_types]
- array['area_type'] = [cc.area_types[lt] for lt in loss_types]
array['unit'] = [cc.units[lt] for lt in loss_types]
attrs = dict(
loss_types=hdf5.array_of_vstr(loss_types),
@@ -910,7 +884,6 @@ def __fromh5__(self, array, attrs):
vars(self).update(attrs)
cc = self.cost_calculator = object.__new__(CostCalculator)
cc.cost_types = dict(zip(self.loss_types, decode(array['cost_type'])))
- cc.area_types = dict(zip(self.loss_types, decode(array['area_type'])))
cc.units = dict(zip(self.loss_types, decode(array['unit'])))
@staticmethod
diff --git a/openquake/risklib/read_nrml.py b/openquake/risklib/read_nrml.py
index 73218a4e9615..e6c3eff04861 100644
--- a/openquake/risklib/read_nrml.py
+++ b/openquake/risklib/read_nrml.py
@@ -352,8 +352,8 @@ def get_fragility_model_04(fmodel, fname):
# ######################## validators ######################## #
-valid_loss_types = valid.Choice('structural', 'nonstructural', 'contents',
- 'business_interruption', 'occupants')
+valid_loss_type = valid.Choice(*[lt for lt in scientific.LOSSTYPE
+ if '+' not in lt and '_ins' not in lt])
def asset_mean_stddev(value, assetRef, mean, stdDev):
@@ -386,9 +386,9 @@ def update_validators():
'vulnerabilityFunction.id': valid.risk_id, # taxonomy
'consequenceFunction.id': valid.risk_id, # taxonomy
'asset.id': valid.asset_id,
- 'costType.name': valid.cost_type,
+ 'costType.name': valid_loss_type,
'costType.type': valid.cost_type_type,
- 'cost.type': valid.cost_type,
+ 'cost.type': valid_loss_type,
'area.type': valid.name,
'isAbsolute': valid.boolean,
'insuranceLimit': valid.positivefloat,
@@ -416,14 +416,14 @@ def update_validators():
'maxIML': valid.positivefloat,
'limitStates': valid.namelist,
'noDamageLimit': valid.NoneOr(valid.positivefloat),
- 'loss_type': valid_loss_types,
+ 'loss_type': valid_loss_type,
'losses': valid.positivefloats,
'averageLoss': valid.positivefloat,
'stdDevLoss': valid.positivefloat,
'ffs.type': valid.ChoiceCI('lognormal'),
'assetLifeExpectancy': valid.positivefloat,
'interestRate': valid.positivefloat,
- 'lossType': valid_loss_types,
+ 'lossType': valid_loss_type,
'aalOrig': valid.positivefloat,
'aalRetr': valid.positivefloat,
'ratio': valid.positivefloat,