Source code for haskoning_atr_tools.vibration_contour_plot.target.target_functions

### ===================================================================================================================
###  Functionality for the targets in the vibration simulation
### ===================================================================================================================
# Copyright ©2026 Haskoning Nederland B.V.

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

# General imports
from warnings import warn
from pathlib import Path
from typing import List, Optional, Union, Literal, Dict

# References for functions and classes in the haskoning_atr_tools package
from haskoning_atr_tools.vibration_contour_plot.helper_functions import load_data_from_file
from haskoning_atr_tools.vibration_contour_plot.target.target import Target, TargetVibrationLimits


### ===================================================================================================================
###  2. Function to create Target instances from file
### ===================================================================================================================

[docs] def create_targets_from_file( project, file_path: Union[Path, str], sheet_name: Union[str, int] = 0, column_mapping: Optional[dict[str, str]] = None) -> List[Target]: """ Function to create targets from file for vibration analysis. Input: - project (obj): Project object containing collections of objects and project variables. - file_path (Path or str): Path to file containing the target data for vibration analysis. The file can be provided as Excel-file or csv-file. In case of Excel, the sheet name should be provided for the worksheet with the target data. In both cases the header should be provided in row 1. When providing a column 'Calculate' the user can specify to use the target or not (overrules other filters). If column is not present, all targets will be loaded, depending on other filters applied. - sheet_name (str or int): Sheet name or index of sheet with the target data. Default value is 0, selecting the first sheet in the Excel file. Input is ignored for csv-files. - column_mapping (dict): Optional input to specify other column headers for the input of the file. This might be convenient if the data is provided with other column names. Default value is None, the default names are used for loading the targets from the file. Output: - The targets are created and added to the project, based on the provided filters. - Returns list of instances of Target class created in the function. """ # Read file and handle the user options df, column_mapping, _ = load_data_from_file( file_path=file_path, sheet_name=sheet_name, column_mapping=column_mapping, default_column_mapping={ 'id': 'ID', 'x': 'X coordinate [m]', 'y': 'Y coordinate [m]', 'z': 'Z coordinate [m]', 'category': 'Category', 'type': 'Type', 'name': 'Name'}, default_optional_column_mapping={ 'calculate': 'Calculate'}) # Loop through rows with equipment data targets_from_file = [] for i, row in df.iterrows(): # Check optional inputs if 'calculate' in column_mapping: if not row[column_mapping['calculate']]: continue # Check the ID as unique identifier for the Target target_identifier = row[column_mapping['id']] if target_identifier in [t.id for t in project.target_list]: raise ValueError(f"ERROR: Please provide unique ID for the target. Duplicate ID: {target_identifier}.") # Create the instance of the equipment, validation executed in class target = Target( id=target_identifier, category=row[column_mapping['category']], type=str(row[column_mapping['type']]), coordinates=(row[column_mapping['x']], row[column_mapping['y']], row[column_mapping['z']]), name=str(row[column_mapping['name']])) if target.name == 'nan': target.name = None target.project = project project.target_list.append(target) targets_from_file.append(target) return targets_from_file
### =================================================================================================================== ### 3. Function to load vibration limits from file and add to targets ### ===================================================================================================================
[docs] def load_target_limits_from_file( project, file_path: Union[Path, str], limit_type: Literal['velocity'] = 'velocity', sheet_name: Union[str, int] = 0, column_mapping: Optional[dict[str, str]] = None) -> Dict[str, List[Target]]: """ Function to add the vibration limits from file to the targets for the vibration assessment. Input: - project (obj): Project object containing collections of objects and project variables. - file_path (Path or str): Path to file containing the vibration limit data for vibration analysis. The file can be provided as Excel-file or csv-file. In case of Excel, the sheet name should be provided for the worksheet with the vibration limit data. In both cases the header should be provided in row 1. The remaining columns in the file will be checked for match with the type specified for the target. In case of a match the data is loaded. - limit_type (str): Select the type of limits provided. Currently, only 'velocity' can be selected. Default value is velocity. - sheet_name (str or int): Sheet name or index of sheet with the vibration limit data. Default value is 0, selecting the first sheet in the Excel file. Input is ignored for csv-files. - column_mapping (dict): Optional input to specify other column headers for the input of the file. This might be convenient if the data is provided with other column names. Default value is None, the default names are used for loading the vibration limits from the file. Output: - The vibration limits are added to the targets with the corresponding type. - Returns dictionary of target types with the target instances. """ # Read file and handle the user options df, column_mapping, _ = load_data_from_file( file_path=file_path, sheet_name=sheet_name, column_mapping=column_mapping, default_column_mapping={'frequency': 'Frequency [Hz]'}) type_names = df.columns.tolist() type_names.remove(column_mapping['frequency']) frequencies = df[column_mapping['frequency']].tolist() loaded_limits = {} for target in project.target_list: if target.type is None: continue if sum([target.type in type_name for type_name in type_names]) > 1: raise ValueError( f"ERROR: The target '{target.name}' (id={target.id}) matches multiple types in the vibration " f"limits file. Please check type names for unique matches.") for type_name in type_names: if target.type in type_name: limits = df[type_name].tolist() if not target.limits: target.limits = dict() if limit_type in target.limits: warn(f"WARNING: The target '{target.name}' (id={target.id}) already has a vibration limit defined, " f"the values are overwritten. Please check if this is correct.") target.limits[limit_type] = TargetVibrationLimits( limit_type=limit_type, frequencies=frequencies, limits=limits) if type_name not in loaded_limits: loaded_limits[type_name] = [] loaded_limits[type_name].append(target) return loaded_limits
### =================================================================================================================== ### 4. End of script ### ===================================================================================================================