KaliVeda  1.12/06
Heavy-Ion Analysis Toolkit
KVDetectionSimulator.cpp
Go to the documentation of this file.
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  event->ResetGetNextParticle();
102  KVNucleus* part;
103  while ((part = event->GetNextParticle())) { // loop over particles
104 
105  KVNucleus* _part = (KVNucleus*)part->GetFrame(detection_frame, kFALSE);
106 
107  KVNameValueList det_stat, nvl;
108  Double_t eLostInTarget = 0;
109 
110  TVector3 initial_momentum = _part->GetMomentum();
111 
112  if (part->GetZ() == 0) {
113  det_stat.SetValue("UNDETECTED", "NEUTRON");
114 
115  part->AddGroup("UNDETECTED");
116  part->AddGroup("NEUTRON");
117  }
118  else if (_part->GetKE() < GetMinKECutOff()) {
119  det_stat.SetValue("UNDETECTED", "NO ENERGY");
120 
121  part->AddGroup("UNDETECTED");
122  part->AddGroup("NO ENERGY");
123  }
124  else {
125  if (IncludeTargetEnergyLoss() && GetTarget()) {
126 
128  //simulate passage through target material
129  Double_t ebef = _part->GetKE();
130  GetTarget()->DetectParticle(_part);
131  eLostInTarget = ebef - _part->GetKE();
132  if (_part->GetKE() < GetMinKECutOff()) {
133  det_stat.SetValue("UNDETECTED", "STOPPED IN TARGET");
134 
135  part->AddGroup("UNDETECTED");
136  part->AddGroup("STOPPED IN TARGET");
137  }
139  }
140 
141  if (_part->GetKE() > GetMinKECutOff()) {
142 
143  nvl = DetectParticle(_part);
144 
145  if (nvl.IsEmpty()) {
146 
147  det_stat.SetValue("UNDETECTED", "DEAD ZONE");
148 
149  part->AddGroup("UNDETECTED");
150  part->AddGroup("DEAD ZONE");
151 
152  }
153  else {
154  part->AddGroup("DETECTED");
155  }
156  }
157  }
158 
159  if (IncludeTargetEnergyLoss() && GetTarget()) part->SetParameter("TARGET Out", eLostInTarget);
160  if (!nvl.IsEmpty()) {
161  Int_t nbre_nvl = nvl.GetNpar();
162  KVString LastDet(nvl.GetNameAt(nbre_nvl - 1));
163  if (part->GetE() < GetMinKECutOff() || part->GetParameters()->HasParameter("DEADZONE")) {
164  part->SetParameter("STOPPING DETECTOR", LastDet.Data());
165  det_stat.SetValue("DETECTED", "OK");
166  }
167  else {
168  det_stat.SetValue("DETECTED", "PUNCHED THROUGH");
169  }
170  for (Int_t ii = 0; ii < nvl.GetNpar(); ++ii) {
171  part->SetParameter(nvl.GetNameAt(ii), nvl.GetDoubleValue(ii));
172  }
173  }
174  for (Int_t ii = 0; ii < det_stat.GetNpar(); ii += 1) {
175  part->SetParameter(det_stat.GetNameAt(ii), det_stat.GetStringValue(ii));
176  }
177 
178  _part->SetMomentum(initial_momentum);
179 
180  }
181 
182 }
183 
184 
185 
186 
197 
199 {
200  // Simulate detection of a single particle
201  //
202  // Propagate particle through the array,
203  // calculating its energy losses in all absorbers, and setting the
204  // energy loss members of the active detectors on the way.
205  //
206  // Returns a list containing the name and energy loss of each
207  // detector hit in array (list is empty if none i.e. particle
208  // in beam pipe or dead zone of the multidetector)
209 
211 
212  // particle missed all detectors
213  if (part->GetParameters()->IsEmpty()) return KVNameValueList();
214 
215  // list of energy losses in active layers of detectors
216  KVNameValueList NVL;
217 
218  // find detectors in array hit by particle
219  KVDetector* last_detector = nullptr;
220  TIter next(part->GetParameters()->GetList());
221  KVNamedParameter* param;
222  while ((param = (KVNamedParameter*)next())) {
223  KVString pname(param->GetName());
224  pname.Begin(":");
225  KVString pn2 = pname.Next();
226  KVString pn3 = pname.Next();
227  if (pn2 == "DE") {
228  pn3.Begin("/");
229  KVString det_name = pn3.Next();
230  if (pn3.End() || pn3.Next().BeginsWith("ACTIVE")) {
231  // energy loss in active layer of detector
232  KVDetector* curDet = last_detector = fArray->GetDetector(det_name);
233  if (!curDet) {
234  Error("DetectParticle",
235  "Cannot find detector %s corresponding to particle energy loss %s",
236  det_name.Data(), pname.Data());
237  }
238  else {
239  Double_t de = param->GetDouble();
240  NVL.SetValue(curDet->GetName(), de);
241  }
242  }
243  }
244  }
245 
246  // add hit group to list if not already in it
247  if (last_detector) fHitGroups.AddGroup(last_detector->GetGroup());
248 
249  return NVL;
250 }
251 
252 
253 
261 
263 {
264  // Given the name of a detector, simulate detection of a given particle
265  // by the complete corresponding group. The particle's theta and phi are set
266  // at random within the limits of detector entrance window
267  //
268  // Returns a list containing the name and energy loss of each
269  // detector hit in array
270 
271  KVDetector* kvd = GetArray()->GetDetector(detname);
272  if (kvd) {
273  kvp->SetMomentum(kvp->GetEnergy(), kvd->GetRandomDirection("random"));
274  return DetectParticle(kvp);
275  }
276  else {
277  Error("DetectParticleIn", "Detector %s not found", detname);
278  }
279  return KVNameValueList();
280 }
281 
282 
int Int_t
ClassImp(KVPartitionList) void KVPartitionList
Initialisation.
char Char_t
const Bool_t kFALSE
double Double_t
const Bool_t kTRUE
Base class for KaliVeda framework.
Definition: KVBase.h:135
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
Base class for detector geometry description, interface to energy-loss calculations.
Definition: KVDetector.h:121
KVGroup * GetGroup() const
TVector3 GetRandomDirection(Option_t *t="isotropic")
Definition: KVDetector.h:666
Base class container for multi-particle events.
Definition: KVEvent.h:176
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
Bool_t HasParameter(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:125
Int_t GetZ() const
Return the number of proton / atomic number.
Definition: KVNucleus.cpp:770
void AddGroup(const Char_t *groupname, const Char_t *from="")
Definition: KVParticle.cpp:485
TVector3 GetMomentum() const
Definition: KVParticle.h:565
KVNameValueList * GetParameters() const
Definition: KVParticle.h:735
void SetMomentum(const TVector3 &v)
Definition: KVParticle.h:535
Double_t GetEnergy() const
Definition: KVParticle.h:582
Double_t GetE() const
Definition: KVParticle.h:613
void SetParameter(const Char_t *name, ValType value) const
Definition: KVParticle.h:739
Double_t GetKE() const
Definition: KVParticle.h:575
KVParticle const * GetFrame(const Char_t *frame, Bool_t warn_and_return_null_if_unknown=kTRUE) const
Definition: KVParticle.cpp:952
Propagate particles through array geometry calculating energy losses.
Extension of ROOT TString class which allows backwards compatibility with ROOT v3....
Definition: KVString.h:72
void Begin(TString delim) const
Definition: KVString.cpp:562
Bool_t End() const
Definition: KVString.cpp:625
KVString Next(Bool_t strip_whitespace=kFALSE) const
Definition: KVString.cpp:675
virtual void DetectParticle(KVNucleus *, TVector3 *norm=0)
Definition: KVTarget.cpp:485
void SetOutgoing(Bool_t r=kTRUE)
Definition: KVTarget.h:237
virtual const char * GetName() const
virtual void Error(const char *method, const char *msgfmt,...) const
Bool_t BeginsWith(const char *s, ECaseCompare cmp=kExact) const
const char * Data() const
const long double s
Definition: KVUnits.h:94
auto * a