### ===================================================================================================================
### Create Time Domain Data
### ===================================================================================================================
# Copyright ©2025 Haskoning Nederland B.V.
### ===================================================================================================================
### 1. Import modules
### ===================================================================================================================
# General imports
import warnings
import numpy as np
from pathlib import Path
from typing import Union, List, Optional, Tuple
# References for functions and classes in the haskoning_atr_tools package
from haskoning_atr_tools.signal_processing_tool.config import ATRConfigSignalProcessingTool as ATRConfig
from haskoning_atr_tools.signal_processing_tool.utils import read_columns_from_file
from haskoning_atr_tools.signal_processing_tool.time_domain.collection import TimeDomainCollection
from haskoning_atr_tools.signal_processing_tool.time_domain.data import TimeDomainData
### ===================================================================================================================
### 2. Helper-functions
### ===================================================================================================================
def _check_duration(duration: float, method: str) -> None:
""" Function to check the input for the duration."""
if not isinstance(duration, (float, int)):
raise TypeError(f"ERROR: Duration for the {method} time signal must be a float, not {type(duration)}.")
if duration <= 0:
raise ValueError(f"ERROR: Duration for the {method} time signal must be greater than zero.")
def _check_sampling_rate(sampling_rate: int, method: str) -> None:
""" Function to check the input for the sampling rate."""
if not isinstance(sampling_rate, int):
raise TypeError(
f"ERROR: Sampling rate for the {method} time signal must be an integer, not {type(sampling_rate)}.")
if sampling_rate <= 0:
raise ValueError(f"ERROR: Sampling rate for the {method} time signal must be greater than zero.")
### ===================================================================================================================
### 3. Functions to create signals
### ===================================================================================================================
[docs]
def create_sinusoidal_time_signal(
harmonic_amplitudes: Union[List[float], float], harmonic_frequencies: Union[List[float], float],
harmonic_phase_shift: Optional[Union[List[float], float]] = None, duration: float = ATRConfig.DURATION,
sampling_rate: Union[int, float] = ATRConfig.SAMPLING_RATE) -> Tuple[List[float], List[float]]:
"""
Create a time signal by adding several sinusoidal waves with specific frequencies, amplitudes, and phase shifts.
Input:
- harmonic_amplitudes (list of float): Amplitudes of the harmonics. Alternative input can be a single amplitude
as float.
- harmonic_frequencies (list of float): Frequencies of the harmonics. Alternative input can be a single
frequency as float.
- harmonic_phase_shift (list of float): Optional input for phase shifts of the harmonics in degrees. If not
provided, all phase shifts are 0. Alternative input can be a single phase_shift as float.
- duration (float): Duration of the signal, in [s]. Default value is 10 seconds.
- sampling_rate (float, int): Sampling rate, in [Hz]. Default value is a sampling rate of 100 Hz.
Output:
- Returns a tuple containing the generated signal as list of floats and the corresponding time steps as list of
floats, in [s].
"""
# Check inputs
_check_duration(duration=duration, method='sinusoidal')
_check_sampling_rate(sampling_rate=sampling_rate, method='sinusoidal')
# Ensure inputs are lists
if isinstance(harmonic_amplitudes, float):
harmonic_amplitudes = [harmonic_amplitudes]
if isinstance(harmonic_frequencies, float):
harmonic_frequencies = [harmonic_frequencies]
if not harmonic_phase_shift:
harmonic_phase_shift = np.zeros(len(harmonic_amplitudes)).tolist()
elif isinstance(harmonic_phase_shift, float):
harmonic_phase_shift = [harmonic_phase_shift]
# Check length of input lists
if not (len(harmonic_amplitudes) == len(harmonic_frequencies) == len(harmonic_phase_shift)):
warnings.warn(
f"WARNING: Input lists for the sinusoidal time signal do not have the same length. Only the first "
f"{min(len(harmonic_amplitudes), len(harmonic_frequencies), len(harmonic_phase_shift))} values will be "
f"used.")
# Convert phase shift from degrees to radians
harmonic_phase_shift = [np.deg2rad(phase) for phase in harmonic_phase_shift]
# Create the time steps for the signal
time_stamps = np.linspace(0, duration, int(sampling_rate * duration) + 1)
signal = np.zeros_like(time_stamps)
# Add each harmonic
for amplitude, frequency, phase_shift in zip(harmonic_amplitudes, harmonic_frequencies, harmonic_phase_shift):
signal += amplitude * np.sin(2 * np.pi * frequency * time_stamps + phase_shift)
return signal.tolist(), time_stamps.tolist()
[docs]
def create_special_time_signal(
signal_type: str, duration: float = ATRConfig.DURATION, event_time: float = 0.0, amplitude: float = 1.0,
sampling_rate: Union[int, float] = ATRConfig.SAMPLING_RATE) -> Tuple[List[float], List[float]]:
"""
Create a special time signal of a specified type. This function generates a time signal based on the specified type,
duration, event time, amplitude, and sampling rate. The supported signal types are 'heaviside', 'kronecker', and
'dirac'.
Input:
- signal_type (str): The type of signal to generate. Valid types are 'heaviside', 'kronecker', and 'dirac'.
- duration (float): The total duration of the signal, in [s]. Default value is 10 seconds.
- event_time (float): The event time is representing the time, in [s] at which the signal event occurs. It’s
used to position the signal (step, impulse, or discrete spike) within the total duration of the signal.
Default value is 0, placing the event at the start of the signal.
- amplitude (float): The amplitude of the signal. Default value is 1.0. Amplitude is not used for the dirac
method.
- sampling_rate (float, int): Sampling rate, in [Hz]. Default value is a sampling rate of 100 Hz.
Output:
- Returns a tuple containing the generated signal as list of floats and the corresponding time steps as list of
floats, in [s].
Raises:
- ValueError: If the signal type is not valid or if the event time is outside the duration.
Example:
In this example a time signal is created with the heaviside method.
.. code-block:: python
signal, time_stamps = create_special_time_signal('heaviside', 1.0, 0.5, amplitude=2.0, sampling_rate=100)
"""
# Define valid signal types
valid_signal_types = ['heaviside', 'kronecker', 'dirac']
# Check if the signal type is valid
if signal_type.lower() not in valid_signal_types:
raise ValueError(f"ERROR: Invalid signal type for creating time signal. Valid types are: {valid_signal_types}.")
signal_type = signal_type.lower()
# Check inputs
_check_duration(duration=duration, method=signal_type.capitalize())
_check_sampling_rate(sampling_rate=sampling_rate, method=signal_type.capitalize())
# Check if the moment is within the time duration
if event_time < 0 or event_time > duration:
raise ValueError(f"ERROR: The event_time for the {signal_type} time signal must be within the time duration.")
# Create time steps
time_stamps = np.linspace(0, duration, int(sampling_rate * duration))
# Initialise the signal
signal = np.zeros_like(time_stamps)
# Generate the signal based on the type
if signal_type.lower() == 'heaviside':
signal = amplitude * np.heaviside(time_stamps - event_time, 1)
elif signal_type.lower() == 'kronecker':
index = int(event_time * sampling_rate)
if index < len(signal):
signal[index] = amplitude
elif signal_type.lower() == 'dirac':
index = int(event_time * sampling_rate)
if index < len(signal):
signal[index] = 1 / (sampling_rate * duration)
return signal.tolist(), time_stamps.tolist()
[docs]
def create_ricker_wavelet(
duration: float, sampling_rate: int, center_frequency: float, centered: bool = False) \
-> Tuple[List[float], List[float]]:
"""
Create a Ricker wavelet for a given duration, sampling rate, and center frequency.
Input:
- duration (float): Duration of the wavelet, in [s].
- sampling_rate (int): Sampling rate, in [-].
- center_frequency (float): Center frequency of the wavelet, in [Hz].
- centered (bool): Select to center the time steps around zero. Default value False.
Output:
- Returns a tuple containing the generated signal as list of floats and the corresponding time steps as list of
floats, in [s].
"""
# Check inputs
_check_duration(duration=duration, method='Ricker wavelet')
_check_sampling_rate(sampling_rate=sampling_rate, method='Ricker wavelet')
if center_frequency <= 0:
raise ValueError("ERROR: Center frequency for the Ricker wavelet time signal must be greater than zero.")
# Create centered time steps
time_stamps = np.linspace(-duration / 2, duration / 2, int(sampling_rate * duration))
# Calculate the Ricker wavelet
t = time_stamps * center_frequency
wavelet = (1 - 2 * (np.pi * t) ** 2) * np.exp(-(np.pi * t) ** 2)
# Shift time to start at 0 if centering is not required
if not centered:
time_stamps = np.linspace(0, duration, int(sampling_rate * duration))
return wavelet.tolist(), time_stamps.tolist()
### ===================================================================================================================
### 4. Functions to create time domain data
### ===================================================================================================================
[docs]
def create_time_domain_data(
project, name: str, amplitude_type: str, amplitudes: List[float], time_stamps: List[float],
amplitude_units: str = 'Unknown units', time_stamps_units: str = 'Unknown units',
collection_name: str = 'Unknown Collection') -> TimeDomainData:
"""
Creates a new time domain data object and adds it to the specified collection in the project.
Input:
- project (obj): Project object containing collections of objects and project variables.
- name (str): The name of the new time domain data.
- amplitude_type (str): The type of the time domain data. For example: 'velocity', 'acceleration', or
'pressure'. Default value is None.
- amplitudes (list of float): A list of amplitude values for the time domain data.
- time_stamps (list of float): A list of time stamps corresponding to the amplitude values.
- amplitude_units (str): The units of the amplitude values. Default value is 'Unknown units'.
- time_stamps_units (str): The units of the time stamps. Defaults value is 'Unknown units'.
- collection_name (str): The name of the collection to which this data will be added. Defaults to 'Unknown
Collection'.
Output:
- Returns the newly created time domain data object.
"""
# Ensure amplitudes and time_stamps are lists
if isinstance(amplitudes, np.ndarray):
amplitudes = amplitudes.tolist()
if isinstance(time_stamps, np.ndarray):
time_stamps = time_stamps.tolist()
# Retrieve the collection from the project
collection = project.time_domain_collections.get(collection_name)
if not collection:
# If the collection does not exist, create a new one
collection = create_time_domain_collection(project=project, name=collection_name, time_domain_data_list=[])
project.time_domain_collections[collection_name] = collection
# Create the new TimeDomainData object with the collection as its parent
new_time_domain_data = TimeDomainData(
name=name, amplitude_type=amplitude_type, amplitudes=amplitudes, time_stamps=time_stamps,
amplitude_units=amplitude_units, time_stamps_units=time_stamps_units, parent=collection)
return new_time_domain_data
[docs]
def create_sinusoidal_time_domain_data(
project, harmonic_amplitudes: Union[float, List[float]], harmonic_frequencies: Union[float, List[float]],
harmonic_phase_shift: Optional[Union[float, List[float]]] = None, duration: float = ATRConfig.DURATION,
sampling_rate: Union[int, float] = ATRConfig.SAMPLING_RATE, name: str = 'Sinusoidal signal',
collection_name: str = 'Unknown Collection', amplitude_type: str = None, amplitude_units: str = 'Unknown units',
time_stamps_units: str = 'Unknown units') -> TimeDomainData:
"""
Creates a time domain data object with sinusoidal amplitudes.
Input:
- project (obj): Project object containing collections of objects and project variables.
- harmonic_amplitudes (list of float): Amplitudes of the harmonics. Alternative input can be a single amplitude
as float.
- harmonic_frequencies (list of float): Frequencies of the harmonics. Alternative input can be a single
frequency as float.
- harmonic_phase_shift (list of float): Optional input for phase shifts of the harmonics in degrees. If not
provided, all phase shifts are 0. Alternative input can be a single phase_shift as float.
- duration (float): Duration of the signal, in [s]. Default value is 10 seconds.
- sampling_rate (float, int): Sampling rate, in [Hz]. Default value is a sampling rate of 100 Hz.
- name (str): The name of the new time domain data. Default value is 'Sinusoidal signal'.
- collection_name (str): The name of the collection to which this data will be added. Defaults to 'Unknown
Collection'.
- amplitude_type (str): The type of the time domain data. For example: 'velocity', 'acceleration', or
'pressure'. Default value is None.
- amplitude_units (str): The units of the amplitude values. Default value is 'Unknown units'.
- time_stamps_units (str): The units of the time stamps. Defaults to 'Unknown units'.
Output:
- Returns the newly created time domain data object based on the inputs for sinusoidal signal.
- TimeDomainData is added to the specified TimeDomainCollection in the project.
"""
# Generate the sinusoidal signal and time steps
signal, time_steps = create_sinusoidal_time_signal(
harmonic_amplitudes=harmonic_amplitudes, harmonic_frequencies=harmonic_frequencies,
harmonic_phase_shift=harmonic_phase_shift, duration=duration, sampling_rate=sampling_rate)
# Create the TimeDomainData object with the sinusoidal signal
return create_time_domain_data(
project=project, name=name, amplitude_type=amplitude_type, amplitudes=signal, time_stamps=time_steps,
amplitude_units=amplitude_units, time_stamps_units=time_stamps_units, collection_name=collection_name)
[docs]
def create_special_time_domain_data(
project, signal_type: str, duration: float = ATRConfig.DURATION, event_time: float = 0.0,
amplitude: float = 1.0, sampling_rate: Union[int, float] = ATRConfig.SAMPLING_RATE, name: Optional[str] = None,
collection_name: str = 'Unknown Collection', amplitude_type: str = None, amplitude_units: str = 'Unknown units',
time_stamps_units: str = 'Unknown units') -> TimeDomainData:
"""
Creates a new time domain data object with special signal and adds it to the specified collection in the project.
Input:
- project (obj): Project object containing collections of objects and project variables.
- signal_type (str): The type of signal to generate. Valid types are 'heaviside', 'kronecker', and 'dirac'.
- duration (float): The total duration of the signal, in [s]. Default value is 10 seconds.
- event_time (float): The event time is representing the time, in [s] at which the signal event occurs. It’s
used to position the signal (step, impulse, or discrete spike) within the total duration of the signal.
Default value is 0, placing the event at the start of the signal.
- amplitude (float): The amplitude of the signal. Default value is 1.0. Amplitude is not used for the dirac
method.
- sampling_rate (float, int): Sampling rate, in [Hz]. Default value is a sampling rate of 100 Hz.
- name (str): The name of the new time domain data. Default value 'Special signal' with additional information
from inputs.
- collection_name (str): The name of the collection to which this data will be added. Defaults to 'Unknown
Collection'.
- amplitude_type (str): The type of the time domain data. For example: 'velocity', 'acceleration', or
'pressure'. Default value is None.
- amplitude_units (str): The units of the amplitude values. Default value is 'Unknown units'.
- time_stamps_units (str): The units of the time stamps. Defaults to 'Unknown units'.
Output:
- Returns the newly created time domain data object based on the inputs for special signal.
- TimeDomainData is added to the specified TimeDomainCollection in the project.
"""
# Generate the special signal and time steps
signal, time_steps = create_special_time_signal(
signal_type=signal_type, duration=duration, event_time=event_time, amplitude=amplitude,
sampling_rate=sampling_rate)
# Set default name if not provided
if not name:
name = f"Special signal {signal_type} at {event_time}s"
# Create the TimeDomainData object with the special signal
return create_time_domain_data(
project=project, name=name, amplitude_type=amplitude_type, amplitudes=signal, time_stamps=time_steps,
amplitude_units=amplitude_units, time_stamps_units=time_stamps_units, collection_name=collection_name)
[docs]
def create_ricker_wavelet_time_domain_data(
project, center_frequency: float, centered: bool = False, duration: float = ATRConfig.DURATION,
sampling_rate: Union[int, float] = ATRConfig.SAMPLING_RATE, name: Optional[str] = None,
collection_name: str = 'Unknown Collection', amplitude_type: str = None, amplitude_units: str = 'Unknown units',
time_stamps_units: str = 'Unknown units') -> TimeDomainData:
"""
Creates a time domain data object with Ricker wavelet signal.
Input:
- project (obj): Project object containing collections of objects and project variables.
- center_frequency (float): Center frequency of the wavelet, in [Hz].
- centered (bool): Select to center the time steps around zero. Default value False.
- duration (float): The total duration of the signal, in [s]. Default value is 10 seconds.
- sampling_rate (float, int): Sampling rate, in [Hz]. Default value is a sampling rate of 100 Hz.
- name (str): The name of the new time domain data. Default value 'Ricker wavelet with xHz center frequency'.
- collection_name (str): The name of the collection to which this data will be added. Defaults to 'Unknown
Collection'.
- amplitude_type (str): The type of the time domain data. For example: 'velocity', 'acceleration', or
'pressure'. Default value is None.
- amplitude_units (str): The units of the amplitude values. Default value is 'Unknown units'.
- time_stamps_units (str): The units of the time stamps. Defaults to 'Unknown units'.
Output:
- Returns the newly created time domain data object based on the inputs for Ricker wavelet signal.
- TimeDomainData is added to the specified TimeDomainCollection in the project.
"""
# Generate the Ricker wavelet signal and time steps
wavelet, time_steps = create_ricker_wavelet(duration=duration, sampling_rate=sampling_rate,
center_frequency=center_frequency, centered=centered)
# Set default name if not provided
if not name:
name = f"Ricker wavelet with {center_frequency}Hz center frequency"
# Create the TimeDomainData object with the Ricker wavelet signal
return create_time_domain_data(
project=project, name=name, amplitude_type=amplitude_type, amplitudes=wavelet, time_stamps=time_steps,
amplitude_units=amplitude_units, time_stamps_units=time_stamps_units, collection_name=collection_name)
[docs]
def create_time_domain_data_from_file(
project, file: Union[str, Path], time_column: Union[str, int], amplitude_column: Union[str, int],
name: Optional[str] = None, amplitude_type: str = None, amplitude_units: str = 'Unknown units',
time_stamps_units: str = 'Unknown units', skip_rows: int = 0, header: bool = True, delimiter: str = ',',
collection_name: str = 'Unknown Collection') -> TimeDomainData:
"""
Creates a time domain data object from file (csv-file or xlsx-file).
Input:
- project (obj): Project object containing collections of objects and project variables.
- file (Path or str): The file path to the data file.
- time_column (str or int): The name or index of the column containing time stamps.
- amplitude_column (str or int): The name or index of the column containing amplitude values.
- name (str): The name of the new time domain data. Default value is the name of the file.
- amplitude_type (str): The type of the time domain data. For example: 'velocity', 'acceleration', or
'pressure'. Default value is None.
- amplitude_units (str): The units of the amplitude values. Default value is 'Unknown units'.
- time_stamps_units (str): The units of the time stamps. Defaults to 'Unknown units'.
- skip_rows (int): Optional input for the number of rows to skip at the beginning of the file. Defaults to 0.
- header (bool): Select whether the file contains a header row. Defaults to True.
- delimiter (str): The delimiter used in the csv-file. Default is ','.
- collection_name (str): The name of the collection to which this data will be added. Defaults to 'Unknown
Collection'.
Output:
- Returns the newly created time domain data object based on the imported signal.
- TimeDomainData is added to the specified TimeDomainCollection in the project.
"""
# Check file
if isinstance(file, str):
file = Path(file)
if not file.exists():
raise FileNotFoundError(
f"ERROR: The signal can't be imported, because the file was not found: {file.as_posix()}.")
# Determine the name
if name == 'use header' and header:
try:
# If amplitude_column is a string, use it directly as the name
if isinstance(amplitude_column, str):
name = amplitude_column
else:
# Read the header row to find the name
amplitude_column_data = read_columns_from_file(
file=file, skip_rows=skip_rows, columns=[amplitude_column])
name = amplitude_column_data[0][0]
except Exception as e:
raise Exception(f"ERROR: An error occurred while reading the file: {e}")
elif not name:
# Default to the file name if no name is provided
name = file.stem
# Adjust skip_rows if header is True
if header:
skip_rows += 1
# Read the data from the file
time_stamps, amplitudes = read_columns_from_file(
file=file, skip_rows=skip_rows, columns=[time_column, amplitude_column], delimiter=delimiter)
# Use create_time_domain_data to create the TimeDomainData object
time_domain_data = create_time_domain_data(
project=project, name=name, amplitude_type=amplitude_type, amplitudes=amplitudes, time_stamps=time_stamps,
amplitude_units=amplitude_units, time_stamps_units=time_stamps_units, collection_name=collection_name)
return time_domain_data
[docs]
def create_time_domain_data_from_sigicom_csv(
project, file: Union[str, Path], name: Optional[str] = None, amplitude_type: str = None,
amplitude_units: str = 'Unknown units', time_stamps_units: str = 'Unknown units',
collection_name: str = 'Unknown Collection') -> TimeDomainData:
"""
Creates a time domain data object from a Sigicom csv-file.
Input:
- project (obj): Project object containing collections of objects and project variables.
- file (Path or str): The file path to the Sigicom csv-file.
- name (str): The name of the new time domain data. Default value is the name of the Sigicom csv-file.
- amplitude_type (str): The type of the time domain data. For example: 'velocity', 'acceleration', or
'pressure'. Default value is None.
- amplitude_units (str): The units of the amplitude values. Default value is 'Unknown units'.
- time_stamps_units (str): The units of the time stamps. Defaults to 'Unknown units'.
- collection_name (str): The name of the collection to which this data will be added. Defaults to 'Unknown
Collection'.
Output:
- Returns the newly created time domain data object based on the imported signal.
- TimeDomainData is added to the specified TimeDomainCollection in the project.
"""
return create_time_domain_data_from_file(
project=project, file=file, time_column='Timestamp', amplitude_column='Value', name=name,
amplitude_type=amplitude_type, amplitude_units=amplitude_units, time_stamps_units=time_stamps_units,
collection_name=collection_name, skip_rows=3, header=False, delimiter=',')
### ===================================================================================================================
### 5. Function to create time domain collection
### ===================================================================================================================
[docs]
def create_time_domain_collection(
project, name: str, time_domain_data_list: List[TimeDomainData]) -> TimeDomainCollection:
"""
Creates a new time domain collection and adds it to the project.
Input:
- name (str): The name of the new time domain collection.
- time_domain_data_list (list of obj): A list of time domain data objects to include in the collection.
Output:
- Returns the newly created time domain collection.
- The collection is added to the time domain collections in project.
"""
collection = TimeDomainCollection(name=name, parent=project)
for time_domain_data in time_domain_data_list:
collection.add_time_domain_data_to_collection(time_domain_data)
return project.add(collection)
### ===================================================================================================================
### 6. Functions to create multiple time domain data in collection
### ===================================================================================================================
[docs]
def create_time_domain_collection_from_file(
project, collection_name: str, info_list: List[list]) -> TimeDomainCollection:
"""
Creates a time domain collection with multiple time domain data objects from cvs- or xlsx-files.
Input:
- project (obj): Project object containing collections of objects and project variables.
- collection_name (str): The name of the collection to which the signals will be added.
- info_list (list of list): A list of lists, each containing the arguments for creating a TimeDomainData object
from a file. The sublist should be in the order of the arguments for create_time_domain_data_from_file, such
as: [file, time_column, amplitude_column, name, amplitude_type, amplitude_units, time_stamps_units, skip_rows,
header]. Only file, time_column, and amplitude_column are mandatory; the other arguments are not required.
Output:
- Returns the newly created time domain collection object.
- TimeDomainData objects are created based on the imported signal from the csv- or xlsx-file.
- The TimeDomainData objects are added to the TimeDomainCollection.
"""
# Initialise an empty collection
collection = TimeDomainCollection(name=collection_name, parent=project)
# Iterate over the info_list and create TimeDomainData objects
for info in info_list:
try:
# Unpack the arguments and call create_time_domain_data_from_file
create_time_domain_data_from_file(project, *info, collection_name=collection_name)
except Exception as e:
warnings.warn(f"ERROR: Failed to create TimeDomainData from info: {info}. Error: {e}")
return collection
[docs]
def create_time_domain_collection_from_sigicom_csv(
project, collection_name: str, info_list: List[list]) -> TimeDomainCollection:
"""
Creates a time domain collection with multiple time domain data objects from Sigicom csv-files.
Input:
- project (obj): Project object containing collections of objects and project variables.
- collection_name (str): The name of the collection to which the signals will be added.
- info_list (list of list): A list of lists, each containing the arguments for creating a TimeDomainData object
from a Sigicom csv-file. The sublist should be in the order of the arguments for
create_time_domain_data_from_sigicom_csv, such as: [file, name, amplitude_type, amplitude_units,
time_stamps_units]. Only file is mandatory the other arguments are not required.
Output:
- Returns the newly created time domain collection object.
- TimeDomainData objects are created based on the imported signal from the Sigicom csv-file.
- The TimeDomainData objects are added to the TimeDomainCollection.
"""
# Initialise an empty collection
collection = TimeDomainCollection(name=collection_name, parent=project)
# Iterate over the info_list and create TimeDomainData objects
for info in info_list:
try:
# Unpack the arguments and call create_time_domain_data_from_sigicom_csv
create_time_domain_data_from_sigicom_csv(project, *info, collection_name=collection_name)
except Exception as e:
warnings.warn(f"ERROR: Failed to create TimeDomainData from info: {info}. Error: {e}")
return collection
### ===================================================================================================================
### 7. End of script
### ===================================================================================================================