### ===================================================================================================================
### 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
### ===================================================================================================================