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

Add TaggerHitFilter and no-cals detectors #1424

Merged
merged 3 commits into from
Sep 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
68 changes: 68 additions & 0 deletions Biasing/include/Biasing/TaggerHitFilter.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
#pragma once

//~~ C++ StdLib ~~//
#include <set>
#include <string>

//~~ SimCore ~~//
#include "SimCore/UserAction.h"

//~~ Framework ~~//
#include "Framework/Configure/Parameters.h"
#include "Framework/EventProcessor.h"

tvami marked this conversation as resolved.
Show resolved Hide resolved
// Forward declarations
class G4Step;

namespace biasing {

/**
* User stepping action used to filter events where the incident electron
* fails to hit a minimum number of tracker sensors.
*/
class TaggerHitFilter : public simcore::UserAction {
public:
/**
* Constructor.
*
* @param[in] name the name of the instance of this UserAction.
* @param[in] parameters the parameters used to configure this
* UserAction.
*/
TaggerHitFilter(const std::string& name,
framework::config::Parameters& parameters);

/// Destructor
~TaggerHitFilter() = default;

/**
* Stepping action called when a step is taken during tracking of
* a particle.
*
* @param[in] step Geant4 step
*/
void stepping(const G4Step* step) final override;

/**
* Action called once tracking of all particles has concluded. This is being
* used to clear the hit count set in preparation for the next event.
*/
void EndOfEventAction(const G4Event* event) final override;
tomeichlersmith marked this conversation as resolved.
Show resolved Hide resolved

/// Retrieve the type of actions this class defines
std::vector<simcore::TYPE> getTypes() final override {
return {simcore::TYPE::STEPPING, simcore::TYPE::EVENT};
}

private:
void checkAbortEvent(G4Track* track);

/// Set used to keep track which layers were hit by a particle.
std::set<int> layer_count_;
/// Total number of hits required to persist an event.
int layers_hit_{8};
/// Enable logging
enableLogging("TaggerHitFilter")

tvami marked this conversation as resolved.
Show resolved Hide resolved
}; // TaggerHitFilter
} // namespace biasing
17 changes: 17 additions & 0 deletions Biasing/python/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -247,3 +247,20 @@ def __init__(self,thresh) :
include.library()

self.threshold = thresh


class TaggerHitFilter(simcfg.UserAction):
""" Configuration used to reject off-energy electrons in the tagger tracker.
Parameters
----------
layers_hit : int
Minimum number of tagger layers with a hit needed to persist the event.
"""

def __init__(self, layersHit=8) :
super().__init__('tagger_hit_filter','biasing::TaggerHitFilter')

from LDMX.Biasing import include
include.library()

self.layers_hit = layersHit
77 changes: 77 additions & 0 deletions Biasing/src/Biasing/TaggerHitFilter.cxx
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@

#include "Biasing/TaggerHitFilter.h"

//~~ Geant4 ~~//
#include "G4RunManager.hh"
#include "G4Step.hh"

namespace biasing {

TaggerHitFilter::TaggerHitFilter(const std::string& name,
framework::config::Parameters& parameters)
: simcore::UserAction(name, parameters) {
layers_hit_ = parameters.getParameter<int>("layers_hit", 8);
ldmx_log(debug) << " layers_hit_ = " << layers_hit_;
}

void TaggerHitFilter::stepping(const G4Step* step) {
// The track associated with this step will allow for the extraction of info
// needed to determine if this is the incident electron.
auto track{step->GetTrack()};
// Require that track is charged
if (auto pdgCh{track->GetParticleDefinition()->GetPDGCharge()};
abs(pdgCh) == 0) {
return;
}

// Only electrons in the Tagger region are of interest.
auto volume{track->GetVolume()};
if (auto region{volume->GetLogicalVolume()->GetRegion()->GetName()};
region.compareTo("tagger") != 0)
return;

// Check if we are exiting the tagger
if (auto nregion{
track->GetNextVolume()->GetLogicalVolume()->GetRegion()->GetName()};
(nregion.compareTo("tagger") != 0)) {
checkAbortEvent(track);
return;
}

// A particle will only leave hits in the active silicon so other volumes can
// be skipped for now.
if (auto volume_name{track->GetVolume()->GetName()};
volume_name.compareTo("tagger_PV") == 0)
return;

// The copy number is used to identify which layer energy was deposited into.
auto copy_number{step->GetPreStepPoint()
->GetTouchableHandle()
->GetHistory()
->GetVolume(2)
->GetCopyNo()};

layer_count_.insert(copy_number);
}

void TaggerHitFilter::EndOfEventAction(const G4Event* event) {
tomeichlersmith marked this conversation as resolved.
Show resolved Hide resolved
checkAbortEvent(nullptr);
layer_count_.clear();
}

void TaggerHitFilter::checkAbortEvent(G4Track* track) {
// These numbers may change in the future
constexpr int early_layer_requirement = 10;
constexpr int late_layer_requirement = 20;
if ((layer_count_.size() < layers_hit_) ||
((layer_count_.count(early_layer_requirement) == 0) &&
(layer_count_.count(late_layer_requirement) == 0))) {
if (track != nullptr) track->SetTrackStatus(fKillTrackAndSecondaries);
G4RunManager::GetRunManager()->AbortEvent();
return;
}
}

} // namespace biasing

DECLARE_ACTION(biasing, TaggerHitFilter)
Loading