Skip to content

Commit

Permalink
Merge remote-tracking branch 'simcenter/master' into 2024_11_UQ_rv_pa…
Browse files Browse the repository at this point in the history
…rams
  • Loading branch information
ioannis-vm committed Dec 6, 2024
2 parents 3a4ad37 + 5d7e9af commit 1c8b297
Show file tree
Hide file tree
Showing 5 changed files with 34 additions and 12 deletions.
14 changes: 9 additions & 5 deletions pelicun/auto.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@

from __future__ import annotations

import copy
import importlib
import sys
from pathlib import Path
Expand Down Expand Up @@ -98,8 +99,11 @@ def auto_populate(
asset information under 'GeneralInformation'.
"""
# create a copy of config to avoid editing the original
config_autopopulated = copy.deepcopy(config)

# try to get the AIM attributes
aim = config.get('GeneralInformation')
aim = config_autopopulated.get('GeneralInformation')
if aim is None:
msg = 'No Asset Information provided for the auto-population routine.'
raise ValueError(msg)
Expand All @@ -122,11 +126,11 @@ def auto_populate(
auto_populate_ext = auto_script.auto_populate

# generate the DL input data
aim_ap, dl_ap, comp = auto_populate_ext(aim=config)
aim_ap, dl_ap, comp = auto_populate_ext(aim=config_autopopulated)

# assemble the extended config
config['GeneralInformation'].update(aim_ap)
config.update({'DL': dl_ap})
config_autopopulated['GeneralInformation'].update(aim_ap)
config_autopopulated.update({'DL': dl_ap})

# return the extended config data and the component quantities
return config, comp
return config_autopopulated, comp
2 changes: 1 addition & 1 deletion pelicun/model/damage_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -1362,7 +1362,7 @@ def parse_scaling_specification(scaling_specification: dict) -> dict: # noqa: C
"""
# if there are contents, ensure they are valid.
# See docstring for an example of what is expected.
parsed_scaling_specification: dict = defaultdict(dict)
parsed_scaling_specification: defaultdict = defaultdict(dict)
# validate contents
for key, value in scaling_specification.items():
# loop through limit states
Expand Down
2 changes: 1 addition & 1 deletion pelicun/resources/auto/Hazus_Earthquake_IM.py
Original file line number Diff line number Diff line change
Expand Up @@ -1031,7 +1031,7 @@ def auto_populate(aim): # noqa: C901
f'Water Distribution network element type {wdn_element_type} '
f'is not supported in Hazus Earthquake IM DL method'
)
dl_ap = None
dl_ap = 'N/A'
comp = None

else:
Expand Down
1 change: 1 addition & 0 deletions pelicun/tests/basic/test_damage_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -593,6 +593,7 @@ def test__create_dmg_RVs(self, assessment_instance: Assessment) -> None:
sample = rv.sample
assert uniform_sample is not None
assert sample is not None

for i in range(len(operation_list)):
if rv_name == 'FRG-cmp.A-1-2-3-1-1':
theta = 1.20 * 30.0
Expand Down
27 changes: 22 additions & 5 deletions pelicun/tools/DL_calculation.py
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@ def convert_df_to_dict(data: pd.DataFrame | pd.Series, axis: int = 1) -> dict:
return out_dict


def run_pelicun(
def run_pelicun( # noqa: C901
config_path: str,
demand_file: str,
output_path: str | None,
Expand Down Expand Up @@ -320,6 +320,12 @@ def run_pelicun(
detailed_results=detailed_results,
)

# An undefined config means that we do not need to run a simulation
# Such config is not an error, those are caught during parsing. This is the
# result of an intentional no-simulation request during auto-population.
if config is None:
return

# List to keep track of the generated output files.
out_files: list[str] = []

Expand Down Expand Up @@ -379,9 +385,8 @@ def run_pelicun(
),
custom_model_dir=custom_model_dir,
scaling_specification=get(config, 'DL/Damage/ScalingSpecification'),
is_for_water_network_assessment=is_specified(
config, 'DL/Asset/ComponentDatabase/Water'
),
is_for_water_network_assessment='Water'
in get(config, 'DL/Asset/ComponentDatabase', ''),
)

if is_unspecified(config, 'DL/Losses/Repair'):
Expand Down Expand Up @@ -572,7 +577,7 @@ def _parse_config_file( # noqa: C901
*,
coupled_edp: bool,
detailed_results: bool,
) -> dict[str, object]:
) -> dict[str, object] | None:
"""
Parse and validate the config file for Pelicun.
Expand Down Expand Up @@ -652,6 +657,14 @@ def _parse_config_file( # noqa: C901
)
raise PelicunInvalidConfigError(msg)

if get(config_ap, 'DL') == 'N/A':
msg = (
'N/A `DL` entry in config file interpreted as a request to '
'skip damage and loss simulation for this asset.'
)
log_msg(msg)
return None

# look for possibly specified assessment options
try:
assessment_options = config['Applications']['DL']['ApplicationData'][
Expand Down Expand Up @@ -708,6 +721,10 @@ def _parse_config_file( # noqa: C901
regional_out_config['Settings']
)

# if no loss simulation is requested, remove the corresponding outputs
if is_unspecified(config_ap, 'DL/Losses'):
update(config_ap, 'DL/Outputs/Loss', {})

# save the extended config to a file
config_ap_path = Path(config_path.stem + '_ap.json').resolve()

Expand Down

0 comments on commit 1c8b297

Please sign in to comment.