Skip to content

Commit c00fa7c

Browse files
author
Marco Giacalone
committed
Add geometrical TPC protection against misfired loopers
1 parent 7e06656 commit c00fa7c

4 files changed

Lines changed: 64 additions & 0 deletions

File tree

Generators/include/Generators/TPCLoopers.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,8 +107,16 @@ class GenTPCLoopers
107107

108108
void SetAdjust(float adjust = 0.f);
109109

110+
void setGeomProtection(bool protect);
111+
112+
// check if a vertex lies in the TPC volume where ionisation can be recorded
113+
bool isInTPCActiveVolume(double vx, double vy) const;
114+
110115
unsigned int getNLoopers() const { return (mNLoopersPairs + mNLoopersCompton); }
111116

117+
// loopers dropped by the geometrical protection since the last reset
118+
unsigned int getNSkipped() const { return mNSkippedPairs + mNSkippedCompton; }
119+
112120
private:
113121
std::unique_ptr<ONNXGenerator> mONNX_pair = nullptr;
114122
std::unique_ptr<ONNXGenerator> mONNX_compton = nullptr;
@@ -137,6 +145,9 @@ class GenTPCLoopers
137145
double mTimeEnd = 0.0; // Time limit for the last event
138146
float mLoopsFractionPairs = 0.08; // Fraction of loopers from Pairs
139147
int mInteractionRate = 50000; // Interaction rate in Hz
148+
bool mGeomProtection = true; // Skip loopers generated outside the TPC active volume
149+
unsigned int mNSkippedPairs = 0; // Pairs dropped by the geometrical protection
150+
unsigned int mNSkippedCompton = 0; // Compton electrons dropped by the geometrical protection
140151
};
141152
#endif // GENERATORS_WITH_TPCLOOPERS
142153

Generators/include/Generators/TPCLoopersParam.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ struct GenTPCLoopersParam : public o2::conf::ConfigurableParamHelper<GenTPCLoope
4545
float multiplier[2] = {1., 1.}; // multiplier for pairs and compton loopers for Poissonian and Gaussian sampling
4646
unsigned int fixedNLoopers[2] = {1, 1}; // fixed number of loopers coming from pairs and compton electrons - valid if flat gas is false and both Poisson and Gaussian params files are empty
4747
float adjust_flatgas = 0.f; // adjustment for the number of flat gas loopers per orbit (in percentage, e.g. -0.1 = -10%) [-1, inf)]
48+
bool geomProtection = true; // skip loopers generated outside the TPC active volume
4849
O2ParamDef(GenTPCLoopersParam, "GenTPCLoopers");
4950
};
5051

Generators/src/Generator.cxx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,7 @@ bool Generator::initTPCLoopersGen()
195195
try {
196196
// Create the TPC loopers generator with the provided parameters
197197
mTPCLoopersGen = new o2::eventgen::GenTPCLoopers(model_pairs, model_compton, poisson, gauss, scaler_pair, scaler_compton);
198+
mTPCLoopersGen->setGeomProtection(loopersParam.geomProtection);
198199
const auto& intrate = loopersParam.intrate;
199200
// Configure the generator with flat gas loopers defined per orbit with clusters/track info
200201
// If intrate is negative (default), automatic IR from collisioncontext.root will be used
@@ -260,6 +261,10 @@ Bool_t
260261
mParticles.insert(mParticles.end(), looperParticles.begin(), looperParticles.end());
261262

262263
LOG(debug) << "Added " << looperParticles.size() << " looper particles";
264+
const auto skippedLoopers = mTPCLoopersGen->getNSkipped();
265+
if (skippedLoopers > 0) {
266+
LOG(debug) << "Geometrical protection skipped " << skippedLoopers << " loopers outside the TPC active volume";
267+
}
263268
}
264269
#endif
265270
return kTRUE;

Generators/src/TPCLoopers.cxx

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,40 @@ namespace o2
126126
namespace eventgen
127127
{
128128

129+
namespace
130+
{
131+
// Radial limits of the region from which a looper can still reach the TPC
132+
// sensitive gas. The field cage positions are those used by the
133+
// "ExcludeFCGap" selection in o2::tpc::Detector::ProcessHits()
134+
// A looper can enter the sensitive gas from just outside it, so an additional margin is set
135+
// with a factor two over the largest radial excursion which was observed in validation (~4.2 cm).
136+
//
137+
// No cut is applied on z because loopers spiral the field lines and a vertex as far as |z| = 283 cm
138+
// feeds hits into the gas. A cut here would discard loopers that produce TPC signals.
139+
constexpr double kFcLxIn = 82.428409; // cm, inner field cage strips
140+
constexpr double kRodROut = 254.25 + 2.2; // cm, outer field cage rods plus their radial size
141+
constexpr double kLooperRadialReach = 10.; // cm, margin for the helix sweep
142+
constexpr double kTPCActiveRMin = kFcLxIn - kLooperRadialReach;
143+
constexpr double kTPCActiveRMax = kRodROut + kLooperRadialReach;
144+
} // namespace
145+
146+
bool GenTPCLoopers::isInTPCActiveVolume(double vx, double vy) const
147+
{
148+
const double vt = std::sqrt(vx * vx + vy * vy);
149+
return (vt >= kTPCActiveRMin && vt <= kTPCActiveRMax);
150+
}
151+
152+
void GenTPCLoopers::setGeomProtection(bool protect)
153+
{
154+
mGeomProtection = protect;
155+
if (mGeomProtection) {
156+
LOG(debug) << "TPC loopers geometrical protection: ON (accepting vertices with "
157+
<< kTPCActiveRMin << " <= Vt <= " << kTPCActiveRMax << " cm)";
158+
} else {
159+
LOG(warning) << "TPC loopers geometrical protection: OFF - loopers will be generated outside the TPC active volume as well.";
160+
}
161+
}
162+
129163
GenTPCLoopers::GenTPCLoopers(std::string model_pairs, std::string model_compton,
130164
std::string poisson, std::string gauss, std::string scaler_pair,
131165
std::string scaler_compton)
@@ -267,11 +301,20 @@ std::vector<TParticle> GenTPCLoopers::importParticles()
267301
std::vector<TParticle> particles;
268302
const double mass_e = TDatabasePDG::Instance()->GetParticle(11)->Mass();
269303
const double mass_p = TDatabasePDG::Instance()->GetParticle(-11)->Mass();
304+
mNSkippedPairs = 0;
305+
mNSkippedCompton = 0;
270306
// Get looper pairs from the event
271307
for (auto& pair : mGenPairs) {
272308
double px_e, py_e, pz_e, px_p, py_p, pz_p;
273309
double vx, vy, vz, time;
274310
double e_etot, p_etot;
311+
// The generative model is not currently fully constrained to the TPC geometry, so it places
312+
// significant fraction of the vertices outside the drift gas.
313+
// These are now dropped before they reach the transport.
314+
if (mGeomProtection && !isInTPCActiveVolume(pair[6], pair[7])) {
315+
mNSkippedPairs++;
316+
continue;
317+
}
275318
px_e = pair[0];
276319
py_e = pair[1];
277320
pz_e = pair[2];
@@ -301,6 +344,10 @@ std::vector<TParticle> GenTPCLoopers::importParticles()
301344
double px, py, pz;
302345
double vx, vy, vz, time;
303346
double etot;
347+
if (mGeomProtection && !isInTPCActiveVolume(compton[3], compton[4])) {
348+
mNSkippedCompton++;
349+
continue;
350+
}
304351
px = compton[0];
305352
py = compton[1];
306353
pz = compton[2];

0 commit comments

Comments
 (0)