Skip to content

Commit 6e9b0e7

Browse files
committed
New method to select primaries
1 parent f93e4e1 commit 6e9b0e7

1 file changed

Lines changed: 100 additions & 41 deletions

File tree

DPG/Tasks/AOTTrack/PID/HMPID/hmpidTableProducer.cxx

Lines changed: 100 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
#include <Framework/runDataProcessing.h>
3535

3636
#include <TGeoManager.h>
37+
#include <TPDGCode.h>
3738

3839
#include <HMPIDBase/Param.h>
3940

@@ -73,6 +74,12 @@ struct HmpidTableProducer {
7374
Configurable<bool> requireTPC{"requireTPC", true, "Require TPC track"};
7475
Configurable<bool> requireTOF{"requireTOF", true, "Require TOF track"};
7576

77+
Configurable<bool> useInAbsorberGeomMethod{"useInAbsorberGeomMethod", false, "Use geometrical method to check if daughters are born in absorber"};
78+
79+
// (reference) 473 cm - was the legacy value in run2 simulation
80+
Configurable<float> survivalThresholdRich2{"survivalThresholdRich2", 437.5f, "survivalThresholdRich2"};
81+
Configurable<float> survivalThresholdRich4{"survivalThresholdRich4", 439.0f, "survivalThresholdRich4"};
82+
7683
using CollisionCandidates = o2::soa::Join<aod::Collisions, aod::EvSels, aod::Mults, aod::CentFV0As>;
7784

7885
using TrackCandidates = soa::Join<aod::Tracks, aod::TracksExtra,
@@ -94,27 +101,7 @@ struct HmpidTableProducer {
94101

95102
static constexpr int Rich2 = 2, Rich4 = 4;
96103

97-
// -----------------------------------------------------------------------
98-
// HMPID absorber geometry (hardcoded from HMPIDSimulation/Detector.cxx,
99-
// Detector::ConstructGeometry / Detector::createAbsorber).
100-
// The experiment is finalised and this geometry will not change, so the
101-
// values are copied here instead of being re-derived from TGeoManager/CCDB
102-
// at runtime. If the detector geometry code is ever revisited, these
103-
// constants must be updated accordingly.
104-
//
105-
// Each absorber is a box (TGeoBBox) whose LOCAL->GLOBAL transform is built as:
106-
// pMatrix->SetTranslation(T);
107-
// pMatrix->RotateZ(theta);
108-
// which yields, for a local point p: p_glob = Rz(theta) * p_loc + T.
109-
// In particular the box CENTER in global coordinates is exactly T (the
110-
// rotation does not affect T, since it is applied to p_loc only, not to
111-
// the already-set translation). Only the box AXES are rotated by theta
112-
// with respect to the global x,y axes.
113-
//
114-
// To test whether a global point lies inside the box we invert the
115-
// transform: p_loc = Rz(-theta) * (p_glob - T), then compare component-wise
116-
// against the box half-widths.
117-
// -----------------------------------------------------------------------
104+
// (reference) HMPID Detector class in O2
118105
static constexpr double AbsThetaDeg = 33.5;
119106
const double mAbsCosT = std::cos(AbsThetaDeg * TMath::DegToRad());
120107
const double mAbsSinT = std::sin(AbsThetaDeg * TMath::DegToRad());
@@ -159,6 +146,10 @@ struct HmpidTableProducer {
159146
kTH1F, {{4, -0.5, 3.5, ""}});
160147

161148
histos.add("hProdVertex", ";X (cm);Y (cm);Z (cm)", HistType::kTH3F, {{500, -500., 500.}, {500, -500., 500.}, {500, -500., 500.}});
149+
histos.add("hDaughterRCyl_Rich2", "hDaughterRCyl_Rich2", kTH1F, {{600, 0., 600.}});
150+
histos.add("hDaughterRCyl_Rich4", "hDaughterRCyl_Rich4", kTH1F, {{600, 0., 600.}});
151+
histos.add("hDaughterRSph_Rich2", "hDaughterRSph_Rich2", kTH1F, {{600, 0., 600.}});
152+
histos.add("hDaughterRSph_Rich4", "hDaughterRSph_Rich4", kTH1F, {{600, 0., 600.}});
162153
}
163154

164155
// -----------------------------------------------------------------------
@@ -361,17 +352,32 @@ struct HmpidTableProducer {
361352
return false;
362353
}
363354

364-
// subtract the box center (translation is not rotated, see geometry block above)
365-
const double rx = vx * mAbsCosT + vy * mAbsSinT;
366-
const double ry = -vx * mAbsSinT + vy * mAbsCosT;
367-
const double rz = vz;
355+
// translate to box center
356+
const double lx = vx - centerX;
357+
const double ly = vy; // centerY = 0
358+
const double lz = vz - centerZ;
368359

369360
// rotate by -theta into the box local frame
370-
const double lx = rx - centerX;
371-
const double ly = ry; // centerY = 0
372-
const double lz = rz - centerZ;
361+
const double rx = lx * mAbsCosT + ly * mAbsSinT;
362+
const double ry = -lx * mAbsSinT + ly * mAbsCosT;
363+
const double rz = lz;
364+
365+
return std::abs(rx) <= halfX && std::abs(ry) <= AbsHalfY && std::abs(rz) <= AbsHalfZ;
366+
}
367+
368+
bool survivedAbsorber(double vx, double vy, int chamber)
369+
{
370+
float thresholdR = 0.;
371+
if (chamber == Rich2) {
372+
thresholdR = survivalThresholdRich2;
373+
} else if (chamber == Rich4) {
374+
thresholdR = survivalThresholdRich4;
375+
} else {
376+
return false;
377+
}
373378

374-
return std::abs(lx) <= halfX && std::abs(ly) <= AbsHalfY && std::abs(lz) <= AbsHalfZ;
379+
const float r = std::hypot(vx, vy);
380+
return r > thresholdR;
375381
}
376382

