ATLAS Offline Software
Loading...
Searching...
No Matches
AsgElectronIsEMSelector.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
3*/
4
5// Dear emacs, this is -*-c++-*-
6
17
25#include "TEnv.h"
27#include "xAODEgamma/Electron.h"
28#include "xAODEgamma/Photon.h"
30#include <cstdint>
31
32//=============================================================================
33// Standard constructor
34//=============================================================================
35AsgElectronIsEMSelector::AsgElectronIsEMSelector(const std::string& myname)
36 : AsgTool(myname)
37 , m_configFile("")
38 , m_rootTool(nullptr)
39 , m_useF3core(false)
40{
41
42 m_rootTool = new Root::TElectronIsEMSelector(myname.c_str());
43
44 declareProperty("WorkingPoint", m_WorkingPoint = "", "The Working Point");
45 declareProperty("ConfigFile",
46 m_configFile = "",
47 "The config file to use (if not setting cuts one by one)");
48
49 // Name of the quality to use
50 declareProperty(
51 "isEMMask",
52 m_rootTool->m_isEMMask =
53 egammaPID::EgPidUndefined, // All pass by default, if not specified
54 "The mask to use");
55
56 declareProperty("useF3core", m_useF3core = false, "Cut on f3 or f3core?");
57
58 // for the trigger needs:
59 declareProperty("caloOnly",
60 m_caloOnly = false,
61 "Flag to tell the tool if its a calo only cutbase");
62 declareProperty("trigEtTh", m_trigEtTh = -999., "Trigger threshold");
63}
64
65//=============================================================================
66// Standard destructor
67//=============================================================================
72
73StatusCode
75{
76 // The standard status code
77 StatusCode sc = StatusCode::SUCCESS;
78
79 if (!m_WorkingPoint.empty()) {
82 }
83
84 // find the file and read it in
85 std::string filename = PathResolverFindCalibFile(m_configFile);
86 if (filename.empty()) {
87 ATH_MSG_ERROR("Could not locate " << m_configFile);
88 sc = StatusCode::FAILURE;
89 return sc;
90 }
91 TEnv env;
92 env.ReadFile(filename.c_str(), kEnvLocal);
93
95
96 // Override the mask via the config only if it is not set
97 if (m_rootTool->m_isEMMask == egammaPID::EgPidUndefined) {
98 int default_mask = static_cast<int>(egammaPID::EgPidUndefined);
99 int mask(env.GetValue("isEMMask", default_mask));
100 m_rootTool->m_isEMMask = static_cast<unsigned int>(mask);
101 }
102 //
103 // From here on the conf ovverides all other properties
104 bool useTRTOutliers(env.GetValue("useTRTOutliers", true));
105 m_rootTool->m_useTRTOutliers = useTRTOutliers;
106 bool useTRTXenonHits(env.GetValue(" useTRTXenonHits", false));
107 m_rootTool->m_useTRTXenonHits = useTRTXenonHits;
108
110 m_rootTool->m_cutBinEta = AsgConfigHelper::HelperFloat("CutBinEta", env);
111 m_rootTool->m_cutBinET = AsgConfigHelper::HelperFloat("CutBinET", env);
112 m_rootTool->m_cutF1 = AsgConfigHelper::HelperFloat("CutF1", env);
113 m_rootTool->m_cutHadLeakage =
114 AsgConfigHelper::HelperFloat("CutHadLeakage", env);
115 m_rootTool->m_cutReta37 = AsgConfigHelper::HelperFloat("CutReta37", env);
116 m_rootTool->m_cutRphi33 = AsgConfigHelper::HelperFloat("CutRphi33", env);
117 m_rootTool->m_cutWeta2c = AsgConfigHelper::HelperFloat("CutWeta2c", env);
118 m_rootTool->m_cutDeltaEmax2 =
119 AsgConfigHelper::HelperFloat("CutDeltaEmax2", env);
120 m_rootTool->m_cutDeltaE = AsgConfigHelper::HelperFloat("CutDeltaE", env);
121 m_rootTool->m_cutDEmaxs1 = AsgConfigHelper::HelperFloat("CutDEmaxs1", env);
122 m_rootTool->m_cutDeltaE = AsgConfigHelper::HelperFloat("CutDeltaE", env);
123 m_rootTool->m_cutWtot = AsgConfigHelper::HelperFloat("CutWtot", env);
124 m_rootTool->m_cutWeta1c = AsgConfigHelper::HelperFloat("CutWeta1c", env);
125 m_rootTool->m_cutFracm = AsgConfigHelper::HelperFloat("CutFracm", env);
126 m_rootTool->m_cutF3 = AsgConfigHelper::HelperFloat("CutF3", env);
127 m_rootTool->m_cutBL = AsgConfigHelper::HelperInt("CutBL", env);
128 m_rootTool->m_cutPi = AsgConfigHelper::HelperInt("CutPi", env);
129 m_rootTool->m_cutSi = AsgConfigHelper::HelperInt("CutSi", env);
130 m_rootTool->m_cutA0 = AsgConfigHelper::HelperFloat("CutA0", env);
131 m_rootTool->m_cutA0Tight = AsgConfigHelper::HelperFloat("CutA0Tight", env);
132 m_rootTool->m_cutDeltaEta = AsgConfigHelper::HelperFloat("CutDeltaEta", env);
133 m_rootTool->m_cutDeltaEtaTight =
134 AsgConfigHelper::HelperFloat("CutDeltaEtaTight", env);
135 m_rootTool->m_cutminDeltaPhi =
136 AsgConfigHelper::HelperFloat("CutminDeltaPhi", env);
137 m_rootTool->m_cutmaxDeltaPhi =
138 AsgConfigHelper::HelperFloat("CutmaxDeltaPhi", env);
139 m_rootTool->m_cutminEp = AsgConfigHelper::HelperFloat("CutminEp", env);
140 m_rootTool->m_cutmaxEp = AsgConfigHelper::HelperFloat("CutmaxEp", env);
141 m_rootTool->m_cutBinEta_TRT =
142 AsgConfigHelper::HelperFloat("CutBinEta_TRT", env);
143 m_rootTool->m_cutBinET_TRT =
144 AsgConfigHelper::HelperFloat("CutBinET_TRT", env);
145 m_rootTool->m_cutNumTRT = AsgConfigHelper::HelperFloat("CutNumTRT", env);
146 m_rootTool->m_cutTRTRatio = AsgConfigHelper::HelperFloat("CutTRTRatio", env);
147 m_rootTool->m_cutTRTRatio90 =
148 AsgConfigHelper::HelperFloat("CutTRTRatio90", env);
149 m_rootTool->m_cutEProbabilityHT =
150 AsgConfigHelper::HelperFloat("CutEProbabilityHT", env);
151
152 ATH_MSG_INFO("operating point : " << this->getOperatingPointName()
153 << " with mask: "
154 << m_rootTool->m_isEMMask);
155
156 // Get the message level and set the underlying ROOT tool message level
157 // accordingly
158 m_rootTool->msg().setLevel(this->msg().level());
159
160 // We need to initialize the underlying ROOT TSelectorTool
161 if (m_rootTool->initialize().isFailure()) {
162 ATH_MSG_ERROR("Could not initialize the TElectronIsEMSelector!");
163 sc = StatusCode::FAILURE;
164 return sc;
165 }
166
167 return sc;
168}
169
170//=============================================================================
171// return the accept info object
172//=============================================================================
173
174const asg::AcceptInfo&
176{
177 return m_rootTool->getAcceptInfo();
178}
179
180//=============================================================================
181// The main accept method: the actual cuts are applied here
182//=============================================================================
185{
186 return accept(Gaudi::Hive::currentContext(), part);
187}
188
190AsgElectronIsEMSelector::accept(const EventContext& ctx,
191 const xAOD::IParticle* part) const
192{
193
194 if (part->type() == xAOD::Type::Electron ||
195 part->type() == xAOD::Type::Photon) {
196 return accept(ctx, static_cast<const xAOD::Egamma*>(part));
197 }
198
200 "AsgElectronIsEMSelector::could not convert argument to Electron/Photon");
201 return m_rootTool->accept();
202}
203
205AsgElectronIsEMSelector::accept(const EventContext& ctx,
206 const xAOD::Egamma* eg) const
207{
208
209 if (eg) {
210 unsigned int isEM = ~0;
211 StatusCode sc = execute(ctx, eg, isEM);
212 if (sc.isFailure()) {
213 ATH_MSG_ERROR("could not calculate isEM");
214 return m_rootTool->accept();
215 }
216 return m_rootTool->fillAccept(isEM);
217 }
218
219 ATH_MSG_ERROR("AsgElectronIsEMSelector::accept was given a bad argument");
220 return m_rootTool->accept();
221}
222
224AsgElectronIsEMSelector::accept(const EventContext& ctx,
225 const xAOD::Electron* el) const
226{
227 return accept(ctx, static_cast<const xAOD::Egamma*>(el));
228}
229
231AsgElectronIsEMSelector::accept(const EventContext& ctx,
232 const xAOD::Photon* ph) const
233{
234 return accept(ctx, static_cast<const xAOD::Egamma*>(ph));
235}
236
237//=============================================================================
239//=============================================================================
240std::string
242{
243
244 if (!m_WorkingPoint.empty()) {
245 return m_WorkingPoint;
246 }
247 if (m_rootTool->m_isEMMask == egammaPID::ElectronLoosePP) {
248 return "Loose";
249 }
250 if (m_rootTool->m_isEMMask == egammaPID::ElectronMediumPP) {
251 return "Medium";
252 }
253 if (m_rootTool->m_isEMMask == egammaPID::ElectronTightPP) {
254 return "Tight";
255 }
256 if (m_rootTool->m_isEMMask == egammaPID::ElectronLoose1) {
257 return "Loose1";
258 }
259 if (m_rootTool->m_isEMMask == egammaPID::ElectronMedium1) {
260 return "Medium1";
261 }
262 if (m_rootTool->m_isEMMask == egammaPID::ElectronTight1) {
263 return "Tight1";
264 }
265 if (m_rootTool->m_isEMMask == egammaPID::ElectronLooseHLT) {
266 return "LooseHLT";
267 }
268 if (m_rootTool->m_isEMMask == egammaPID::ElectronMediumHLT) {
269 return "MediumHLT";
270 }
271 if (m_rootTool->m_isEMMask == egammaPID::ElectronTightHLT) {
272 return "TightHLT";
273 }
274 if (m_rootTool->m_isEMMask == 0) {
275 return "0 No cuts applied";
276 }
277
278 ATH_MSG_INFO("Didn't recognize the given operating point with mask: "
279 << m_rootTool->m_isEMMask);
280 return "";
281}
282
283// ==============================================================
284StatusCode
285AsgElectronIsEMSelector::execute(const EventContext& ctx,
286 const xAOD::Egamma* eg,
287 unsigned int& isEM) const
288{
289 //
290 // Particle identification for electrons based on cuts
291 //
292 (void)ctx;
293 // initialisation
294 isEM = 0;
295 // protection against null pointer
296 if (eg == nullptr) {
297 // if object is bad then use the bit for "bad eta"
298 ATH_MSG_ERROR("exiting because el is NULL");
300 return StatusCode::SUCCESS;
301 }
302 // retrieve associated cluster
303 const xAOD::CaloCluster* cluster = eg->caloCluster();
304 if (cluster == nullptr) {
305 // if object is bad then use the bit for "bad eta"
306 ATH_MSG_ERROR("exiting because cluster is NULL");
308 return StatusCode::SUCCESS;
309 }
310 // eta position in second sampling
311 const float eta2 = fabsf(cluster->etaBE(2));
312 // energy in calorimeter
313 const double energy = cluster->e();
314 // transverse energy of the electron (using the track eta)
315 // const double et = el->pt();
316 double et = (cosh(eta2) != 0.) ? energy / cosh(eta2) : 0.;
317 ;
318
319 // see if we have an electron, with track, for eta
320 const xAOD::Electron* el = nullptr;
321 if (eg->type() == xAOD::Type::Electron) {
322 el = static_cast<const xAOD::Electron*>(eg);
323 }
324 if (el && el->trackParticle() && !m_caloOnly) {
325 et = (cosh(el->trackParticle()->eta()) != 0.)
326 ? energy / cosh(el->trackParticle()->eta())
327 : 0.;
328 }
329
330 // Call the calocuts using the egamma object
331 isEM = calocuts_electrons(eg, eta2, et, m_trigEtTh, 0);
332
333 // Call the calo cuts using the el , if available and we want to apply them
334 if (el && el->trackParticle() && !m_caloOnly) {
335 isEM = TrackCut(el, eta2, et, energy, isEM);
336 }
337
338 return StatusCode::SUCCESS;
339}
340
341// ======================================================================
342unsigned int
344 float eta2,
345 double et,
346 double trigEtTh,
347 unsigned int iflag) const
348{
349
350 //
351 // apply cut-based selection based on calo information
352 // eg : xAOD::Electron object
353 // trigETthr : threshold in ET to apply the cuts at trigger level
354 // iflag: the starting isEM
355 //
356
357 float Reta(0);
358 float Rphi(0);
359 float Rhad1(0);
360 float Rhad(0);
361 float e277(0);
362 float weta1c(0);
363 float weta2c(0);
364 float f1(0);
365 float emax2(0);
366 float Eratio(0);
367 float DeltaE(0);
368 float wtot(0);
369 float fracm(0);
370 float f3(0);
371
372 bool allFound = true;
373 // Reta
374 allFound =
375 allFound && eg->showerShapeValue(Reta, xAOD::EgammaParameters::Reta);
376 // Rphi
377 allFound =
378 allFound && eg->showerShapeValue(Rphi, xAOD::EgammaParameters::Rphi);
379 // transverse energy in 1st scintillator of hadronic calorimeter
380 allFound =
381 allFound && eg->showerShapeValue(Rhad1, xAOD::EgammaParameters::Rhad1);
382 // transverse energy in hadronic calorimeter
383 allFound =
384 allFound && eg->showerShapeValue(Rhad, xAOD::EgammaParameters::Rhad);
385 // E(7*7) in 2nd sampling
386 allFound =
387 allFound && eg->showerShapeValue(e277, xAOD::EgammaParameters::e277);
388 // shower width in 3 strips in 1st sampling
389 allFound =
390 allFound && eg->showerShapeValue(weta1c, xAOD::EgammaParameters::weta1);
391 // shower width in 2nd sampling
392 allFound =
393 allFound && eg->showerShapeValue(weta2c, xAOD::EgammaParameters::weta2);
394 // fraction of energy reconstructed in the 1st sampling
395 allFound = allFound && eg->showerShapeValue(f1, xAOD::EgammaParameters::f1);
396 // E of 2nd max between max and min in strips
397 allFound =
398 allFound && eg->showerShapeValue(Eratio, xAOD::EgammaParameters::Eratio);
399 // E of 1st max in strips
400 allFound =
401 allFound && eg->showerShapeValue(DeltaE, xAOD::EgammaParameters::DeltaE);
402 // total shower width in 1st sampling
403 allFound =
404 allFound && eg->showerShapeValue(wtot, xAOD::EgammaParameters::wtots1);
405 // E(+/-3)-E(+/-1)/E(+/-1)
406 allFound =
407 allFound && eg->showerShapeValue(fracm, xAOD::EgammaParameters::fracs1);
408
409 if (m_useF3core) {
410 allFound =
411 allFound && eg->showerShapeValue(f3, xAOD::EgammaParameters::f3core);
412 } else {
413 allFound = allFound && eg->showerShapeValue(f3, xAOD::EgammaParameters::f3);
414 }
415
416 if (!allFound) {
417 // if object is bad then use the bit for "bad eta"
418 ATH_MSG_WARNING("Have some variables missing.");
420 return iflag;
421 }
422
423 // For cut-based triggers above 20 GeV threshold, the online cut values on the
424 // discriminant variables are always taken from the 20 GeV optimisation.
425 // if(et > 20000 ) { if(trigEtTh > 0) et = trigEtTh*1.01; }
426
427 return m_rootTool->calocuts_electrons(eta2,
428 et,
429 Reta, // replacing e233
430 Rphi, // replacing e237,
431 Rhad1, // replacing ethad1,
432 Rhad, // replacing ethad,
433 e277,
434 weta1c,
435 weta2c,
436 f1,
437 emax2, // emax2
438 Eratio, // emax
439 DeltaE, // emin,
440 wtot,
441 fracm,
442 f3,
443 iflag,
444 trigEtTh);
445}
446
447//================================================================
448unsigned int
450 float eta2,
451 double et,
452 double energy,
453 unsigned int iflag) const
454{
455 // apply track cuts for electron identification
456 // - Track quality cuts
457 // - (eta,phi) and E/p matching between ID and ECAL
458 // - use of TRT
459 // eg : egamma object
460 // iflag: the starting isEM to use
461 //
462 // retrieve associated track
463 const xAOD::TrackParticle* t = eg->trackParticle();
464
465 // protection against bad pointers
466 if (t == nullptr) {
467 ATH_MSG_ERROR("Something is bad with the variables as passed");
468 // if object is bad then use the bit for "bad eta"
470 return iflag;
471 }
472
473 // Track quality cuts
474 uint8_t nSiHitsPlusDeadSensors =
476 uint8_t nPixHitsPlusDeadSensors =
478 bool passBLayerRequirement =
480
481 // TRT information
482 uint8_t nTRThigh = 0;
483 uint8_t nTRThighOutliers = 0;
484 uint8_t nTRT = 0;
485 uint8_t nTRTOutliers = 0;
486 uint8_t nTRTXenonHits = 0;
487 float TRT_PID = 0.0;
488
489 bool allFound = true;
490
491 allFound =
492 allFound && t->summaryValue(nTRThigh, xAOD::numberOfTRTHighThresholdHits);
493 allFound =
494 allFound &&
495 t->summaryValue(nTRThighOutliers, xAOD::numberOfTRTHighThresholdOutliers);
496 allFound = allFound && t->summaryValue(nTRT, xAOD::numberOfTRTHits);
497 allFound =
498 allFound && t->summaryValue(nTRTOutliers, xAOD::numberOfTRTOutliers);
499 allFound =
500 allFound && t->summaryValue(nTRTXenonHits, xAOD::numberOfTRTXenonHits);
501 allFound = allFound && t->summaryValue(TRT_PID, xAOD::eProbabilityHT);
502
503 const float trackd0 = fabsf(t->d0());
504
505 // Delta eta,phi matching
506 float deltaeta;
507 float deltaphi;
508
509 allFound = allFound && eg->trackCaloMatchValue(
511 allFound = allFound && eg->trackCaloMatchValue(
513
514 // E/p
515 const double ep = energy * fabs(t->qOverP());
516
517 if (!allFound) {
518 // if object is bad then use the bit for "bad eta"
519 ATH_MSG_WARNING("Have some variables missing.");
521 return iflag;
522 }
523
524 return m_rootTool->TrackCut(eta2,
525 et,
526 passBLayerRequirement,
527 nPixHitsPlusDeadSensors,
528 nSiHitsPlusDeadSensors,
529 nTRThigh,
530 nTRThighOutliers,
531 nTRT,
532 nTRTOutliers,
533 nTRTXenonHits,
534 TRT_PID,
535 trackd0,
536 deltaeta,
537 deltaphi,
538 ep,
539 iflag);
540}
#define ATH_MSG_ERROR(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_WARNING(x)
static Double_t sc
std::string PathResolverFindCalibFile(const std::string &logical_file_name)
Root::TElectronIsEMSelector * m_rootTool
Pointer to the underlying ROOT based tool.
bool m_caloOnly
Flag for calo only cut-base.
std::string m_WorkingPoint
Working Point.
virtual StatusCode execute(const EventContext &ctx, const xAOD::Egamma *eg, unsigned int &isEM) const override final
Add a legacy execute method - return isEM value.
virtual asg::AcceptData accept(const xAOD::IParticle *part) const override final
Accept with generic interface.
unsigned int calocuts_electrons(const xAOD::Egamma *eg, float eta2, double et, double trigEtTh, unsigned int iflag) const
virtual StatusCode initialize() override
Gaudi Service Interface method implementations.
bool m_useF3core
use f3core or f3 (default: use f3)
virtual std::string getOperatingPointName() const override final
Method to get the operating point.
unsigned int TrackCut(const xAOD::Electron *eg, float eta2, double et, double energy, unsigned int iflag) const
virtual ASG_TOOL_CLASS3(AsgElectronIsEMSelector, IAsgElectronIsEMSelector, IAsgEGammaIsEMSelector, IAsgSelectionTool) public ~AsgElectronIsEMSelector()
Standard constructor.
std::string m_configFile
Config File.
virtual const asg::AcceptInfo & getAcceptInfo() const override final
Method to get the plain AcceptInfo.
virtual double e() const
The total energy of the particle.
float etaBE(const unsigned layer) const
Get the eta in one layer of the EM Calo.
Class providing the definition of the 4-vector interface.
std::vector< int > HelperInt(const std::string &input, TEnv &env)
std::string findConfigFile(const std::string &input, const std::map< std::string, std::string > &configmap)
std::vector< float > HelperFloat(const std::string &input, TEnv &env)
const std::map< std::string, std::string > ElectronCutPointToConfFile
std::size_t numberOfPixelHitsAndDeadSensors(const xAOD::TrackParticle &tp)
return the number of Pixel hits plus dead sensors in the track particle
bool passBLayerRequirement(const xAOD::TrackParticle &tp)
return true if effective number of BL hits + outliers is at least one
std::size_t numberOfSiliconHitsAndDeadSensors(const xAOD::TrackParticle &tp)
return the number of Silicon hits plus dead sensors in the track particle
const unsigned int ElectronMediumHLT
Medium 2014 tunes electron selecton.
const unsigned int ElectronLoose1
Electron trigger PID definitions.
const unsigned int ElectronTightHLT
Tight 2014 tunes electron selecton.
const unsigned int ElectronLooseHLT
Loose 2014 tunes electron selection.
const unsigned int ElectronTightPP
Tight++ electron selecton.
const unsigned int ElectronTight1
Tight1 tunes electron selecton.
const unsigned int ElectronMediumPP
Medium++ electron selecton.
const unsigned int ElectronLoosePP
Loose++ electron selection.
const unsigned int ElectronMedium1
Medium1 tunes electron selecton.
@ ClusterEtaRange_Electron
cluster eta range
const unsigned int EgPidUndefined
@ Photon
The object is a photon.
Definition ObjectType.h:47
@ Electron
The object is an electron.
Definition ObjectType.h:46
@ deltaPhi2
difference between the cluster phi (second sampling) and the phi of the track extrapolated to the sec...
@ deltaEta1
difference between the cluster eta (first sampling) and the eta of the track extrapolated to the firs...
@ wtots1
shower width is determined in a window detaxdphi = 0,0625 ×~0,2, corresponding typically to 20 strips...
@ f3core
E3(3x3)/E fraction of the energy reconstructed in the third compartment of the electromagnetic calori...
Definition EgammaEnums.h:66
@ e277
uncalibrated energy (sum of cells) of the middle sampling in a rectangle of size 7x7
Definition EgammaEnums.h:81
@ f3
fraction of energy reconstructed in 3rd sampling
Definition EgammaEnums.h:55
@ f1
E1/E = fraction of energy reconstructed in the first sampling, where E1 is energy in all strips belon...
Definition EgammaEnums.h:53
@ Eratio
(emaxs1-e2tsts1)/(emaxs1+e2tsts1)
@ DeltaE
e2tsts1-emins1
@ fracs1
shower shape in the shower core : [E(+/-3)-E(+/-1)]/E(+/-1), where E(+/-n) is the energy in ± n strip...
@ weta2
the lateral width is calculated with a window of 3x5 cells using the energy weighted sum over all cel...
@ weta1
shower width using +/-3 strips around the one with the maximal energy deposit: w3 strips = sqrt{sum(E...
Definition EgammaEnums.h:98
CaloCluster_v1 CaloCluster
Define the latest version of the calorimeter cluster class.
TrackParticle_v1 TrackParticle
Reference the current persistent version:
Egamma_v1 Egamma
Definition of the current "egamma version".
Definition Egamma.h:17
Photon_v1 Photon
Definition of the current "egamma version".
@ numberOfTRTHighThresholdOutliers
number of TRT high threshold outliers (only xenon counted) [unit8_t].
@ numberOfTRTXenonHits
number of TRT hits on track in straws with xenon [unit8_t].
@ numberOfTRTHits
number of TRT hits [unit8_t].
@ eProbabilityHT
Electron probability from High Threshold (HT) information [float].
@ numberOfTRTHighThresholdHits
number of TRT hits which pass the high threshold (only xenon counted) [unit8_t].
@ numberOfTRTOutliers
number of TRT outliers [unit8_t].
Electron_v1 Electron
Definition of the current "egamma version".
Extra patterns decribing particle interation process.
MsgStream & msg
Definition testRead.cxx:32