Source code for viiapackage.reporting.helper_functions.viia_templating_data

### ===================================================================================================================
###   FUNCTION: Collect the data for the template of the engineering report
### ===================================================================================================================
# Copyright ©VIIA 2024

### ===================================================================================================================
###   1. Import modules
### ===================================================================================================================

# General imports
from __future__ import annotations
from typing import TYPE_CHECKING, Dict, Any, Optional, List
from pathlib import Path
from warnings import warn
from json import load

# References for functions and classes in the viiaPackage
if TYPE_CHECKING:
    from viiapackage.viiaStatus import ViiaProject
from viiapackage.database import myviia_get_measures_objectpart, myviia_get_object_deel
from viiapackage.viiaLoads import _get_viia_importance_factor
from viiapackage.reference_approach import viia_get_ref_info_from_myviia
from viiapackage.strengthening import viia_collect_strengthening_measures, viia_check_measures, GMCMeasures
from viiapackage.reporting.helper_functions.get_connection_info import get_connection_info
from viiapackage.reporting.helper_functions.get_element_numbers import get_element_numbers
from viiapackage.reporting.helper_functions.get_foundation_info import get_foundation_info
from viiapackage.reporting.helper_functions.get_components_info import get_components_info
from viiapackage.reporting.helper_functions.get_inspection_data import get_inspection_data
from viiapackage.reporting.helper_functions.get_beoordeling_data import get_beoordeling_data
from viiapackage.reporting.helper_functions.get_wall_displacements_data import viia_get_wall_displacements_data
from viiapackage.reporting.helper_functions.get_a1_info_from_myviia import viia_get_a1_info_from_myviia
from viiapackage.reporting.helper_functions.get_acceptance_criteria import viia_get_acceptance_criteria
from viiapackage.reporting.helper_functions.get_l2_measure_data import get_l2_measure_data
from viiapackage.reporting.helper_functions.viia_collect_input_folders import viia_check_input_folders, \
    viia_collect_result_files_nlth
from viiapackage.reporting.helper_functions.viia_get_general_info import viia_get_general_info
from viiapackage.reporting.helper_functions.viia_get_gutter_height import viia_get_gutter_height
from viiapackage.reporting.helper_functions.viia_get_psse_nsce_plots import viia_get_psse_nsce_plots
from viiapackage.reporting.helper_functions.viia_get_ontwerpnotitie_report_data import get_ontwerpnotitie_report_data
from viiapackage.reporting.helper_functions.viia_get_uo_report_data import get_uo_report_data
from viiapackage.reporting.helper_functions.viia_get_bevindingen_report_data import get_bevindingen_report_data


### ===================================================================================================================
###   2. Function to collect the data for the report template
### ===================================================================================================================

