Source code for viiapackage.reporting.helper_functions.viia_collect_input_folders

### ===================================================================================================================
###   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 ### ===================================================================================================================
[docs]def viia_check_input_folders(input_folders: Dict[str, Union[Path, Dict[str, Path]]]) -> Dict[str, Path]: """ This function checks the input folders by the user for reporting functionality. Input: - input_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 dictionary with the same structure, only the non-existing folders have been set to None. """ collected_folders = {} analyses = ['A7', 'A10', 'A12', 'A13', 'A15'] for analysis in analyses: collected_folders[analysis] = None if analysis in input_folders and input_folders[analysis] is not None: if isinstance(input_folders[analysis], Path) and input_folders[analysis].exists(): collected_folders[analysis] = input_folders[analysis] elif isinstance(input_folders[analysis], dict): collected_folders[analysis] = { signal: folder for signal, folder in input_folders[analysis].items() if folder is not None and isinstance(folder, Path) and folder.exists()} return collected_folders
### =================================================================================================================== ### 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 ### ===================================================================================================================