Skip to content

Commit 9180222

Browse files
Fix PFTrack producer to find electrons in signal with overlay (#1706)
* Add input pass names + printout to existence checks * Add specific (multi-)electron tracking condition * Add constituent hit association to clusters * Fix response correction bug at out-of-range values * Add boolean to only track beam electrons * Remove unused debug flag * Apply clang-format * Make electron selection criteria configurable * Apply clang-format * Remove trailing debug bool in PF Ecal clustering * Remove trailing debug bool in PF Hcal clustering --------- Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
1 parent 5d056d7 commit 9180222

File tree

8 files changed

+62
-18
lines changed

8 files changed

+62
-18
lines changed

Recon/include/Recon/DBScanClusterBuilder.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ class DBScanClusterBuilder {
2727
float minClusterHitMult); // overloaded constructor
2828

2929
std::vector<std::vector<const ldmx::CalorimeterHit *> > runDBSCAN(
30-
const std::vector<const ldmx::CalorimeterHit *> &hits, bool debug);
30+
const std::vector<const ldmx::CalorimeterHit *> &hits);
3131

3232
void fillClusterInfoFromHits(ldmx::CaloCluster *cl,
3333
std::vector<const ldmx::CalorimeterHit *> hits,

Recon/include/Recon/PFTrackProducer.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,13 @@ class PFTrackProducer : public framework::Producer {
3636
std::string input_pass_name_;
3737
// name of collection for pfTracks to be output
3838
std::string outputTrackCollName_;
39+
// boolean to cheat to select only electron tracks
40+
// in this cheating truth tracker
41+
bool doElectronTracking_{};
42+
// minimum z momentum component allowed for beam electron selection
43+
double minElectronMomentumZ_{};
44+
// maximum trackID allowed for beam electron selection
45+
int maxElectronTrackID_{};
3946
};
4047
} // namespace recon
4148

Recon/python/pfReco.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,11 @@ class pfTrackProducer(ldmxcfg.Producer) :
4141
def __init__(self, name='PFTrack') :
4242
super().__init__(name, 'recon::PFTrackProducer','Recon')
4343
self.inputTrackCollName = 'EcalScoringPlaneHits'
44+
self.input_pass_name = ''
4445
self.outputTrackCollName = 'PFTracks'
45-
self.input_pass_name = ''
46+
self.doElectronTracking = False
47+
self.minElectronMomentumZ = 2500.
48+
self.maxElectronTrackID = 30
4649

4750
class pfProducer(ldmxcfg.Producer) :
4851
"""Configuration for particle reco"""

