Make modules follow a uniform interface
What we have now
We have lots of modules:
- PrimaryGenerators
- CherenkovGenerators
- CloneGenerators
- Propagators
- Triggers
- Analyses
- Writers
- etc
Most of them have distinct base classes, however these classes are very similar - they have one function, which receives an event
and does something with it (adds new particles, analyzes existing etc, writes out the output).
This implements a Visitor pattern, and it makes our modules very much independent of each other - which is really nice!
And it's possible to make pipelines, just by looping over the visitors, and allowing them to "visit" the event. Imagine having our NTSim organized like this:
class NTSim:
steps = [PrimaryGenerator(...), CherenkovGenerator(...), ..., H5Writer(...)]
...
def process(self, event):
for step in self.steps:
step.process(event)
Problem
In our implementation the method names are different for different base classes (PrimaryGeneratorBase.make_event
, PropagatorBase.propagate
...).
Also in the NTSim
these classes are hardcoded, so we can't make various pipelines - instead we have to provide a flag for each of the module, if it is participating in our pipeline...
This is problematic.
What I suggest
Making a base class:
class EventProcessor:
def begin_job(self):
#run before the beginning of the pipeline
...
def end_job(self):
#run after the pipeline
...
def process(self, event):
#run for each event
...
and make sure all our modules implement this scheme.
There are many nice features with this pattern:
- Code unification, we can loop over the modules and reuse/substitute them
- We can make complex
EventProcessor
s - for example, decorators, or entire processor chains -
NTSim
will also be such a chain - processing each event, feeding it to its children one-by-one