[docs]def viia_templating_data( project: ViiaProject, report_type: str, tender_specification: str, governing_analysis: str = None, input_folders: Dict[str, Path] = None, extra_object_parts: Optional[List[str]] = None) -> Dict[str, Any]: """ This function collects data for the templates. Input: - project (obj): VIIA project object containing collections of fem objects and project variables. - report_type (str): Report type, for example 'opname', 'opnameplan' or 'engineering', etc. Refer to the viia_create_report function for allowed report-types. - tender_specification (str): Tender specification (NL: vraagspecificatie) that relates to the required template version . For example '2021_09082021'. - governing_analysis (str): Governing analysis for NLTH/NLPO results. For NLTH, choosing from 'S1', 'S2', 'S3', 'S4', 'S5', 'S6', 'S7', 'S8', 'S9', 'S10' or 'S11'. For NLPO choosing from 'X_pos_uni', 'X_pos_modal', 'X_neg_uni', 'X_neg_modal', 'Y_pos_uni', 'Y_pos_modal', 'Y_neg_uni' or 'Y_neg_modal'. - input_folders (dict): Dictionary with the folders where the results of the analyses should be collected from. Default value None. Input is only required for the engineering report of NLTH assessment. - extra_object_parts (list of str): List of names of extra object parts to include in the report. Default value is None, only required when the uo report is created with this function. Output: - Returns dictionary with all data to be passed to the jinja tags in the template. """ # Set language if report_type in ['engineering']: language = 'en' else: language = 'nl' # Initialise the dict with general information (data from MYVIIA) report_data = viia_get_general_info(project=project, language=language) # Inspection info if report_type == 'opname': report_data.update(**get_inspection_data(project=project)) return report_data # Beoordeling info if report_type == 'beoordeling': report_data.update(**get_beoordeling_data(project=project)) return report_data # Ontwerpnotitie report if report_type == 'ontwerpnotitie': report_data.update(**get_ontwerpnotitie_report_data(project=project, extra_object_parts=extra_object_parts)) return report_data # UO report if report_type == 'uo': report_data.update(**get_uo_report_data(project=project, extra_object_parts=extra_object_parts)) return report_data # Bevindingen report if report_type == 'bevindingen': report_data.update(**get_bevindingen_report_data(project=project, extra_object_parts=extra_object_parts)) return report_data # Other reports if report_type != 'engineering': return report_data # Add importance factor and design pga importance_factor = _get_viia_importance_factor(project=project) report_data.update({'importance_factor': importance_factor}) design_PGA = round(importance_factor * project.project_information['pga'], 4) report_data.update({'design_PGA': design_PGA}) # Data for appendix C4 if not project.project_information['geotechnical_analysis'] == 'Required': # Consequence class if 'CC1' in project.project_information['gevolgklasse'] or \ 'CC2' in project.project_information['gevolgklasse']: report_data.update({'CC_bool': 'Yes'}) else: report_data.update({'CC_bool': 'No'}) # Gutter height gutter_height = viia_get_gutter_height(project=project) if gutter_height: if gutter_height <= 6: gutter_height_bool = 'Yes' else: gutter_height_bool = 'No' else: gutter_height = '_' gutter_height_bool = 'Yes' report_data.update({'gutter_height': gutter_height, 'gutter_height_bool': gutter_height_bool}) # Building type if report_data['gebouwtype'] == '': report_data['gebouwtype'] = \ 'Building type not given in MYVIIA. Please specify yourself. Examples: Farm, ' \ 'Front house of farm, Barn, Regular residence etc. ' # Damages inspection_info = None damages = None inspection_type = project.project_information.get('inspection_subtype', None) objectpart_id = project.get_myviia_object_deel_id() if inspection_type is None and project.project_information.get('objectdeel', None) != 'Gehele object': for object_part in project.project_information['objectdelen']: if object_part['naam'] == 'Gehele object': if object_part['opnamemethodiek_id']: inspection_type = object_part['opnamemethodiek_id']['subtype'] objectpart_id = object_part['id'] break # Get the details of the object-part related to the inspection object_part_details = myviia_get_object_deel(object_deel_id=objectpart_id, token=project.token) # Regular inspection if inspection_type in ['VAL-P', 'VAL']: if object_part_details and object_part_details['object_deel_opname_val']: # Check if any of the answers in regular inspection for the questions on damages is yes if 'Ja' in [ object_part_details['object_deel_opname_val']['vraag_10_1'], object_part_details['object_deel_opname_val']['vraag_10_2'], object_part_details['object_deel_opname_val']['vraag_10_3']]: damages = True else: damages = False # Validation checklist inspection elif inspection_type == 'VAL-C': if object_part_details and object_part_details['object_deel_opname_val2']: # Check if any of the answers in validation checklist inspection for the question on damages is yes if 'Ja' in [ object_part_details['object_deel_opname_val2']['vraag_1_17']]: damages = True else: damages = False # Typology inspection elif inspection_type in ['TYPO', 'TYPO-3']: if object_part_details and object_part_details['object_deel_opname']: # Check if any of the answers in typology checklist inspection for the question on damages is yes if 'Ja' in [ object_part_details['object_deel_opname']['vraag_b_2_1'], object_part_details['object_deel_opname']['vraag_b_2_2'], object_part_details['object_deel_opname']['vraag_b_2_3'], object_part_details['object_deel_opname']['vraag_b_2_4']]: damages = True else: damages = False if damages is None: report_data['damages'] = \ 'No damage observed / Some damage observed but these have no significant impact on the integrity of ' \ 'the structural system.' report_data['damages_bool'] = 'Yes' elif not damages: report_data['damages'] = 'No damage observed' report_data['damages_bool'] = 'Yes' else: report_data['damages'] = \ 'Damages observed in the object. Refer to the inspection report. (Some damage observed but these ' \ 'have no significant impact on the integrity of the structural system).' report_data['damages_bool'] = 'No' # Foundation type report_data['pile_foundation'] = False if inspection_type in ['VAL-P', 'VAL'] and object_part_details and \ object_part_details['object_deel_opname_val'] and \ object_part_details['object_deel_opname_val']['vraag_8_1'] in ['Paalfundering', 'Gemengde fundering']: report_data['pile_foundation'] = True # Generic criteria sets if design_PGA < 0.16: report_data['generic_criteria_sets'] = 'Set 1' else: report_data['generic_criteria_sets'] = 'Sets 1 and 2' # Tender specification report_data.update(vraagspecificatie=tender_specification) report_data['praktijkaanpak'] = False if tender_specification in ['PA_2.0_V1']: report_data['praktijkaanpak'] = True # Set analysis type options analysis_type = f'OPTIE_{project.analysis_type}' report_data.update(**{analysis_type: True}) # Governing analysis if project.analysis_type == 'NLTH': report_data.update(governing_analysis=f'Signal {governing_analysis}') else: report_data.update(governing_analysis=None) # Check version if project.analysis_type in ['NLTH']: if project.version < 2: if (project.workfolder_location / project.diana_settings.analysis_settings['A15']['folder_name']).exists(): warn( f"WARNING: A15 folder exists but the version number is higher as 1. If strengthening measures are " f"modelled the version number should be increased. Provided version number is {project.version}.") # Collect the measures for the report measures = GMCMeasures().get_strengthening_measures(project=project) measures_myviia = [] if 'test-' == project.name[:5] and project.name != 'test-report_nlth': # Required for testing for _key in measures.keys(): measures_myviia.append({'name': _key}) else: # Collect the measures from MYVIIA measures_myviia = myviia_get_measures_objectpart( object_deel_id=project.get_myviia_object_deel_id(), token=project.token)['object_deel_measures'] for measure in measures_myviia: measure_name = measure['name'].split("-")[0] + "-" + measure['name'].split("-")[1] if measure_name in measures: if language == 'en': measure['description'] = measures[measure_name]['description_en'] elif language == 'nl': measure['description'] = measures[measure_name]['description_nl'] else: raise ValueError(f"ERROR: Language not recognised. Provided was {language}.") else: project.write_log( f"WARNING: Measure {measure_name} not present in the GMC. Present in the GMC are " f"{list(measures.keys())}.") measure['description'] = '' if measures_myviia: if project.version == 1 and project.analysis_type in ['NLTH']: pass # raise ValueError( # "ERROR: There are measures in MYVIIA but the version number is set to 1. When there are " # "measure the version should be higher than 1.") report_data.update({'strengthening_myviia': measures_myviia}) # Start collecting data required for the NLTH if project.analysis_type != 'NLTH': if project.analysis_type != 'NLTH-REF': raise NotImplementedError(f"ERROR: The {project.analysis_type} is not implemented for reporting.") report_data.update({'ref_objects': viia_get_ref_info_from_myviia(project=project)}) report_data.update({'compliant': True}) if measures_myviia: report_data.update({'compliant': False}) return report_data # Collect FEM number of elements report_data.update(**get_element_numbers(project=project)) # Collect data for reporting on foundation type report_data.update(**get_foundation_info(project=project)) report_data.update(fos=project.shallow_foundation_present()) report_data.update(pile=project.pile_foundation_present()) # Structural components if project.collections.shapes: components = {'components': get_components_info(project=project)} report_data.update(**components) else: report_data.update(components={}) # Collect data for reporting connections report_data.update(**get_connection_info(project=project)) # Adding information about number of elements for various building components # These values will be used to update jinja tags (like {{ count.fstrips }}) in Appendix C3_v7_0 report_data['count'] = dict() report_data['count'].update({ 'fstrips': len(project.collections.fstrips), 'fwalls': len([wall for wall in project.collections.walls if 'F-WANDEN' in wall.name]), 'floors': len(project.collections.floors), 'walls': len([wall for wall in project.collections.walls if 'F-WANDEN' not in wall.name]), 'columns': len(project.collections.columns), 'beams': len(project.collections.beams) + len(project.collections.lintels), 'roofs': len(project.collections.roofs), 'linemasses': len(project.collections.line_masses)}) # Verify if measures in MYVIIA are the same in model and add to template data report_data.update({'compliant': True}) object_measures = viia_collect_strengthening_measures(project=project) if object_measures: if project.version == 1: raise ValueError( "ERROR: There are measures in the model but the version number is set to 1. When there are " "measure the version should be higher than 1.") # Collect the acceptance criteria report_data.update({ 'acceptance_criteria_for_floors': viia_get_acceptance_criteria(project=project, shape_type='floors')}) report_data.update({ 'acceptance_criteria_for_roofs': viia_get_acceptance_criteria(project=project, shape_type='roofs')}) # Check for differences viia_check_measures(project=project, object_measures=object_measures, myviia_measures=measures_myviia) report_data.update({'Strengthening': object_measures}) if measures_myviia: report_data.update({'compliant': False}) else: report_data.update({'compliant': True}) # Collect the data from A1 analysis from MYVIIA (weight of the building) report_data.update(**viia_get_a1_info_from_myviia(project=project, language=language)) # Collect the result folders with the results from the analyses result_folders = viia_check_input_folders(input_folders) report_data['results'] = {} # Collect the Eigenfrequency analysis report_data['results']['eigen'] = result_folders['A7'] # Collect the NLTH analyses report_data['results'].update(**viia_collect_result_files_nlth( version=project.version, governing_signal=governing_analysis, result_folders=result_folders)) # Collect the PSSE-NSCE plots if input_folders['appendix_pictures'] is not None: report_data.update(**viia_get_psse_nsce_plots( project=project, appendix_pictures_folder=input_folders['appendix_pictures'])) # Collect data from the eigenfrequency analysis add_eigenfrequency_results = False eigen_json_file = None if isinstance(result_folders['A7'], Path): eigen_json_file = result_folders['A7'] / 'Eigen.json' if eigen_json_file.exists(): add_eigenfrequency_results = True # No data found for eigenfrequencies if not add_eigenfrequency_results: if not isinstance(result_folders['A7'], Path): project.write_log( f"WARNING: The folder for the eigenfrequency analysis was not provided. Results for the eigenfrequency " f"analysis are not added to the report.") else: project.write_log( f"WARNING: The json-file with the eigenmodes could not be found. Expecting file: " f"'{eigen_json_file.as_posix()}'. Results for the eigenfrequency analysis are not added to the " f"report.") report_data.update(first_dom_mode_x_mass_par='UNKNOWN') report_data.update(second_dom_mode_x_mass_par='UNKNOWN') report_data.update(first_dom_mode_y_mass_par='UNKNOWN') report_data.update(second_dom_mode_y_mass_par='UNKNOWN') report_data.update(first_dom_mode_z_mass_par='UNKNOWN') # Handle results from json-file with eigenmodes else: with open(eigen_json_file) as fp: eigen_data = load(fp) # Check contents of json-file if any([f'modal_{x}' not in eigen_data['Eigen'] for x in ['x', 'y', 'z']]): missing = ', '.join([f'modal_{x}' for x in ['x', 'y', 'z'] if f'modal_{x}' not in eigen_data['Eigen']]) project.write_log( "WARNING: The json-file with the eigenmodes did not contain all required information. Missing " f"items: {missing}. Probably it is generated with an older version of the viiaPackage. Please " f"perform the result handling of A7 in the current package.") # Required data is present else: # Sorting the lists sorted_modal_x = sorted(eigen_data['Eigen']['modal_x'], reverse=True) sorted_modal_y = sorted(eigen_data['Eigen']['modal_y'], reverse=True) if len(eigen_data['Eigen']['modal_z']) > 10: sorted_modal_z = sorted(eigen_data['Eigen']['modal_z'][:10], reverse=True) else: sorted_modal_z = sorted(eigen_data['Eigen']['modal_z'], reverse=True) # Adding data to report_data dictionary report_data.update(first_dom_mode_x_mass_par=format(sorted_modal_x[0], '.2f')) report_data.update(second_dom_mode_x_mass_par=format(sorted_modal_x[1], '.2f')) report_data.update(first_dom_mode_y_mass_par=format(sorted_modal_y[0], '.2f')) report_data.update(second_dom_mode_y_mass_par=format(sorted_modal_y[1], '.2f')) report_data.update(first_dom_mode_z_mass_par=format(sorted_modal_z[0], '.2f')) # Get wall displacements data report_data['results']['governing_analysis'].update(**viia_get_wall_displacements_data( project=project, result_folder=report_data['results']['governing_analysis']['folder'])) l2_measure_data = get_l2_measure_data(project=project) if l2_measure_data: report_data['results']['governing_analysis'].update(**{'l2_measure_data': l2_measure_data}) return report_data
### =================================================================================================================== ### 3. End of script ### ===================================================================================================================