Source code for io_operations.io_handler
"""Handle input and output paths."""
import datetime
import logging
from pathlib import Path
__all__ = ["IOHandlerSingleton", "IOHandler"]
class IncompleteIOHandlerInitError(Exception):
"""Exception raised when IOHandler is not initialized."""
[docs]
class IOHandlerSingleton(type):
"""Singleton base class."""
_instances = {}
def __call__(cls, *args, **kwargs):
"""
Ensure a single instance of the IOHandlerSingleton class.
Creates a new instance if it doesn't exist, otherwise returns the existing instance.
"""
if cls not in cls._instances:
cls._instances[cls] = super().__call__(*args, **kwargs)
return cls._instances[cls]
[docs]
class IOHandler(metaclass=IOHandlerSingleton):
"""Handle input and output paths."""
def __init__(self):
"""Initialize IOHandler."""
self._logger = logging.getLogger(__name__)
self._logger.debug("Init IOHandler")
self.output_path = None
self.use_plain_output_path = False
self.data_path = None
self.model_path = None
[docs]
def set_paths(
self, output_path=None, data_path=None, model_path=None, use_plain_output_path=False
):
"""
Set paths for input and output.
Parameters
----------
output_path: str or Path
Path pointing to the output directory.
data_path: str or Path
Path pointing to the data files (e.g., CORSIKA or sim_telarray output).
model_path: str or Path
Path pointing to the model file directory.
use_plain_output_path: bool
Use plain output path without adding tool name and date
"""
self.output_path = output_path
self.use_plain_output_path = use_plain_output_path
self.data_path = data_path
self.model_path = model_path
[docs]
def get_output_directory(self, label=None, sub_dir=None):
"""
Return path to output directory.
Parameters
----------
label: str
Instance label.
sub_dir: str
Name of the subdirectory (ray-tracing, model etc)
Returns
-------
Path
Raises
------
FileNotFoundError
if error creating directory
TypeError
raised for errors while creating directory name
"""
path = Path(self.output_path)
if not self.use_plain_output_path:
path = (
path
if str(self.output_path).endswith("-output")
else path.joinpath("simtools-output")
)
label_dir = label if label is not None else "d-" + str(datetime.date.today())
path = (
path.joinpath(label_dir) if sub_dir is None else path.joinpath(label_dir, sub_dir)
)
try:
path.mkdir(parents=True, exist_ok=True)
except FileNotFoundError:
self._logger.error(f"Error creating directory {path!s}")
raise
return path.absolute()
[docs]
def get_output_file(self, file_name, label=None, sub_dir=None):
"""
Get path of an output file.
Parameters
----------
files_name: str
File name.
label: str
Instance label.
sub_dir: str
Name of the subdirectory (ray-tracing, model etc)
Returns
-------
Path
"""
return (
self.get_output_directory(label=label, sub_dir=sub_dir).joinpath(file_name).absolute()
)