KaliVeda
Toolkit for HIC analysis
KVDetectionSimulator.cpp
1 //Created by KVClassFactory on Sat Oct 10 09:37:42 2015
2 //Author: John Frankland,,,
3 
4 #include "KVDetectionSimulator.h"
5 #include "KVGeoNavigator.h"
6 
8 
9 
10 
16  KVBase(Form("DetectionSimulator_%s", a->GetName()),
17  Form("Simulate detection of particles or events in detector array %s", a->GetTitle())),
18  fArray(a), fCalcTargELoss(kTRUE)
19 {
20  // Initialise a detection simulator
21  // The detector array is put into simulation mode, and the minimum cut-off energy
22  // for propagation of particles is set
23  a->Clear();
24  a->SetSimMode(kTRUE);
25  static_cast<KVRangeTableGeoNavigator*>(a->GetNavigator())->SetCutOffKEForPropagation(e_cut_off);
26 }
27 
28 
29 
63 
64 void KVDetectionSimulator::DetectEvent(KVEvent* event, const Char_t* detection_frame)
65 {
66  //Simulate detection of event by multidetector array.
67  //
68  // optional argument detection_frame(="" by default) can be used to give name of
69  // inertial reference frame (defined for all particles of 'event') to be used.
70  // e.g. if the simulated event's default reference frame is the centre of mass frame, before calling this method
71  // you should create the 'laboratory' or 'detector' frame with KVEvent::SetFrame(...), and then give the
72  // name of the 'LAB' or 'DET' frame as 3rd argument here.
73  //
74  //For each particle in the event we calculate first its energy loss in the target (if the target has been defined, see KVMultiDetArray::SetTarget).
75  //By default these energy losses are calculated from a point half-way along the beam-direction through the target (taking into account the orientation
76  //of the target), if you want random depths for each event call GetTarget()->SetRandomized() before using DetectEvent().
77  //
78  //If the particle escapes the target then we look for the group in the array that it will hit. If there is one, then the detection of this particle by the
79  //different members of the group is simulated.
80  //
81  //The detectors concerned have their fEloss members set to the energy lost by the particle when it crosses them.
82  //
83  //Give tags to the simulated particles via KVNucleus::AddGroup() method
84  //Two general tags :
85  // - DETECTED : cross at least one active layer of one detector
86  // - UNDETECTED : go through dead zone or stopped in target
87  //We add also different sub group :
88  // - For UNDETECTED particles : "DEAD ZONE", "STOPPED IN TARGET" and "THRESHOLD", the last one concerned particle
89  //go through the first detection stage of the multidetector array but stopped in an absorber (ie an inactive layer)
90  // - For DETECTED particles :
91  // "PUNCH THROUGH" corrresponds to particle which cross all the materials in front of it
92  // (high energy particle punh through), or which miss some detectors due to a non perfect
93  // overlap between defined telescope,
94  // "INCOMPLETE" corresponds to particles which stopped in the first detection stage of the multidetector
95  // in a detector which can not give alone a clear identification,
96  //
97 
98  // Reset detectors in array hit by any previous events
100 
101  for (auto& part : EventIterator(event)) {
102  // loop over particles
103 
104  KVNucleus* _part = (KVNucleus*)part.GetFrame(detection_frame, kFALSE);
105 
106  KVNameValueList det_stat, nvl;
107  Double_t eLostInTarget = 0;
108 
109  TVector3 initial_momentum = _part->GetMomentum();
110 
111  if (part.GetZ() == 0) {
112  det_stat.SetValue("UNDETECTED", "NEUTRON");
113 
114  part.AddGroup("UNDETECTED");
115  part.AddGroup("NEUTRON");
116  }
117  else if (_part->GetKE() < GetMinKECutOff()) {
118  det_stat.SetValue("UNDETECTED", "NO ENERGY");
119 
120  part.AddGroup("UNDETECTED");
121  part.AddGroup("NO ENERGY");
122  }
123  else {
124  if (IncludeTargetEnergyLoss() && GetTarget()) {
125 
127  //simulate passage through target material
128  Double_t ebef = _part->GetKE();
129  GetTarget()->DetectParticle(_part);
130  eLostInTarget = ebef - _part->GetKE();
131  if (_part->GetKE() < GetMinKECutOff()) {
132  det_stat.SetValue("UNDETECTED", "STOPPED IN TARGET");
133 
134  part.AddGroup("UNDETECTED");
135  part.AddGroup("STOPPED IN TARGET");
136  }
138  }
139 
140  if (_part->GetKE() > GetMinKECutOff()) {
141 
142  nvl = DetectParticle(_part);
143 
144  if (nvl.IsEmpty()) {
145 
146  det_stat.SetValue("UNDETECTED", "DEAD ZONE");
147 
148  part.AddGroup("UNDETECTED");
149  part.AddGroup("DEAD ZONE");
150 
151  }
152  else {
153  part.AddGroup("DETECTED");
154  }
155  }
156  }
157 
158  if (IncludeTargetEnergyLoss() && GetTarget()) part.SetParameter("TARGET Out", eLostInTarget);
159  if (!nvl.IsEmpty()) {
160  Int_t nbre_nvl = nvl.GetNpar();
161  KVString LastDet(nvl.GetNameAt(nbre_nvl - 1));
162  if (part.GetE() < GetMinKECutOff() || part.GetParameters()->HasParameter("DEADZONE")) {
163  part.SetParameter("STOPPING DETECTOR", LastDet.Data());
164  det_stat.SetValue("DETECTED", "OK");
165  }
166  else {
167  det_stat.SetValue("DETECTED", "PUNCHED THROUGH");
168  }
169  for (Int_t ii = 0; ii < nvl.GetNpar(); ++ii) {
170  part.SetParameter(nvl.GetNameAt(ii), nvl.GetDoubleValue(ii));
171  }
172  }
173  for (Int_t ii = 0; ii < det_stat.GetNpar(); ii += 1) {
174  part.SetParameter(det_stat.GetNameAt(ii), det_stat.GetStringValue(ii));
175  }
176 
177  _part->SetMomentum(initial_momentum);
178 
179  }
180 
181 }
182 
183 
184 
185 
196 
198 {
199  // Simulate detection of a single particle
200  //
201  // Propagate particle through the array,
202  // calculating its energy losses in all absorbers, and setting the
203  // energy loss members of the active detectors on the way.
204  //
205  // Returns a list containing the name and energy loss of each
206  // detector hit in array (list is empty if none i.e. particle
207  // in beam pipe or dead zone of the multidetector)
208 
210 
211  // particle missed all detectors
212  if (part->GetParameters()->IsEmpty()) return KVNameValueList();
213 
214  // list of energy losses in active layers of detectors
215  KVNameValueList NVL;
216 
217  // find detectors in array hit by particle
218  KVDetector* last_detector = nullptr;
219  TIter next(part->GetParameters()->GetList());
220  KVNamedParameter* param;
221  while ((param = (KVNamedParameter*)next())) {
222  KVString pname(param->GetName());
223  pname.Begin(":");
224  KVString pn2 = pname.Next();
225  KVString pn3 = pname.Next();
226  if (pn2 == "DE") {
227  pn3.Begin("/");
228  KVString det_name = pn3.Next();
229  if (pn3.End() || pn3.Next().BeginsWith("ACTIVE")) {
230  // energy loss in active layer of detector
231  KVDetector* curDet = last_detector = fArray->GetDetector(det_name);
232  if (!curDet) {
233  Error("DetectParticle",
234  "Cannot find detector %s corresponding to particle energy loss %s",
235  det_name.Data(), pname.Data());
236  }
237  else {
238  Double_t de = param->GetDouble();
239  NVL.SetValue(curDet->GetName(), de);
240  }
241  }
242  }
243  }
244 
245  // add hit group to list if not already in it
246  if (last_detector) fHitGroups.AddGroup(last_detector->GetGroup());
247 
248  return NVL;
249 }
250 
251 
252 
260 
262 {
263  // Given the name of a detector, simulate detection of a given particle
264  // by the complete corresponding group. The particle's theta and phi are set
265  // at random within the limits of detector entrance window
266  //
267  // Returns a list containing the name and energy loss of each
268  // detector hit in array
269 
270  KVDetector* kvd = GetArray()->GetDetector(detname);
271  if (kvd) {
272  kvp->SetMomentum(kvp->GetEnergy(), kvd->GetRandomDirection("random"));
273  return DetectParticle(kvp);
274  }
275  else {
276  Error("DetectParticleIn", "Detector %s not found", detname);
277  }
278  return KVNameValueList();
279 }
280 
281 
int Int_t
char Char_t
constexpr Bool_t kFALSE
double Double_t
constexpr Bool_t kTRUE
Class for iterating over nuclei in events accessed through base pointer/reference.
Base class for KaliVeda framework.
Definition: KVBase.h:142
Simulate detection of particles or events in a detector array.
KVMultiDetArray * GetArray() const
KVTarget * GetTarget() const
void DetectEvent(KVEvent *event, const Char_t *detection_frame="")
Double_t GetMinKECutOff() const
KVNameValueList DetectParticleIn(const Char_t *detname, KVNucleus *kvp)
Bool_t IncludeTargetEnergyLoss() const
KVNameValueList DetectParticle(KVNucleus *)
KVDetectorEvent fHitGroups
used to reset hit detectors in between events
KVMultiDetArray * fArray
array used for detection
void AddGroup(KVGroup *grp)
Base class for detector geometry description.
Definition: KVDetector.h:160
KVGroup * GetGroup() const
TVector3 GetRandomDirection(Option_t *t="isotropic")
Definition: KVDetector.h:720
Abstract base class container for multi-particle events.
Definition: KVEvent.h:67
virtual void PropagateParticle(KVNucleus *, TVector3 *TheOrigin=0)
KVDetector * GetDetector(const Char_t *name) const
Return detector in this structure with given name.
Base class for describing the geometry of a detector array.
KVGeoNavigator * GetNavigator() const
Handles lists of named parameters with different types, a list of KVNamedParameter objects.
Double_t GetDoubleValue(const Char_t *name) const
void SetValue(const Char_t *name, value_type value)
const Char_t * GetNameAt(Int_t idx) const
Int_t GetNpar() const
return the number of stored parameters
Bool_t IsEmpty() const
const Char_t * GetStringValue(const Char_t *name) const
KVHashList * GetList() const
A generic named parameter storing values of different types.
Double_t GetDouble() const
Description of properties and kinematics of atomic nuclei.
Definition: KVNucleus.h:126
TVector3 GetMomentum() const
Definition: KVParticle.h:604
KVNameValueList * GetParameters() const
Definition: KVParticle.h:815
Double_t GetEnergy() const
Definition: KVParticle.h:621
void SetMomentum(const TVector3 *v)
Definition: KVParticle.h:542
Double_t GetKE() const
Definition: KVParticle.h:614
KVParticle const * GetFrame(const Char_t *frame, Bool_t warn_and_return_null_if_unknown=kTRUE) const
Definition: KVParticle.cpp:865
Propagate particles through array geometry calculating energy losses.
Extension of ROOT TString class which allows backwards compatibility with ROOT v3....
Definition: KVString.h:73
void Begin(TString delim) const
Definition: KVString.cpp:565
Bool_t End() const
Definition: KVString.cpp:634
KVString Next(Bool_t strip_whitespace=kFALSE) const
Definition: KVString.cpp:695
virtual void DetectParticle(KVNucleus *, TVector3 *norm=0)
Definition: KVTarget.cpp:485
void SetOutgoing(Bool_t r=kTRUE)
Definition: KVTarget.h:237
const char * GetName() const override
virtual void Clear(Option_t *="")
virtual void Error(const char *method, const char *msgfmt,...) const
const char * Data() const
Bool_t BeginsWith(const char *s, ECaseCompare cmp=kExact) const
TArc a
ClassImp(TPyArg)