### ===================================================================================================================
### Functions to collect the input folders for reporting
### ===================================================================================================================
# Copyright ©VIIA 2023
### ===================================================================================================================
### 1. Import modules
### ===================================================================================================================
# General imports
from __future__ import annotations
from typing import TYPE_CHECKING, Dict, Union, Optional, Tuple
from pathlib import Path
# References for functions and classes in the viiaPackage
if TYPE_CHECKING:
from viiapackage.viiaStatus import ViiaProject
from viiapackage.viiaSettings import ViiaSettings
from viiapackage.general import viia_get_latest_model_folder
### ===================================================================================================================
### 2. Function to collect folders for reporting and include any user inputs
### ===================================================================================================================
[docs]def viia_collect_folders_reporting(
project: ViiaProject, governing_analysis: str, folder_a7: Optional[Path] = None,
folder_a10: Optional[Path] = None, folders_a12: Optional[Dict[str, Path]] = None,
folder_a13: Optional[Path] = None, folders_a15: Optional[Dict[str, Path]] = None) \
-> Tuple[Dict[str, Path], Optional[Path]]:
"""
This function collects the folders with analyses relevant for the reporting in TVA of the NLTH. It provides options
for the user to check the inputs and overrule if needed. It will load the model of the governing analysis, which is
used for the automated reporting (mesh data, applied strengthening measures, etc.).
.. note:: This function should be run in the report script, there should not be a model loaded prior to this
function. Checks are performed if all required data is found and correct. Please follow VIIA workflow.
Input:
- project (obj): VIIA project object containing collections of fem objects and project variables.
- governing_analysis (str): Governing analysis for NLTH results. For NLTH report the governing analysis can be
selected from 'S1', 'S2', 'S3', 'S4', 'S5', 'S6', 'S7', 'S8', 'S9', 'S10' or 'S11'.
- folder_a7 (Path): Path of the A7 analysis folder where the results of the analysis can be found. Default value
is None, in which case the folder is automatically retrieved based on naming conventions in VIIA.
- folder_a10 (Path): Path of the A10 analysis folder where the results of the analysis can be found. Default
value is None, in which case the folder is automatically retrieved based on naming conventions in VIIA.
- folders_a12 (dict): Dictionary with the paths of the A12 analysis to be used. Default value is None, in which
case the folder is automatically retrieved based on naming conventions in VIIA.
- folder_a13 (Path): Path of the A13 analysis folder where the results of the analysis can be found. Default
value is None, in which case the folder is automatically retrieved based on naming conventions in VIIA. Only
used for objects with strengthening.
- folders_a15 (dict): Dictionary with the paths of the A15 analysis to be used. Default value is None, in which
case the folder is automatically retrieved based on naming conventions in VIIA. Only required for strengthened
objects.
Output:
- Returns tuple of two with first item a dictionary with the result folders to be used for reporting. Second
item is the folder of the governing NLTH folder (the governing signal for A12 or A15 analysis, depending on
the version.
"""
# Function only available for 'NLTH' and 'NLTH-REF' analyses
if project.analysis_type not in ['NLTH', 'NLTH-REF']:
raise NotImplementedError(
f"ERROR: This function should only be used for objects with analysis type 'NLTH' (or 'NLTH-REF'). Current "
f"analysis type is {project.analysis_type}, which is not supported.")
def _collect_analysis_folder(
analysis_name: str, analysis_folder: Optional[Path] = None, signal: Optional[str] = None) -> Optional[Path]:
""" Function to handle inputs for the analysis folder, or retrieve it when required."""
# Check if the analysis folder is provided by user
if isinstance(analysis_folder, str):
analysis_folder = Path(analysis_folder)
if isinstance(analysis_folder, Path):
if analysis_folder.exists():
return analysis_folder
else:
raise FileNotFoundError(
f"ERROR: The provided folder {analysis_folder.as_posix()} for the {analysis_name} analysis could "
f"not be found. Please check your input.")
analysis_folder = project.viia_get_latest_model_folder(
version='highest', folder=Path(project.diana_settings.analysis_settings[analysis_name]['folder_name']),
signal=signal)
return analysis_folder
try:
model_pictures_folder = project.viia_get_latest_model_folder(
folder=project.workfolder_location / project.diana_settings.analysis_settings['MODEL']['folder_name'])
except FileNotFoundError:
model_pictures_folder = None
# Collect the latest appendix pictures folder
project.appendix_pictures_folder = viia_get_latest_model_folder(
project=project, folder=project.workfolder_location / ViiaSettings.DEFAULT_APPENDIX_PICTURES_FOLDER)
# Only appendix pictures folder required for NLTH-REF
if project.analysis_type == 'NLTH-REF':
return {'appendix_pictures': project.appendix_pictures_folder}, None
# Collect the folders for the reporting
reporting_folders = {
'model_pictures': model_pictures_folder,
'appendix_pictures': project.appendix_pictures_folder,
'A7': _collect_analysis_folder(analysis_folder=folder_a7, analysis_name='A7'),
'A10': _collect_analysis_folder(analysis_folder=folder_a10, analysis_name='A10'),
'A12': {},
'A13': None,
'A15': None}
if project.version == 1:
reporting_folders['A12'] = {signal: _collect_analysis_folder(
analysis_folder=folders_a12, analysis_name='A12', signal=signal)
for signal in [f'S{nr}' for nr in range(1, 12)]}
main_results_folder = reporting_folders['A12'][governing_analysis]
else:
reporting_folders['A12'][governing_analysis] = _collect_analysis_folder(
analysis_folder=folders_a12, analysis_name='A12', signal=governing_analysis)
reporting_folders['A13'] = _collect_analysis_folder(
analysis_folder=folder_a13, analysis_name='A13')
reporting_folders['A15'] = {signal: _collect_analysis_folder(
analysis_folder=folders_a15, analysis_name='A15', signal=signal)
for signal in [f'S{nr}' for nr in range(1, 12)]}
main_results_folder = reporting_folders['A15'][governing_analysis]
reporting_folders['A12'] = {key: value for key, value in reporting_folders['A12'].items() if value is not None}
if reporting_folders['A15']:
reporting_folders['A15'] = {key: value for key, value in reporting_folders['A15'].items() if value is not None}
# Check for situations where the strengthening is not modelled (only A12). For example NSCE measures.
if project.version > 1 and not reporting_folders['A15'] and governing_analysis in reporting_folders['A12'] and \
reporting_folders['A12'][governing_analysis].exists():
main_results_folder = reporting_folders['A12'][governing_analysis]
reporting_folders['A12'] = {signal: _collect_analysis_folder(
analysis_folder=folders_a12, analysis_name='A12', signal=signal)
for signal in [f'S{nr}' for nr in range(1, 12)]}
# Check the number of analyses found for NLTH
nlth_signal = 'A12'
if project.version > 1:
nlth_signal = 'A15'
if len(reporting_folders[nlth_signal].keys()) < 7:
project.write_log(
f"WARNING: Only {len(reporting_folders[nlth_signal].keys())} result folders have been found. Reporting "
f"will be performed, but is incomplete!")
elif len(reporting_folders['A12'].keys()) > 7:
signal_folders = [
[signal, int(folder.parent.stem.split('-v')[0])]
for signal, folder in reporting_folders[nlth_signal].items()]
signal_folders = sorted(signal_folders, key=lambda x: (-x[1], x[0]))
signal_folders = [signal[0] for signal in signal_folders]
for signal in signal_folders[7:]:
del reporting_folders[nlth_signal][signal]
project.write_log(
f"WARNING: {len(signal_folders)} result folders {nlth_signal} have been found (signals "
f"{', '.join(sorted(signal_folders, key=lambda x: int(x[1:])))}). The most recent analyses have been "
f"collected, which include signals {', '.join(sorted(signal_folders[:7], key=lambda x: int(x[1:])))}.")
# Notify the user
project.write_log(
f"The following folder locations will be used for reporting the results of the analyses:", without_endline=True)
for k, v in reporting_folders.items():
if isinstance(v, Path):
project.write_log(f" {k}: {v.as_posix()}", without_time=True)
elif v == {} and k == 'A15':
project.write_log(
f" {k}: Analysis {k} will not be used for the reporting. This is probably because the "
f"measures are only NSCE and not required to be assessed in NLTH. If not, please contact the "
f"automation team.", without_time=True)
elif isinstance(v, dict):
for k2, v2 in v.items():
if isinstance(v2, Path):
project.write_log(f" {k} ({k2}): {v2.as_posix()}", without_time=True)
else:
project.write_log(
f" {k} ({k2}): Analysis {k2} will not be used for the reporting.", without_time=True)
else:
project.write_log(f" {k}: Analysis {k} will not be used for the reporting.", without_time=True)
project.write_log("", without_time=True)
# Return the collected folders
return reporting_folders, main_results_folder
### ===================================================================================================================
### 3. Function to check if the provided folders actually exist
### ===================================================================================================================
### ===================================================================================================================
### 3. Function to collect the folders in the required format for the jinja tags in the templates
### ===================================================================================================================
[docs]def viia_collect_result_files_nlth(
version: int, governing_signal: str, result_folders: Dict[str, Union[Path, Dict[str, Path]]]) \
-> Dict[str, Dict[str, Union[str, Path]]]:
"""
Function to collect the data for governing signal and collect the other analyses separately. According to the
jinja-tags used in the templates.
Input:
- version (int): Version number of the object, 1 is existing situation assessment.
- governing_signal (str): Name of the governing signal, for example 'S1'.
- result_folders (dict): Dictionary with the input folders for reporting, provided by the user. The keys are the
different analyses. The value is the path, or in case of the NLTH the signal folders as sub-dictionary.
Output:
- Returns the dictionary of analysis conforming to the structure expected in the templates.
"""
# Depending on the version result folders are selected
analysis = 'A12'
if version > 1:
analysis = 'A15'
# Return dictionary with requested data
return {
'governing_analysis': {
'name': governing_signal,
'folder': result_folders[analysis].get(governing_signal, None)},
'other_analyses': {
signal: {'name': signal, 'latest_folder': folder}
for signal, folder in result_folders[analysis].items() if signal != governing_signal}}
### ===================================================================================================================
### 4. End of script
### ===================================================================================================================