377383
void processEvent(CollisionCandidates::iterator const& col,
@@ -514,23 +520,76 @@ struct HmpidTableProducer {
514520

515521
if ((chamberM3 == Rich2 || chamberM3 == Rich4) && mc.has_daughters()) {
516522
auto dIds = mc.daughtersIds();
517-
518-
for (int32_t idx = dIds.front(); idx <= dIds.back(); ++idx) {
519-
auto daughter = mcParticles.rawIteratorAt(idx);
520-
521-
histos.fill(HIST("hProdVertex"), daughter.vx(), daughter.vy(), daughter.vz());
522-
523-
if (isInAbsorber(daughter.vx(), daughter.vy(), daughter.vz(), chamberM3)) {
524-
interactionInAbsorber = true;
525-
break;
526-
}
527-
} // end loop daughters
523+
bool foundRelevantDaughter = false; // true if at least one non-delta/photon daughter was examined
524+
525+
if (useInAbsorberGeomMethod) {
526+
for (int32_t idx = dIds.front(); idx <= dIds.back(); ++idx) {
527+
auto daughter = mcParticles.rawIteratorAt(idx);
528+
529+
int absPdg = std::abs(daughter.pdgCode());
530+
if (absPdg == kElectron || absPdg == kGamma)
531+
continue;
532+
533+
foundRelevantDaughter = true;
534+
535+
// diagnostics on daughters distribution
536+
histos.fill(HIST("hProdVertex"), daughter.vx(), daughter.vy(), daughter.vz());
537+
538+
double rCyl = std::hypot(daughter.vx(), daughter.vy());
539+
double rSph = std::hypot(daughter.vx(), daughter.vy(), daughter.vz());
540+
if (chamberM3 == Rich2) {
541+
histos.fill(HIST("hDaughterRCyl_Rich2"), rCyl);
542+
histos.fill(HIST("hDaughterRSph_Rich2"), rSph);
543+
} else {
544+
histos.fill(HIST("hDaughterRCyl_Rich4"), rCyl);
545+
histos.fill(HIST("hDaughterRSph_Rich4"), rSph);
546+
}
547+
548+
if (isInAbsorber(daughter.vx(), daughter.vy(), daughter.vz(), chamberM3)) {
549+
interactionInAbsorber = true;
550+
}
551+
} // end loop daughters
552+
} else {
553+
bool survived = false;
554+
for (int32_t idx = dIds.front(); idx <= dIds.back(); ++idx) {
555+
auto daughter = mcParticles.rawIteratorAt(idx);
556+
557+
// skip delta rays (e-/e+), photons, and HMPID Cherenkov/feedback
558+
int absPdg = std::abs(daughter.pdgCode());
559+
if (absPdg == kElectron || absPdg == kGamma)
560+
continue;
561+
562+
foundRelevantDaughter = true;
563+
564+
histos.fill(HIST("hProdVertex"), daughter.vx(), daughter.vy(), daughter.vz());
565+
566+
double rCyl = std::hypot(daughter.vx(), daughter.vy());
567+
double rSph = std::hypot(daughter.vx(), daughter.vy(), daughter.vz());
568+
if (chamberM3 == Rich2) {
569+
histos.fill(HIST("hDaughterRCyl_Rich2"), rCyl);
570+
histos.fill(HIST("hDaughterRSph_Rich2"), rSph);
571+
} else {
572+
histos.fill(HIST("hDaughterRCyl_Rich4"), rCyl);
573+
histos.fill(HIST("hDaughterRSph_Rich4"), rSph);
574+
}
575+
576+
if (survivedAbsorber(daughter.vx(), daughter.vy(), chamberM3)) {
577+
survived = true;
578+
}
579+
} // end loop daughters
580+
581+
// No relevant daughter found (only delta rays/photons, or no
582+
// daughters at all): no evidence of a genuine interaction -> treat
583+
// as primary/survived, consistent with the "no daughters" case.
584+
interactionInAbsorber = foundRelevantDaughter ? !survived : false;
585+
}
528586
} // end if has_daughters
529587

530588
hmpidAnalysisMC(mc.pdgCode(), mc.vx(), mc.vy(), mc.vz(),
531589
mc.isPhysicalPrimary(), mc.getProcess(), interactionInAbsorber);
532590
} else {
533-
hmpidAnalysisMC(-1, 0.f, 0.f, 0.f, false, -100, false);
591+
// No MC truth associated to this track
592+
hmpidAnalysisMC(-999, -999.f, -999.f, -999.f, false, -100, false);
534593
}
535594
} // end if constexpr (isMC)
536595

0 commit comments

Comments
 (0)