Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: allow users of ddsim to set e.g. stepping action #1218

Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
c75b0b6
feat: add Geant4TestStackAction
wdconinc Jan 25, 2024
b68eda5
feat: allow ddsim --action.step etc for action plugins
wdconinc Jan 25, 2024
f853680
fix: rm EOF empty line
wdconinc Jan 25, 2024
34659bc
feat: print Geant4TestActions properties at destruction
wdconinc Feb 3, 2024
347d966
fix: expect list of tuple or dict for actions; parse JSON on CLI
wdconinc Feb 4, 2024
6ae0a93
fix: placate flake8
wdconinc Feb 4, 2024
83a89d3
fix: placate flake8
wdconinc Feb 4, 2024
4ce8931
fix: extended Action docstring
wdconinc Feb 4, 2024
f2b445b
fix: docstring line breaks for flake8
wdconinc Feb 4, 2024
cd08eb8
fix: split comma-separated string into list of dict
wdconinc Feb 4, 2024
cc9994b
fix: typo
wdconinc Feb 5, 2024
823c597
fix: grammar
wdconinc Feb 5, 2024
74719e2
doc: add json example
wdconinc Feb 5, 2024
028c796
fix: allow dict without parameter key
wdconinc Feb 5, 2024
e5834cf
feat: unit tests for ddsim actions (no output checks)
wdconinc Feb 6, 2024
e166b19
fix: use dict.get with default empty
wdconinc Feb 6, 2024
02fa084
fix: correct quoting of DDTest command line json
wdconinc Feb 10, 2024
62b7b14
fix: accept list of str as action argument
wdconinc Feb 10, 2024
c452e5a
fix: action=append for argparse; deduplicate; recursive makeListOfDic…
wdconinc Feb 11, 2024
088ca64
Merge branch 'master' into ddsim-set-run-event-track-step-stack-actions
MarkusFrankATcernch Feb 11, 2024
24e8de7
Merge branch 'master' into ddsim-set-run-event-track-step-stack-actions
MarkusFrankATcernch Feb 12, 2024
292bcea
Update Geant4TestActions.cpp
MarkusFrankATcernch Feb 12, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions DDG4/include/DDG4/Geant4TestActions.h
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,26 @@ namespace dd4hep {
void operator()(const G4Step*, G4SteppingManager*) override;
};

/// Example stacking action doing nothing, but print
/**
* \author M.Frank
* \version 1.0
* \ingroup DD4HEP_SIMULATION
*/
class Geant4TestStackAction: public Geant4StackingAction, public Geant4TestBase {
public:
/// Standard constructor with initializing arguments
Geant4TestStackAction(Geant4Context* c, const std::string& n);
/// Default destructor
virtual ~Geant4TestStackAction();
/// New-stage callback
virtual void newStage(G4StackManager*) override;
/// Preparation callback
virtual void prepare(G4StackManager*) override;
/// Return TrackClassification with enum G4ClassificationOfNewTrack or NoTrackClassification
virtual TrackClassification classifyNewTrack(G4StackManager*, const G4Track*) override;
};

