Configuration and simulation-file formats#

simtools resolves simulation models and physical run settings before writing a simulation program’s configuration. Configuration writers translate these values into native files. Result readers translate native output into the quantities used by simtools. These two selections are independent.

The supplied writers support CORSIKA7, sim_telarray, and the LightEmission programs ff-1m and xyzls. The supplied eventio reader supports current CORSIKA IACT and sim_telarray files. Supporting another format requires changing the corresponding built-in implementation.

Shared file suffixes, generated defaults, fixed filenames, and lifecycle labels belong in resources/file_types.yml and are schema-validated when loaded. Add an entry when a product is shared by multiple producers or consumers; keep parameterized native names, directory placement, and cleanup rules with their owning workflow.

Shared run settings#

SimulationParameters holds run number, particle identity, pointing in degrees, shower counts, event counts including shower reuse, viewcone, and calibration mode. Telescope simulations supplied with a shower file obtain these values from its reader. They do not need a CORSIKA configuration object.

Model objects retain model parameters and table access. SimtelModelWriter keeps native table conversions and configuration-writing state separately. Writing additional site or calibration parameters does not change the telescope model’s parameter dictionary.

Add a configuration writer#

  1. Put the native configuration syntax and table conversions in a module for the simulation software. Accept resolved models rather than fetching model parameters again.

  2. Implement write_config_file(additional_models=None, label=None) for individual models, and export_config_files() for an array. Return the written configuration path from write_config_file.

  3. Select a supported writer with get_model_writer(model, simulation_software=software_name).write_config_file() or array_model.export_config_files(simulation_software=software_name).

  4. Test native syntax, unit conversions, and preservation of model parameters. Add an API reference entry and a real-file integration example when the format is supported.

Shower configuration uses CORSIKA7. Calibration light uses the LightEmission writer selected by light_source_software in the light-source configuration. Its writer implements make_command(iact_output). Source position, pointing, wavelength, intensity, and event numbering remain in the simulation setup; native LightEmission options and pulse/angular-distribution tables belong to its writer.

Add a result reader#

  1. Put native parsing and unit/coordinate conversions in simtools.sim_events.formats. Use EventioReader as the current example.

  2. Implement the EventReader protocol methods in simtools.sim_events.formats.readers, described below.

  3. Select the supported format using simulation_file_format in an application configuration, or file_format in EventDataWriter and Simulator.write_reduced_event_lists. The default is eventio; file suffixes do not select a reader.

  4. Test small generated inputs with known energies, directions, reuse positions, and telescope identifiers. Check the reduced tables and metadata against these values. Real simulation-file compatibility belongs in integration tests.

Expose supported reader modules in the API reference. Unknown selections raise ValueError.

Reader methods and quantities#

  • read_run_number() returns the run number, or None when absent.

  • count_events() returns shower and event counts, counting shower reuse as separate events where available.

  • iter_records(file_id) yields (table_name, row_dictionary) pairs for SHOWERS, TRIGGERS, and FILE_INFO. Supply the complete fields defined in TableSchemas, with scalar values in its units: energy in TeV, distances in metres, and angles in degrees. The reduced tables currently use CORSIKA7 particle identifiers; convert other native identifiers at the reader boundary. Preserve shower/event identifiers and use the supplied file_id.

  • Supply one FILE_INFO row per file and all simulated shower reuse positions, including events without an array trigger. Trigger rows contain comma-separated native telescope IDs and common simtools telescope IDs.

  • read_metadata() returns the per-file provenance dictionary after reading: native run information, source filename and identifiers, and any available telescope metadata. Supply simulation_software as a software-name string when the source differs from sim_telarray. Keep native header dictionaries here, outside the common event rows.

  • For a shower file supplied to telescope simulation, read_simulation_parameters() returns the arguments for SimulationParameters, excluding run_number, run_mode, and use_curved_atmosphere. It also supplies observation_levels in metres for comparison with the site model. Convert pointing to geographic azimuth and zenith in degrees.

A new reader does not have to manufacture eventio headers. The existing file_info native-header convenience functions serve current CORSIKA/eventio callers; new workflows should use the physical settings and event records.

EventDataWriter creates typed tables, validates records, and writes bounded chunks independently of native parsing. Format readers must keep their own buffers bounded; EventioReader retains at most one shower’s reuse positions. The HDF5 product and its units remain the same when an input reader changes.