Skip to content
This repository has been archived by the owner on May 6, 2024. It is now read-only.

Commit

Permalink
refactor to move config deducing into python
Browse files Browse the repository at this point in the history
the translation of different format of runs provided by the user into
the actual data structure used during processing is done within python
now so it can be more transparent in error
  • Loading branch information
tomeichlersmith committed Nov 14, 2023
1 parent ddc1a52 commit bde4f0d
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 62 deletions.
32 changes: 11 additions & 21 deletions include/SimCore/ReSimulator.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,43 +27,33 @@ class ReSimulator : public SimulatorBase {

private:
/**
* List of event numbers in the input files that should be resimulated if
* List of events in the input files that should be resimulated if
* `resimulate_all_events` is false.
*
* @note: If an event number in `events_to_resimulate_` is not part of the
* Each event is identified uniquely by its run number and event number.
*
* @note: If an event in `events_to_resimulate_` is not part of the
* input file, it will be ignored.
*/
std::vector<int> events_to_resimulate_;
std::vector<std::pair<int,int>> events_to_resimulate_;

/**
* List of run numbers in the input files that should be resimulated if
* `resimulate_all_events` is false.
*
* @note: If a run number in `runs_to_resimulate_` is not part of the
* input file, it will be ignored.
*
* The list of runs to resimulate comes in one of three forms:
* 1. Empty: If no runs are given, we only match based off the event number.
* 2. Single Entry: If only one run is given, then we require the run number
* to be that entry for all events requested to resimulate.
* 3. More than one entry: In this case, we require the length of this list
* to be the same as the length of the events to resimulate so that we
* only resimulate events where the event/run *pair* matches a corresponding
* *pair* in the events and runs to resimulate lists.
* Whether to resimulate all events in the input files
*/
std::vector<int> runs_to_resimulate_;
bool resimulate_all_events_;

/**
* Whether to resimulate all events in the input files
* Whether or not we should check the run number when seeing
* if a specific event should be resimulated
*/
bool resimulate_all_events;
bool care_about_run_;

/*
* How many events have already been resimulated. This determines the event
* number in the output file, since more than one input file can be used.
*
*/
int events_resimulated = 0;
int events_resimulated_ = 0;
};
} // namespace simcore

Expand Down
31 changes: 26 additions & 5 deletions python/simulator.py.in
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,25 @@ with several helpful member functions.

from @PYTHON_PACKAGE_NAME@.Framework.ldmxcfg import Producer

class _EventToReSim:
"""A class to hold the information identifying a specific event we wish to re-simulate

This is an internal class used by simulator.resimulate in order to pass the event
identification to the ReSimulator class

Attributes
----------
run: int
run number of the event to re-sim, -1 if we don't care about the run
event: int
event number to re-sim, required
"""

def __init__(self, event, run = -1):
self.event = event
self.run = run