/// Example sensitve detector action doing nothing, but print
/**
* \author M.Frank
Expand Down
2 changes: 1 addition & 1 deletion DDG4/plugins/Geant4Factories.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ DECLARE_GEANT4ACTION(Geant4TestRunAction)
DECLARE_GEANT4ACTION(Geant4TestEventAction)
DECLARE_GEANT4ACTION(Geant4TestStepAction)
DECLARE_GEANT4ACTION(Geant4TestTrackAction)
//DECLARE_GEANT4ACTION(Geant4TestStackingAction)
DECLARE_GEANT4ACTION(Geant4TestStackAction)
DECLARE_GEANT4ACTION(Geant4TestGeneratorAction)
DECLARE_GEANT4SENSITIVE(Geant4TestSensitive)
DECLARE_GEANT4SENSITIVE(Geant4TestSensitiveTracker)
Expand Down
14 changes: 14 additions & 0 deletions DDG4/python/DDSim/DD4hepSimulation.py
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,20 @@ def run(self):
# configure geometry creation
self.geometry.constructGeometry(kernel, geant4, self.output.geometry)

# ----------------------------------------------------------------------------------
# Configure run, event, track, step, and stack actions, if present
for action_list, DDG4_Action, kernel_Action in \
[(self.action.run, DDG4.RunAction, kernel.runAction),
(self.action.event, DDG4.EventAction, kernel.eventAction),
(self.action.track, DDG4.TrackingAction, kernel.trackingAction),
(self.action.step, DDG4.SteppingAction, kernel.steppingAction),
(self.action.stack, DDG4.StackingAction, kernel.stackingAction)]:
for action_dict in action_list:
action = DDG4_Action(kernel, action_dict["name"])
for parameter, value in action_dict['parameter'].items():
wdconinc marked this conversation as resolved.
Show resolved Hide resolved
setattr(action, parameter, value)
wdconinc marked this conversation as resolved.
Show resolved Hide resolved
kernel_Action().add(action)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We may want to kernel.registerGlobalAction(action) here to allow access by name later on(?).

# ----------------------------------------------------------------------------------
# Configure Run actions
run1 = DDG4.RunAction(kernel, 'Geant4TestRunAction/RunInit')
Expand Down
86 changes: 84 additions & 2 deletions DDG4/python/DDSim/Helper/Action.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@


class Action(ConfigHelper):
"""Helper holding sensitive detector actions.
"""Helper holding sensitive detector and other actions.

The default tracker and calorimeter actions can be set with
The default tracker and calorimeter sensitive actions can be set with

>>> SIM = DD4hepSimulation()
>>> SIM.action.tracker=('Geant4TrackerWeightedAction', {'HitPositionCombination': 2, 'CollectSingleDeposits': False})
Expand All @@ -30,6 +30,15 @@ class Action(ConfigHelper):
>>> SIM = DD4hepSimulation()
>>> SIM.action.mapActions['ecal'] =( "CaloPreShowerSDAction", {"FirstLayerNumber": 1} )

Additional actions can be set as well with

>>> SIM = DD4hepSimulation()
>>> SIM.action.run = [ ("Geant4TestRunAction", {"Property_int": 10} ) ]
>>> SIM.action.event = [ ("Geant4TestEventAction", {"Property_int": 10} ) ]
>>> SIM.action.track = [ ("Geant4TestTrackAction", {"Property_int": 10} ) ]
>>> SIM.action.step = [ ("Geant4TestStepAction", {"Property_int": 10} ) ]
>>> SIM.action.stack = [ ("Geant4TestStackAction", {"Property_int": 10} ) ]
wdconinc marked this conversation as resolved.
Show resolved Hide resolved

"""

def __init__(self):
Expand All @@ -39,6 +48,11 @@ def __init__(self):
self._mapActions = dict()
self._trackerSDTypes = ['tracker']
self._calorimeterSDTypes = ['calorimeter']
self._run = []
self._event = []
self._track = []
self._step = []
self._stack = []
self._closeProperties()

@property
Expand Down Expand Up @@ -108,3 +122,71 @@ def calorimeterSDTypes(self):
@calorimeterSDTypes.setter
def calorimeterSDTypes(self, val):
self._calorimeterSDTypes = ConfigHelper.makeList(val)

@staticmethod
def makeListOfDictFromJSON(val):
if isinstance(val, str):
# assumes: valid JSON string or comma-separated list of names
import json
try:
val = json.loads(val)
except ValueError:
val = tuple(val.split(","))
wdconinc marked this conversation as resolved.
Show resolved Hide resolved
if isinstance(val, tuple):
# assumes: ( "Geant4TestEventAction", {"Property_int": 10} )
# creates: { "name": "Geant4TestEventAction", "parameter": {"Property_int": 10} }
# note: not able to specified as json which only allows a list
wdconinc marked this conversation as resolved.
Show resolved Hide resolved
val = dict(name=val[0], parameter=val[1])
if isinstance(val, dict):
# assumes: { "name": "Geant4TestEventAction", "parameter": {"Property_int": 10} }
# creates: [ { "name": "Geant4TestEventAction", "parameter": {"Property_int": 10} } ]
val = [val]
if isinstance(val, list):
# assumes: [ { "name": "Geant4TestEventAction", "parameter": {"Property_int": 10} } ]
return val
wdconinc marked this conversation as resolved.
Show resolved Hide resolved
raise RuntimeError("Commandline setting of action is not successful for: %s " % val)

@property
def run(self):
""" set the default run action """
return self._run

@run.setter
def run(self, val):
self._run.extend(Action.makeListOfDictFromJSON(val))

@property
def event(self):
""" set the default event action """
return self._event

@event.setter
def event(self, val):
self._event.extend(Action.makeListOfDictFromJSON(val))

@property
def track(self):
""" set the default track action """
return self._track

@track.setter
def track(self, val):
self._track.extend(Action.makeListOfDictFromJSON(val))

@property
def step(self):
""" set the default step action """
return self._step

@step.setter
def step(self, val):
self._step.extend(Action.makeListOfDictFromJSON(val))

@property
def stack(self):
""" set the default stack action """
return self._stack

@stack.setter
def stack(self, val):
self._stack.extend(Action.makeListOfDictFromJSON(val))
28 changes: 28 additions & 0 deletions DDG4/src/Geant4TestActions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ Geant4TestBase::Geant4TestBase(Geant4Action* a, const std::string& typ)
}
/// Default destructor
Geant4TestBase::~Geant4TestBase() {
printout(VERBOSE, m_type, "properties at destruction: %d, %f, %s", m_value1, m_value2, m_value3.c_str());
InstanceCount::decrement(this);
}

Expand Down Expand Up @@ -185,6 +186,33 @@ void Geant4TestStepAction::operator()(const G4Step*, G4SteppingManager*) {
PRINT("%s> calling operator()", m_type.c_str());
}

/// Standard constructor with initializing arguments
Geant4TestStackAction::Geant4TestStackAction(Geant4Context* c, const std::string& n)
: Geant4StackingAction(c, n), Geant4TestBase(this, "Geant4TestStackAction") {
InstanceCount::increment(this);
}

/// Default destructor
Geant4TestStackAction::~Geant4TestStackAction() {
InstanceCount::decrement(this);
}
/// New-stage callback
void Geant4TestStackAction::newStage(G4StackManager*) {
PRINT("%s> calling newStage()", m_type.c_str());
}
/// Preparation callback
void Geant4TestStackAction::prepare(G4StackManager*) {
PRINT("%s> calling prepare()", m_type.c_str());
}
/// Return TrackClassification with enum G4ClassificationOfNewTrack or NoTrackClassification
TrackClassification Geant4TestStackAction::classifyNewTrack(G4StackManager*, const G4Track* trk) {
PRINT("%s> calling classifyNewTrack(track=%d, parent=%d, position=(%f,%f,%f) Context: run=%p evt=%p)",
m_type.c_str(), trk->GetTrackID(),
trk->GetParentID(), trk->GetPosition().x(), trk->GetPosition().y(), trk->GetPosition().z(),
&context()->run(), &context()->event());
return TrackClassification();
}

/// Standard constructor with initializing arguments
Geant4TestSensitive::Geant4TestSensitive(Geant4Context* c, const std::string& n, DetElement det, Detector& description)
: Geant4Sensitive(c, n, det, description), Geant4TestBase(this, "Geant4TestSensitive") {
Expand Down
Loading