KaliVeda
Toolkit for HIC analysis
KVReconstructedNucleus.cpp
1 #include "KVReconstructedNucleus.h"
2 #include "KVIDTelescope.h"
3 #include "KVGroup.h"
4 #include "KVMultiDetArray.h"
5 
6 using namespace std;
7 
9 
10 
13 
15 {
16  //default initialisation
17  fReconTraj = nullptr;
18  fRealZ = fRealA = 0.;
19  fDetNames = "/";
20  fIDTelName = "";
21  fIDTelescope = nullptr;
22  fNSegDet = 0;
23  fAnalStatus = 99;
24  fTargetEnergyLoss = 0;
25  ResetBit(kIsIdentified);
26  ResetBit(kIsCalibrated);
27  ResetBit(kCoherency);
28  ResetBit(kZMeasured);
29  ResetBit(kAMeasured);
30 }
31 
32 
33 
34 
37 
38 KVReconstructedNucleus::KVReconstructedNucleus() : fIDResults("KVIdentificationResult", 5)
39 {
40  //default ctor.
41  init();
42 }
43 
44 
45 
48 
50  : KVNucleus(), fIDResults("KVIdentificationResult", 5)
51 {
52  //copy ctor
53  init();
54 #if ROOT_VERSION_CODE >= ROOT_VERSION(3,4,0)
55  obj.Copy(*this);
56 #else
57  ((KVReconstructedNucleus&) obj).Copy(*this);
58 #endif
59 }
60 
61 
62 
63 
67 
69 {
70  // Stream an object of class KVReconstructedNucleus.
71  //Customized streamer.
72 
73  UInt_t R__s, R__c;
74  if (R__b.IsReading()) {
75  Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
76  if (R__v < 17) {
77  // Before v17, fIDResults was a static array: KVIdentificationResult fIDresults[5]
78  // We convert this to the new TClonesArray format
79  KVNucleus::Streamer(R__b);
80  fDetNames.Streamer(R__b);
81  fIDTelName.Streamer(R__b);
82  if (R__v >= 16) {
83  R__b >> fNSegDet;
84  R__b >> fAnalStatus;
85  }
86  R__b >> fRealZ;
87  R__b >> fRealA;
88  R__b >> fTargetEnergyLoss;
89  int R__i;
90  KVIdentificationResult id_array[5];
91  for (R__i = 0; R__i < 5; R__i++) {
92  id_array[R__i].Streamer(R__b);
93  id_array[R__i].Copy(*GetIdentificationResult(R__i + 1));
94  }
95  R__b.CheckByteCount(R__s, R__c, KVReconstructedNucleus::IsA());
96  }
97  else
98  R__b.ReadClassBuffer(KVReconstructedNucleus::Class(), this, R__v, R__s, R__c);
99  // if the multidetector object exists, update some informations
100  // concerning the detectors etc. hit by this particle
101  if (gMultiDetArray) {
102  fReconTraj = nullptr;
103  RebuildReconTraj();
104  fIDTelescope = nullptr;
105  if (fIDTelName != "") fIDTelescope = gMultiDetArray->GetIDTelescope(fIDTelName.Data());
106  if (fReconTraj) {
107  if (R__v < 16) fNSegDet = fReconTraj->GetNumberOfIndependentIdentifications(); // fNSegDet/fAnalStatus non-persistent before v.16
108  }
109  else {
110  TIter next_det(&fDetList);
111  KVDetector* det;
112  while ((det = (KVDetector*)next_det())) {
113  det->AddHit(this);
114  if (det->IsDetecting()) { //to be coherent with AddDetector() method
115  //modify detector's counters depending on particle's identification state
116  if (IsIdentified())
118  else
120  }
121  }
122  }
123  }
124  }
125  else {
127  }
128 }
129 
130 
131 
132 
134 
136 {
137  switch (GetStatus()) {
138  case kStatusOK:
139  cout <<
140  "Particle alone in group, or identification independently of other particles in group is directly possible." << endl;
141  break;
142 
143  case kStatusOKafterSub:
144  cout <<
145  "Particle reconstructed after identification of others in group and subtraction of their calculated energy losses in common detectors."
146  << endl;
147  break;
148 
149  case kStatusOKafterShare:
150  cout <<
151  "Particle identification estimated after arbitrary sharing of energy lost in common detectors between several reconstructed particles."
152  << endl;
153  break;
154 
156  cout <<
157  "Particle stopped in first stage of telescope. Estimation of minimum Z."
158  << endl;
159  break;
160 
161  case kStatusPileupDE:
162  cout <<
163  "Undetectable pile-up in first member of identifying telesscope (apparent status=OK). Would lead to incorrect identification by DE-E method (Z and/or A overestimated)."
164  << endl;
165  break;
166 
167  case kStatusPileupGhost:
168  cout <<
169  "Undetectable ghost particle in filtered simulation. Another particle passed through all of the same detectors (pile-up)."
170  << endl;
171  break;
172 
173 
174  default:
175  cout << GetStatus() << endl;
176  break;
177  }
178 }
179 
180 
181 
184 
186 {
187  // Returns kTRUE if particle was detected in array with given name
188  return GetArrayName() == name;
189 }
190 
191 
192 
195 
197 {
198  // Returns name of array particle was detected in (if known)
199  if (GetParameters()->HasStringParameter("ARRAY")) return GetParameters()->GetStringValue("ARRAY");
201  return "";
202 }
203 
204 
205 
207 
209 {
210 
211  int ndets = GetNumDet();
212  if (ndets) {
213 
214  for (int i = ndets - 1; i >= 0; i--) {
215  KVDetector* det = GetDetector(i);
216  if (det) det->Print("data");
217  }
218  for (int i = 1; i <= GetNumberOfIdentificationResults(); i++) {
220  if (idr->IDattempted) idr->Print();
221  }
222  }
223  if (GetStoppingDetector()) cout << "STOPPED IN : " <<
224  GetStoppingDetector()->GetName() << endl;
225  if (IsIdentified()) {
226  if (GetIdentifyingTelescope()) cout << "IDENTIFIED IN : " <<
227  GetIdentifyingTelescope()->GetName() << endl;
228  cout << " =======> ";
229  if(GetZ())
230  {
231  cout << " Z=" << GetZ() << " A=" << GetA();
232  if (IsAMeasured()) cout << " Areal=" << GetRealA();
233  else cout << " Zreal=" << GetRealZ();
234  }
235  else if(GetA()==1)
236  {
237  cout << "neutron";
238  }
239  else
240  {
241  cout << "gamma";
242  }
243  }
244  else {
245  cout << "(unidentified)" << endl;
246  }
247  if (IsCalibrated()) {
248  cout << " Total Energy = " << GetEnergy() << " MeV, Theta=" << GetTheta() << " Phi=" << GetPhi() << endl;
249  cout << " Target energy loss correction : " << GetTargetEnergyLoss() << " MeV" << endl;
250  }
251  else {
252  cout << " (uncalibrated)" << endl;
253  }
254  cout << "RECONSTRUCTION STATUS : " << endl;
256  if (fReconTraj) fReconTraj->ls();
257  if (GetParameters()->GetNpar()) GetParameters()->Print();
258 }
259 
260 
261 
262 #if ROOT_VERSION_CODE >= ROOT_VERSION(3,4,0)
263 
268 
270 #else
272 #endif
273 {
274  //
275  //Copy this to obj
276  //
277  KVNucleus::Copy(obj);
279  robj.SetIdentifyingTelescope(GetIdentifyingTelescope());
280  robj.fDetNames = fDetNames;
281  robj.SetRealZ(GetRealZ());
282  robj.SetRealA(GetRealA());
283  robj.SetTargetEnergyLoss(GetTargetEnergyLoss());
284  robj.fReconTraj = fReconTraj;
285  robj.fIDTelescope = fIDTelescope;
286  robj.fNSegDet = fNSegDet;
287  robj.fAnalStatus = fAnalStatus;
288  // copy id results
289  Int_t nidres = GetNumberOfIdentificationResults();
290  for (int i = 1; i <= nidres; ++i) {
291  GetIdentificationResult(i)->Copy(*robj.GetIdentificationResult(i));
292  }
293  robj.SetBit(kIsIdentified, TestBit(kIsIdentified));
294  robj.SetBit(kIsCalibrated, TestBit(kIsCalibrated));
295  robj.SetBit(kCoherency, TestBit(kCoherency));
296  robj.SetBit(kZMeasured, TestBit(kZMeasured));
297  robj.SetBit(kAMeasured, TestBit(kAMeasured));
298 }
299 
300 
301 
306 
308 {
309  // Copy all characteristics of 'other' and also change all references to
310  // 'other' to references to 'this' (i.e. in detectors hit by particle).
311  // 'other' will not be fully valid after this operation (shouldn't be used further)
312 
313  other->Copy(*this);
314  KVGeoDetectorNode* node;
315  const KVReconNucTrajectory* traj = other->GetReconstructionTrajectory();
316  traj->IterateFrom();
317  while ((node = traj->GetNextNode())) {
318  KVDetector* d = node->GetDetector();
319  // if 'other' was in the detector's hitlist, we add 'this' in its place
320  if(d->RemoveHit(const_cast<KVReconstructedNucleus*>(other)))
321  d->AddHit(this);
322  }
323 }
324 
325 
326 
330 
332 {
333  // Reset nucleus. Calls KVNucleus::Clear.
334  // if opt!="N": Calls KVGroup::Reset for the group where it was reconstructed.
335 
336  KVNucleus::Clear(opt);
337  if (GetGroup() && strncmp(opt, "N", 1))
338  GetGroup()->Reset();
339  fDetList.Clear();
340  fIDResults.Clear("C");
341  init();
342 }
343 
344 
345 
349 
351 {
352  // this method modifies the reconstructed trajectory
353  // probably called during the identification coherency check
354  fReconTraj = t;
355  fDetNames = t->GetPathString();//to store/retrieve reconstruction trajectory on file
356 }
357 
358 
359 
362 
364 {
365  // Method called in initial reconstruction of particle.
366 
367  fReconTraj = t;
369  t->AddUnidentifiedParticle(0);//add 1 unidentified particle to each detector on trajectory
370  fDetNames = t->GetPathString();//to store/retrieve reconstruction trajectory on file
371 }
372 
373 
374 
387 
389 {
390  // Calculate angles theta and phi for nucleus based on the detectors on its reconstruction trajectory.
391  // The momentum is set using these angles, its mass and its kinetic energy.
392  //
393  // The detector with the smallest solid angle along the trajectory is the one which defines the
394  // angles for the reconstructed particle.
395  //
396  // The (optional) option string can be "random" or "mean":
397  //
398  // If "random" (default) the angles are drawn at random between the over the surface of the detector.
399  //
400  // If "mean" the (theta,phi) position of the centre of the detector is used to fix the nucleus' direction.
401 
402 
403  if (GetEnergy() <= 0.0)//don't try if particle has no correctly defined energy
404  return;
406  return;
407 
408  KVDetector* angle_det = nullptr;
409  double small_solid = 1.e+09;
412  while ((n = GetReconstructionTrajectory()->GetNextNode())) {
413  if (n->GetDetector()->GetSolidAngle() < small_solid) {
414  angle_det = n->GetDetector();
415  small_solid = n->GetDetector()->GetSolidAngle();
416  }
417  }
418  if (!strcmp(opt, "random")) {
419  //random angles
420  TVector3 dir = angle_det->GetRandomDirection("random");
421  SetMomentum(GetEnergy(), dir);
422  }
423  else {
424  //middle of telescope
425  TVector3 dir = angle_det->GetDirection();
426  SetMomentum(GetEnergy(), dir);
427  }
428 }
429 
430 
431 
435 
436 void KVReconstructedNucleus::RebuildReconTraj()
437 {
438  // Called by Streamer when reading in data
439  // The fDetNames string is used to associate the particle with its reconstruction trajectory
440 
441  if (gMultiDetArray) {
442  // for old data, detnames was written as "/DET_1/DET_2/..."
443  // trajectory paths are written as "DET_1/DET_2/..."
444  if (fDetNames[0] == '/') fDetNames.Remove(0, 1);
445  fDetNames.Begin("/");
446  KVString n_stop_det = fDetNames.Next();
447  KVDetector* stop_det = gMultiDetArray->GetDetector(n_stop_det);
448  if (stop_det) {
449  KVGroup* gr = stop_det->GetGroup();
450  gr->AddHit(this);//for backwards compatibility, group coherency analysis performed in KVReconstructedEvent::Streamer (old data)
451  fReconTraj = (KVReconNucTrajectory*)gr->FindReconTraj(fDetNames);
452  if (fReconTraj) {
453  fReconTraj->IterateFrom();
455  while ((n = fReconTraj->GetNextNode())) {
456  n->GetDetector()->AddHit(this);
457  if (IsIdentified()) n->GetDetector()->IncrementIdentifiedParticles();
458  else n->GetDetector()->IncrementUnidentifiedParticles();
459  }
460  }
461  }
462  }
463 }
464 
465 
466 
472 
474 {
475  // Change the particle's reconstruction trajectory to a different one starting from the
476  // same stopping detector (and therefore in the same group).
477  //
478  // trajectory paths are written as "DET_1/DET_2/..."
479 
481  if (!new_traj) {
482  KVError::Error(this, "ReplaceReconTraj", "Trajectory %s not found - meant to replace %s", traj_name.Data(), fReconTraj->GetTitle());
483  return;
484  }
485  // first iterate over existing trajectory and reset detectors
486  fReconTraj->IterateFrom();
488  while ((n = fReconTraj->GetNextNode())) {
489  n->GetDetector()->RemoveHit(this);
490  if (IsIdentified()) n->GetDetector()->IncrementIdentifiedParticles(-1);
491  else n->GetDetector()->IncrementUnidentifiedParticles(-1);
492  }
493  // set new trajectory
494  fReconTraj = new_traj;
495  fReconTraj->IterateFrom();
496  while ((n = fReconTraj->GetNextNode())) {
497  n->GetDetector()->AddHit(this);
498  if (IsIdentified()) n->GetDetector()->IncrementIdentifiedParticles();
499  else n->GetDetector()->IncrementUnidentifiedParticles();
500  }
501 }
502 
503 
504 
512 
514 {
515  // Set identification of nucleus from informations in identification result object
516  // The mass (A) information in KVIdentificationResult is only used if the mass
517  // was measured as part of the identification. Otherwise the nucleus' mass formula
518  // will be used to calculate A from the measured Z.
519  //
520  // The identifying telescope is set to idt.
521 
523  SetIDCode(idr->IDcode);
524  SetZMeasured(idr->Zident);
525  SetAMeasured(idr->Aident);
526  SetZ(idr->Z);
527  if (idr->Aident) {
528  SetA(idr->A);
529  SetRealA(idr->PID);
530  }
531  else {
532  SetRealZ(idr->PID);
533  }
534 }
535 
536 
537 
539 
541 {
542  printf(" A:%6s", GetParameters()->GetStringValue("ARRAY"));
543  if (GetStoppingDetector()) printf(" D:%10s", GetStoppingDetector()->GetName());
544  printf(" IDCODE=%2d", GetIDCode());
545  if (IsIdentified()) {
546  if (GetIdentifyingTelescope()) printf(" ID:%15s", GetIdentifyingTelescope()->GetName());
547  if (IsZMeasured()) printf(" Z=%2d", GetZ());
548  else printf(" ");
549  if (IsAMeasured()) printf(" A=%3d : ", GetA());
550  else printf(" : ");
551  if (IsCalibrated()) printf(" E=%g MeV", GetEnergy());
552  if (GetParameters()->IsValue("Coherent", false)) printf("/not coherent/");
553  if (GetParameters()->IsValue("Pileup", true)) printf("/pileup/");
554  }
555  printf("\n");
556 }
557 
558 
int Int_t
unsigned int UInt_t
#define d(i)
bool Bool_t
short Version_t
const char Option_t
char name[80]
Base class for detector geometry description, interface to energy-loss calculations.
Definition: KVDetector.h:173
void IncrementIdentifiedParticles(Int_t n=1)
Definition: KVDetector.h:565
void IncrementUnidentifiedParticles(Int_t n=1)
Definition: KVDetector.h:559
KVGroup * GetGroup() const
void Print(Option_t *option="") const override
Definition: KVDetector.cpp:338
virtual Bool_t IsDetecting() const
Definition: KVDetector.h:666
TVector3 GetRandomDirection(Option_t *t="isotropic") override
Definition: KVDetector.h:712
void AddHit(KVNucleus *part)
Definition: KVDetector.h:424
TVector3 GetDirection() override
Definition: KVDetector.h:724
KVGeoDetectorNode * GetNextNode() const
KVString GetPathString() const
void AddUnidentifiedParticle(int modify_identified=-1) const
void IterateFrom(const KVGeoDetectorNode *node0=nullptr) const
Information on relative positions of detectors & particle trajectories.
KVDetector * GetDetector() const
virtual KVDetector * GetDetector(const Char_t *name) const
Return detector in this structure with given name.
KVGeoStrucElement * GetParentStructure(const Char_t *type, const Char_t *name="") const
Group of detectors which can be treated independently of all others in array.
Definition: KVGroup.h:20
void Reset(Option_t *opt="")
Definition: KVGroup.h:45
const KVGeoDNTrajectory * FindReconTraj(const KVString &path)
Definition: KVGroup.h:111
Base class for all detectors or associations of detectors in array which can identify charged particl...
Definition: KVIDTelescope.h:85
Full result of one attempted particle identification.
Bool_t IDattempted
=kTRUE if identification was attempted
void Print(Option_t *opt="") const override
Bool_t Aident
= kTRUE if A of particle established
Double_t PID
= "real" Z if Zident==kTRUE and Aident==kFALSE, "real" A if Zident==Aident==kTRUE
Int_t A
A of particle found (if Aident==kTRUE)
Int_t Z
Z of particle found (if Zident==kTRUE)
Int_t IDcode
a general identification code for this type of identification
void Copy(TObject &) const override
Copy this to obj.
Bool_t Zident
=kTRUE if Z of particle established
Base class for describing the geometry of a detector array.
KVIDTelescope * GetIDTelescope(const Char_t *name) const
Return pointer to DeltaE-E ID Telescope with "name".
const Char_t * GetStringValue(const Char_t *name) const
void Print(Option_t *opt="") const override
Description of properties and kinematics of atomic nuclei.
Definition: KVNucleus.h:123
void Copy(TObject &) const override
Copy this KVNucleus into the KVNucleus object referenced by "obj".
Definition: KVNucleus.cpp:831
void Clear(Option_t *opt="") override
Definition: KVNucleus.cpp:291
Int_t GetA() const
Definition: KVNucleus.cpp:796
void SetA(Int_t a)
Definition: KVNucleus.cpp:651
void SetZ(Int_t z, Char_t mt=-1)
Definition: KVNucleus.cpp:700
Int_t GetZ() const
Return the number of proton / atomic number.
Definition: KVNucleus.cpp:767
KVNameValueList * GetParameters() const
Definition: KVParticle.h:818
Double_t GetTheta() const
Definition: KVParticle.h:683
void SetMomentum(const TVector3 &v)
Definition: KVParticle.h:581
Double_t GetEnergy() const
Definition: KVParticle.h:624
const Char_t * GetName() const override
return the field fName
Definition: KVParticle.cpp:455
Double_t GetPhi() const
Definition: KVParticle.h:691
Path through detector array used to reconstruct detected particle.
Int_t GetNumberOfIndependentIdentifications() const
void ls(Option_t *="") const override
Nuclei reconstructed from data measured by a detector array .
virtual void SetIDCode(UShort_t s)
void ls(Option_t *="") const override
KVDetector * GetDetector(const TString &label) const
virtual Bool_t IsZMeasured() const
virtual void SetAMeasured(Bool_t yes=kTRUE)
void SetReconstructionTrajectory(const KVReconNucTrajectory *t)
Method called in initial reconstruction of particle.
virtual Double_t GetTargetEnergyLoss() const
void CopyAndMoveReferences(const KVReconstructedNucleus *)
@ kStatusOKafterShare
of energy losses of other particles in the same group which have Status=0
@ kStatusStopFirstStage
(arbitrarily) between this and the other particle(s) with Status=2
@ kStatusPileupDE
telescope; a minimum Z could be estimated from the measured energy loss.
Bool_t InArray(const TString &) const
Returns kTRUE if particle was detected in array with given name.
Int_t GetNumberOfIdentificationResults() const
KVIdentificationResult * GetIdentificationResult(Int_t i)
const KVReconNucTrajectory * GetReconstructionTrajectory() const
void SetIdentification(KVIdentificationResult *, KVIDTelescope *)
void Copy(TObject &) const override
void Clear(Option_t *option="") override
virtual Int_t GetIDCode() const
KVDetector * GetStoppingDetector() const
virtual void SetTargetEnergyLoss(Double_t e)
void ModifyReconstructionTrajectory(const KVReconNucTrajectory *t)
virtual void GetAnglesFromReconstructionTrajectory(Option_t *opt="random")
void init()
default initialisation
TString GetArrayName() const
Returns name of array particle was detected in (if known)
void Print(Option_t *option="") const override
virtual void SetZMeasured(Bool_t yes=kTRUE)
void ReplaceReconTraj(const TString &traj_name)
KVIDTelescope * GetIdentifyingTelescope() const
void SetIdentifyingTelescope(KVIDTelescope *i)
virtual Bool_t IsAMeasured() const
void Clear(Option_t *option="") override
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
KVString Next(Bool_t strip_whitespace=kFALSE) const
Definition: KVString.cpp:695
virtual Version_t ReadVersion(UInt_t *start=nullptr, UInt_t *bcnt=nullptr, const TClass *cl=nullptr)=0
virtual Int_t CheckByteCount(UInt_t startpos, UInt_t bcnt, const char *classname)=0
virtual Int_t ReadClassBuffer(const TClass *cl, void *pointer, const TClass *onfile_class=nullptr)=0
Bool_t IsReading() const
virtual Int_t WriteClassBuffer(const TClass *cl, void *pointer)=0
void Clear(Option_t *option="") override
TClass * IsA() const override
void Streamer(TBuffer &) override
static TClass * Class()
const char * GetName() const override
void Streamer(TBuffer &) override
const char * GetTitle() const override
void SetBit(UInt_t f)
const char * Data() const
virtual void Streamer(TBuffer &)
TString & Remove(EStripType s, char c)
const Int_t n
TGraphErrors * gr
void Error(UserClass p, const char *location, const char *va_(fmt),...)
Definition: KVError.h:116
ClassImp(TPyArg)