Recon/src/Recon/DBScanClusterBuilder.cxx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ DBScanClusterBuilder::DBScanClusterBuilder(float minHitEnergy,
2626

2727
std::vector<std::vector<const ldmx::CalorimeterHit *> >
2828
DBScanClusterBuilder::runDBSCAN(
29-
const std::vector<const ldmx::CalorimeterHit *> &hits, bool debug = false) {
29+
const std::vector<const ldmx::CalorimeterHit *> &hits) {
3030
const int n = hits.size();
3131
std::vector<std::vector<const ldmx::CalorimeterHit *> > idx_clusters;
3232
std::vector<unsigned int> tried;
@@ -89,6 +89,7 @@ void DBScanClusterBuilder::fillClusterInfoFromHits(
8989
std::vector<float> raw_yvals{};
9090
std::vector<float> raw_zvals{};
9191
std::vector<float> raw_evals{};
92+
std::vector<const ldmx::CalorimeterHit *> constituentHits;
9293

9394
for (const ldmx::CalorimeterHit *h : hits) {
9495
if (h->getEnergy() < minHitEnergy_) continue;
@@ -106,7 +107,8 @@ void DBScanClusterBuilder::fillClusterInfoFromHits(
106107
raw_yvals.push_back(h->getYPos());
107108
raw_zvals.push_back(h->getZPos());
108109
raw_evals.push_back(h->getEnergy());
109-
}
110+
constituentHits.emplace_back(h);
111+
} // over hits
110112
x /= sumw; // now is <x>
111113
y /= sumw;
112114
z /= sumw;
@@ -124,6 +126,7 @@ void DBScanClusterBuilder::fillClusterInfoFromHits(
124126
cl->setHitValsY(raw_yvals);
125127
cl->setHitValsZ(raw_zvals);
126128
cl->setHitValsE(raw_evals);
129+
cl->addHits(constituentHits); // associate used hits to cluster
127130

128131
if (raw_xvals.size() > 2) {
129132
// skip fits for 'vertical' clusters

Recon/src/Recon/PFEcalClusterProducer.cxx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ void PFEcalClusterProducer::produce(framework::Event& event) {
3939
std::vector<const ldmx::CalorimeterHit*> ptrs;
4040
for (const auto& h : ecalRecHits) ptrs.push_back(&h);
4141
std::vector<std::vector<const ldmx::CalorimeterHit*> > all_hit_ptrs =
42-
cb.runDBSCAN(ptrs, false);
42+
cb.runDBSCAN(ptrs);
4343

4444
for (const auto& hit_ptrs : all_hit_ptrs) {
4545
ldmx::CaloCluster cl;

Recon/src/Recon/PFHcalClusterProducer.cxx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ void PFHcalClusterProducer::produce(framework::Event& event) {
4343
std::vector<const ldmx::CalorimeterHit*> ptrs;
4444
for (const auto& h : hcalRecHits) ptrs.push_back(&h);
4545
std::vector<std::vector<const ldmx::CalorimeterHit*> > all_hit_ptrs =
46-
cb.runDBSCAN(ptrs, false);
46+
cb.runDBSCAN(ptrs);
4747

4848
for (const auto& hit_ptrs : all_hit_ptrs) {
4949
ldmx::CaloCluster cl;

Recon/src/Recon/PFTrackProducer.cxx

Lines changed: 37 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ void PFTrackProducer::configure(framework::config::Parameters& ps) {
99
inputTrackCollName_ = ps.getParameter<std::string>("inputTrackCollName");
1010
input_pass_name_ = ps.getParameter<std::string>("input_pass_name");
1111
outputTrackCollName_ = ps.getParameter<std::string>("outputTrackCollName");
12+
doElectronTracking_ = ps.getParameter<bool>("doElectronTracking");
13+
minElectronMomentumZ_ = ps.getParameter<double>("minElectronMomentumZ");
14+
maxElectronTrackID_ = ps.getParameter<int>("maxElectronTrackID");
1215
}
1316

1417
double getP(const ldmx::SimTrackerHit& tk) {
@@ -28,14 +31,41 @@ void PFTrackProducer::produce(framework::Event& event) {
2831
std::vector<ldmx::SimTrackerHit> pfTracks;
2932
if (truthTracking_) {
3033
for (const auto& spHit : ecalSpHits) {
31-
if (spHit.getTrackID() != 1 || fabs(240 - spHit.getPosition()[2]) > 0.1 ||
32-
spHit.getMomentum()[2] <= 0)
33-
continue;
3434
if (spHit.getPdgID() == 22 || spHit.getPdgID() == 2112) continue;
35-
pfTracks.push_back(spHit);
36-
break;
37-
}
38-
}
35+
if (fabs(240 - spHit.getPosition()[2]) > 0.1) continue;
36+
if (doElectronTracking_) { // only select electron SP hits
37+
if (spHit.getPdgID() != 11) continue;
38+
if (spHit.getTrackID() < 2 &&
39+
spHit.getMomentum()[2] > minElectronMomentumZ_) {
40+
// this is almost guaranteed to be a pileup beam electron! keep it
41+
pfTracks.push_back(spHit);
42+
ldmx_log(debug) << "Added beam electron SP hit: trackID="
43+
<< spHit.getTrackID()
44+
<< ", pz = " << spHit.getMomentum()[2];
45+
} else if (spHit.getTrackID() <= maxElectronTrackID_ &&
46+
spHit.getMomentum()[2] > 5) {
47+
// require more than minimum forward momentum to catch recoil electron
48+
// candidates
49+
pfTracks.push_back(spHit);
50+
ldmx_log(debug) << "Adding SP hit: trackID=" << spHit.getTrackID()
51+
<< ", pdgID= " << spHit.getPdgID()
52+
<< ", pz = " << spHit.getMomentum()[2];
53+
continue;
54+
}
55+
} // if electron tracking
56+
else {
57+
if (spHit.getTrackID() != 1 ||
58+
fabs(240 - spHit.getPosition()[2]) > 0.1 ||
59+
spHit.getMomentum()[2] < 0)
60+
continue;
61+
pfTracks.push_back(spHit);
62+
ldmx_log(debug) << "Adding SP hit: trackID=" << spHit.getTrackID()
63+
<< ", pdgID= " << spHit.getPdgID()
64+
<< ", pz = " << spHit.getMomentum()[2];
65+
break;
66+
}
67+
} // over SP hits
68+
} // do truth tracking
3969
std::sort(pfTracks.begin(), pfTracks.end(),
4070
[](ldmx::SimTrackerHit a, ldmx::SimTrackerHit b) {
4171
return getP(a) > getP(b);

Recon/src/Recon/ParticleFlow.cxx

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -54,11 +54,12 @@ void ParticleFlow::fillCandEMCalo(ldmx::PFCandidate& cand,
5454
const ldmx::CaloCluster& em) {
5555
float corr = 1.;
5656
float e = em.getEnergy();
57+
// update energy: use min or max factor if outside calibration range
5758
if (e < eCorr_->GetX()[0]) {
58-
corr = eCorr_->GetX()[0];
59+
corr = eCorr_->GetY()[0];
5960
} else if (e > eCorr_->GetX()[eCorr_->GetN() - 1]) {
60-
corr = eCorr_->GetX()[eCorr_->GetN() - 1];
61-
} else {
61+
corr = eCorr_->GetY()[eCorr_->GetN() - 1];
62+
} else { // else look up calibration factor
6263
corr = eCorr_->Eval(e);
6364
}
6465
cand.setEcalEnergy(e * corr);
@@ -78,9 +79,9 @@ void ParticleFlow::fillCandHadCalo(ldmx::PFCandidate& cand,
7879
float corr = 1.;
7980
float e = had.getEnergy();
8081
if (e < hCorr_->GetX()[0]) {
81-
corr = hCorr_->GetX()[0];
82+
corr = hCorr_->GetY()[0];
8283
} else if (e > hCorr_->GetX()[hCorr_->GetN() - 1]) {
83-
corr = hCorr_->GetX()[hCorr_->GetN() - 1];
84+
corr = hCorr_->GetY()[hCorr_->GetN() - 1];
8485
} else {
8586
corr = hCorr_->Eval(e);
8687
}

0 commit comments

Comments
 (0)