remage package¶
Subpackages¶
Submodules¶
remage.cli module¶
- remage.cli._cleanup_tmp_files(ipc_info, extra_tmp_files)¶
Remove temporary files created by the C++ application, that might not have been cleaned up.
- remage.cli._run_remage_cpp(args=None, is_cli=False, num_procs=0)¶
run the remage-cpp executable and return the exit code as seen in bash.
- remage.cli.remage_run(macros=(), *, gdml_files=(), output=None, threads=1, procs=1, overwrite_output=False, merge_output_files=False, flat_output=False, time_window=None, macro_substitutions=None, log_level=None, raise_on_error=True, raise_on_warning=False)¶
Run the remage simulation utility with the provided args.
This is the main entry point for users wanting to run remage from Python code.
- Parameters:
macros (Sequence[str] | str) – one or more remage/Geant4 macro command listings to execute.
gdml_files (Sequence[str | Path | g4.Registry] | str | Path | g4.Registry) – supply one or more GDML files describing the experimental geometry.
output (str | Path | None) – output file for detector hits.
threads (int) – set the number of threads used by remage. This cannot be combined with procs.
procs (int) – set the number of processes used by remage. This cannot be combined with threads.
overwrite_output (bool) – overwrite existing output files.
merge_output_files (bool) – merge output files created by individual remage threads.
flat_output (bool) – if
False, perform a reshaping of the output files so that each row in the output table contains data about all steps in a physical interaction in a detector, based on the time-window. This results in each column being aVectorOfVectors. IfTrue, the output table will be flat with each row holding information about a single Geant4 step.time_window (float | None) – time window to group together steps into hits, in microseconds.
macro_substitutions (Mapping[str, str] | None) – key-value-pairs that will be substituted in macros as Geant4 aliases.
log_level (str | None) – logging level. One of debug_event, debug, detail, summary, warning, error, fatal, nothing.
raise_on_error (bool) – raise a
RuntimeErrorwhen an error in the C++ application occurs. This applies to non-fatal errors being logged as well as fatal errors. If false, the function only returns the error code, the Python-based post-processing will be skipped in any case.raise_on_warning (bool) – raise a
RuntimeErrorwhen a warning (or error) is logged in the C++ application. If false, warnings are only logged and the python-based post-processing will be run normally.
- Return type:
- remage.cli.remage_run_from_args(args=None, *, raise_on_error=True, raise_on_warning=False, extra_tmp_files=())¶
Run the remage simulation utility with the provided args.
- remage.cli.watchdog_thread_fn(proc)¶
In multiprocess mode, ensures failure from one child process propagates to the others.
Important
This function runs in a dedicated thread in
remage.cli._run_remage_cpp()and should not be called directly by the user.
remage.find_remage module¶
- remage.find_remage.find_remage_cpp()¶
Find the remage executable to wrap.
It uses (in order of precedence) the following methods: - the REMAGE_CPP_PATH environment variable pointing to the remage-cpp executable, - the config stored into the package at build-time, or - the system PATH.
- Return type:
remage.ipc module¶
IPC message receiver implementation for remage-cpp.
Note
The C++ IPC sender implementation can be found in RMGIpc.
Binary message format¶
Messages are encoded as UTF-8 strings; transmitting binary (non-string) data with this IPC mechanism is not possible.
Message parts are separated using ASCII control characters. Each message ends with
GS (group separator, 0x1D) which may be optionally preceded by ENQ (enquiry,
0x05) to indicate that the C++ process expects an acknowledgement with a POSIX signal
before continuing.
Records within a message are delimited by RS (record separator, 0x1E). Each
message must contain at least three records. The first is the process index, for
typical (non-multiprocessing) uses, this is always 0. The second is treated as
the message’s key, whereas the second one is the associated value:
proc_id |
key |
|
value |
[ |
|
More values can follow afterwards, again delimited by RS.
Each record may contain multiple units split by US (unit separator, 0x1F). Records
with more then one unit are returned as tuples on the python side.
Example: A message
proc_id |
key |
|
value0 |
|
value1 |
|
value2 |
[ |
|
would be decoded to ["value0", ("value1", "value2")].
Blocking messages¶
Blocking messages need to be acknowledged by sending ASCII ACK over the second pipe
(per-process file descriptor) to the remage-cpp process, after performing the
associated action (example: checking version equality of python and C++ IPC sides,
pre-processing files).
Transmitting additional response data with the acknowledgement is not possible.
- class remage.ipc.IpcResult(ipc_info)¶
Bases:
objectStorage structure for the IPC messages returned by
remage-cpp.- get(name: str, expected_len: Literal[1] = 1) list[str]¶
- get(name: str, expected_len: int) list[list[str]]
Return all messages of a given key
namefrom the IPC message list.- Parameters:
expected_len – only return messages that have the expected number of records. Other messages are silently skipped.
- get_as_dict(name)¶
Same as
get()but return a dictionary keyed by record key.Operates on two-record messages: the first record is used as the key and the second as a value appended to that key’s list.
- get_single(name, default=None)¶
Return the single single value for the key
nameordefaultif not present.Note
if more then one value for the key had been submitted, this function will throw.
- remage.ipc.handle_ipc_message(msg, proc)¶
Parse a already UTF-8 decoded IPC message from
remage-cpp.This function should directly handle all known blocking IPC messages, which will not be returned for subsequent processing.
- Parameters:
- Returns:
(is_blocking, parsed_message, is_fatal)whereis_blockingisTruewhen the sender waits for a reply,parsed_messageis the decoded message orNoneif it was consumed internally, andis_fatalsignals that the application should terminate.proc_numis the index of the subprocess.- Return type:
- remage.ipc.ipc_thread_fn(pipe_r, pipes_o_w, proc, unhandled_ipc_messages)¶
Read and handle IPC messages coming from
remage-cpp.Important
This function runs in a dedicated thread in
remage.cli._run_remage_cpp()and should not be called directly by the user. The parameterunhandled_ipc_messagesacts as a return value, as thread functions cannot directly return.The function reads from the pipe file descriptor
pipe_rand dispatches each complete IPC message tohandle_ipc_message()for parsing and handling of the associated action. Any message parts will be decoded as UTF-8 before parsing.Blocking messages are acknowledged by sending ASCII ACK over the second pipe (per-process file descriptor).
- Parameters:
- Return type:
None
remage.logging module¶
- remage.logging.set_logging_level(logger, rmg_log_level)¶
remage.post_proc module¶
- remage.post_proc.copy_links(original_file, output_files, lh5_links_group_name)¶
- remage.post_proc.deduplicate_table(file, table_name, unique_col, to_struct)¶
- remage.post_proc.make_tmp(files)¶
Hide files.
Prepend a . to their name and rename them on disk.
- remage.post_proc.post_proc(ipc_info, flat_output, merge_output_files, time_window_in_us)¶
- remage.post_proc.tmp_renamed_files(remage_files)¶
Temporarily rename files, restoring originals on error and deleting temps on success.
- remage.post_proc.un_make_tmp(files)¶
Un-hide files.
Remove . from name and rename on disk.
remage.reshaping module¶
- remage.reshaping._calorimeter_hit_table(stps)¶
Build a flat hit table from an already per-hit detector table.
Calorimeter-like output accumulates exactly one hit per event. It must not be step-grouped; we only rename the
timecolumn tot0for the TCM.
- remage.reshaping._get_wo_mode(first_write, chunk_idx, new_file, overwrite)¶
LH5 write mode for a detector table chunk.
For the first chunk of the first detector in a new hit file we (over)write the whole file; for the first chunk of a further detector we append a new column to the parent struct; otherwise we append rows to the existing table.
- remage.reshaping._get_wo_mode_forwarded(written_tables, new_file, overwrite)¶
LH5 write mode for a table that is copied through unchanged.
- remage.reshaping._group_by_time(obj, *, window_us)¶
Group steps into hits by
evtidand a coincidence time window.A new hit starts whenever
evtidchanges, ortimejumps by more thanwindow_usmicroseconds within the same evtid. Returns anlgdo.TableofVectorOfVectors, one per field ofobj, preserving each field’sunitsparameter.timeis assumed to be in nanoseconds (the unit remage writes).
- remage.reshaping._iter_chunks(stp_file, table, buffer)¶
Yield
buffer-sized row chunks oftable.Used for flat hit tables (e.g. calorimeter) where every row is an independent hit, so no evtid alignment is needed and the table can be streamed in fixed-size blocks to bound memory.
- remage.reshaping._iter_event_aligned_chunks(stp_file, table, buffer)¶
Yield
buffer-sized chunks oftablealigned to evtid boundaries.All steps of a given evtid stay in the same chunk, so each chunk can be grouped into hits independently. The full evtid column is read once up front to compute the split points.
This relies on remage writing evtids monotonically increasing.
- remage.reshaping._move_units_to_flattened_data(data)¶
Recursively move a
unitsattr from a VectorOfVectors to its flattened_data.- Parameters:
data (LGDO)
- Return type:
None
- remage.reshaping._write_lh5(hit_table, file, out_field, out_detector, wo_mode)¶
Write a hit table at
out_field/out_detector.On the first write the table is wrapped in a Struct so the parent group is created with the right type; subsequent appends target the table directly.
- remage.reshaping.reshape_output(stp_files, hit_files, *, reshape_tables, forward_tables, out_field, time_window_in_us, flat_hit_tables=(), overwrite=False, buffer=5000000)¶
Post-process remage step files into reshaped hit files.
For each detector listed in
reshape_tables, steps are grouped by event id and time (window in microseconds), producing per-hitt0andevtidcolumns. Detectors inflat_hit_tablesalready hold one hit per detector per event and are written alongside the reshaped detectors with theirtimecolumn renamed tot0(no step-grouping). Tables listed inforward_tablesare copied unchanged.- Parameters:
hit_files (list[str] | str) – list of output hit files (one per stp file) or a single file when all inputs should be merged into the same output.
reshape_tables (Sequence[str]) – detector tables to reshape via time-grouping.
forward_tables (Sequence[str]) – auxiliary tables to forward to the output unchanged.
out_field (str) – lh5 group under which reshaped detector tables are written.
time_window_in_us (float) – coincidence time window in microseconds for hit grouping.
flat_hit_tables (Sequence[str]) – detector tables that already contain one hit per detector per event (e.g. calorimeter output) and must not be step-grouped. They are written next to the reshaped detectors under
out_fieldwithtimerenamed tot0so they can join the time-coincidence map.overwrite (bool) – whether to overwrite the output files.
buffer (int) – buffer size (in rows) for the lh5 iterator.
- Return type:
None
remage.utils module¶
- remage.utils._to_list(thing)¶