Source code for simtel.simulator_array

"""Simulation runner for array simulations."""

import logging

from simtools.io_operations import io_handler
from simtools.runners.simtel_runner import InvalidOutputFileError, SimtelRunner

__all__ = ["SimulatorArray"]


[docs] class SimulatorArray(SimtelRunner): """ SimulatorArray is the interface with sim_telarray to perform array simulations. Parameters ---------- corsika_config_data: CorsikaConfig CORSIKA configuration. simtel_path: str or Path Location of source of the sim_telarray/CORSIKA package. label: str Instance label. use_multipipe: bool Use multipipe to run CORSIKA and sim_telarray. """ def __init__( self, corsika_config, simtel_path, label=None, use_multipipe=False, sim_telarray_seeds=None, ): """Initialize SimulatorArray.""" self._logger = logging.getLogger(__name__) self._logger.debug("Init SimulatorArray") super().__init__( label=label, simtel_path=simtel_path, corsika_config=corsika_config, use_multipipe=use_multipipe, ) self.sim_telarray_seeds = sim_telarray_seeds self.corsika_config = corsika_config self.io_handler = io_handler.IOHandler() self._log_file = None def _make_run_command(self, run_number=None, input_file=None): """ Build and return the command to run simtel_array. Parameters ---------- input_file: str Full path of the input CORSIKA file run_number: int (optional) run number Returns ------- str Command to run sim_telarray. """ self._log_file = self.get_file_name(file_type="log", run_number=run_number) histogram_file = self.get_file_name(file_type="histogram", run_number=run_number) output_file = self.get_file_name(file_type="output", run_number=run_number) # Array command = str(self._simtel_path.joinpath("sim_telarray/bin/sim_telarray")) command += f" -c {self.corsika_config.array_model.get_config_file()}" command += f" -I{self.corsika_config.array_model.get_config_directory()}" command += super().get_config_option("telescope_theta", self.corsika_config.zenith_angle) command += super().get_config_option("telescope_phi", self.corsika_config.azimuth_angle) command += super().get_config_option( "power_law", SimulatorArray.get_power_law_for_sim_telarray_histograms( self.corsika_config.primary_particle ), ) command += super().get_config_option("histogram_file", histogram_file) command += super().get_config_option("output_file", output_file) command += super().get_config_option("random_state", "none") if self.sim_telarray_seeds: command += super().get_config_option("random_seed", self.sim_telarray_seeds) command += super().get_config_option("show", "all") command += f" {input_file}" command += f" > {self._log_file} 2>&1 || exit" return command def _check_run_result(self, run_number=None): """ Check if simtel output file exists. Parameters ---------- run_number: int Run number. Returns ------- bool True if simtel output file exists. Raises ------ InvalidOutputFileError If simtel output file does not exist. """ output_file = self.get_file_name(file_type="output", run_number=run_number) if not output_file.exists(): msg = f"sim_telarray output file {output_file} does not exist." self._logger.error(msg) raise InvalidOutputFileError(msg) self._logger.debug(f"simtel_array output file {output_file} exists.") return True
[docs] @staticmethod def get_power_law_for_sim_telarray_histograms(primary): """ Get the power law index for sim_telarray. Events will be histogrammed in sim_telarray with a weight according to the difference between this exponent and the one used for the shower simulations. Parameters ---------- primary: str Primary particle. Returns ------- float Power law index. """ power_laws = { "gamma": 2.5, "electron": 3.3, } if primary.name in power_laws: return power_laws[primary.name] return 2.68