class simulator(Producer):
"""A instance of the simulation configuration

Expand Down Expand Up @@ -174,23 +193,25 @@ class simulator(Producer):
resimulator.className = 'simcore::ReSimulator'
if which_events is None:
resimulator.resimulate_all_events = True
resimulator.care_about_run = False
resimulator.events_to_resimulate = [ ]
resimulator.runs_to_resimulate = [ ]
elif isinstance(which_events, list):
resimulator.resimulate_all_events = False
resimulator.events_to_resimulate = which_events
if len(which_events) == 0:
raise ValueError('which_events must contain at least one element if provided')
if which_runs is None:
resimulator.runs_to_resimulate = [ ]
resimulator.care_about_run = False
resimulator.events_to_resimulate = [ _EventToReSim(event) for event in which_events ]
elif isinstance(which_runs, int):
resimulator.runs_to_resimulate = [ which_runs ]
resimulator.care_about_run = True
resimulator.events_to_resimulate = [ _EventToReSim(event, which_runs) for event in which_events ]
elif isinstance(which_runs, list):
if len(which_runs) == 0:
raise ValueError('which_runs must have at least one value if provided as a list')
if len(which_runs) != len(which_events):
raise ValueError('which_runs must have the same number of entries as which_events if more than one run is provided')
resimulator.runs_to_resimulate = which_runs
resimulator.care_about_run = True
resimulator.runs_to_resimulate = [ _EventToReSim(event, run) for event, run in zip(which_events, which_runs) ]
else:
raise ValueError('which_runs must be an int or a list of ints if provided')
else:
Expand Down
58 changes: 22 additions & 36 deletions src/SimCore/ReSimulator.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -4,55 +4,41 @@ namespace simcore {

void ReSimulator::configure(framework::config::Parameters& parameters) {
SimulatorBase::configure(parameters);
resimulate_all_events =
resimulate_all_events_ =
parameters.getParameter<bool>("resimulate_all_events");
if (!resimulate_all_events) {
events_to_resimulate_ =
parameters.getParameter<std::vector<int>>("events_to_resimulate", {});
runs_to_resimulate_ =
parameters.getParameter<std::vector<int>>("runs_to_resimulate", {});
if (events_to_resimulate_.size() == 0) {
if (!resimulate_all_events_) {
care_about_run_ = parameters.getParameter<bool>("care_about_run");
auto configured_events{parameters.getParameter<std::vector<framework::config::Parameters>>("events_to_resimulate", {})};
if (configured_events.size() == 0) {
EXCEPTION_RAISE(
"ReSimNoEvents",
"ReSim was configured with resimulate_all_events marked false but "
"no event numbers were requested.\n\nDid you forget to configure "
"the events_to_resimulate parameter?\n");
}
if (runs_to_resimulate_.size() > 1 and runs_to_resimulate_.size() != events_to_resimulate_.size()) {
EXCEPTION_RAISE(
"ReSimBadConf",
"ReSim needs the runs list to match the length of the events list if there is more than "
"one run that needs to be resimulated.");
for (const auto& run_event : configured_events) {
events_to_resimulate_.emplace_back(
run_event.getParameter<int>("run"),
run_event.getParameter<int>("event")
);
}
}
}

void ReSimulator::produce(framework::Event& event) {
/* numEventsBegan_++; */
auto& eventHeader{event.getEventHeader()};
const auto eventNumber{eventHeader.getEventNumber()};
if (!resimulate_all_events) {
auto found_event = std::find(std::begin(events_to_resimulate_),
std::end(events_to_resimulate_), eventNumber);
bool should_resim{found_event != std::end(events_to_resimulate_)};
if (should_resim and runs_to_resimulate_.size() > 0) {
// non-empty list of runs and event number in event list,
// we need to check run number is also requested
int run{event.getEventHeader().getRun()};
if (runs_to_resimulate_.size() == 1) {
// single run applied to all events requested
should_resim = runs_to_resimulate_.at(0) == run;
} else {
// more than one run, look for run corresponding to index
// of event number found
// developer note: this code has a high-liklihood of throwing
// the std::out_of_range error if the runs_to_resimulate_ vector
// isn't pre-checked to be the same size as events_to_resimulate_
should_resim = runs_to_resimulate_.at(
std::distance(events_to_resimulate_.begin(), found_event)
) == run;
}
}
if (not should_resim) {
if (!resimulate_all_events_) {
auto found_event_to_resim = std::find_if(
std::begin(events_to_resimulate_), std::end(events_to_resimulate_),
[&](const std::pair<int,int>& run_event) -> bool {
bool runs_match = true;
if (care_about_run_) runs_match = (event.getEventHeader().getRun() == run_event.first);
return eventNumber == run_event.second and runs_match;
}
);
if (found_event_to_resim == std::end(events_to_resimulate_)) {
if (verbosity_ > 1) {
std::cout << "Skipping event: " << eventNumber
<< " since it wasn't part of the requested events..."
Expand Down Expand Up @@ -83,7 +69,7 @@ void ReSimulator::produce(framework::Event& event) {
std::to_string(eventNumber));
}

eventHeader.setEventNumber(++events_resimulated);
eventHeader.setEventNumber(++events_resimulated_);
updateEventHeader(eventHeader);
saveTracks(event);

Expand Down

0 comments on commit bde4f0d

Please sign in to comment.