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;
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 
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) {
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  Error("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
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;
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:160
void IncrementIdentifiedParticles(Int_t n=1)
Definition: KVDetector.h:561
void IncrementUnidentifiedParticles(Int_t n=1)
Definition: KVDetector.h:555
KVGroup * GetGroup() const
void Print(Option_t *option="") const override
Definition: KVDetector.cpp:356
virtual Bool_t IsDetecting() const
Definition: KVDetector.h:662
TVector3 GetRandomDirection(Option_t *t="isotropic") override
Definition: KVDetector.h:708
void AddHit(KVNucleus *part)
Definition: KVDetector.h:420
TVector3 GetDirection() override
Definition: KVDetector.h:720
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
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
void SetMomentum(const TVector3 *v)
Definition: KVParticle.h:545
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)
Float_t fRealZ
Z returned by identification routine.
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.
const KVReconNucTrajectory * fReconTraj
trajectory used to reconstruct particle
Int_t GetNumberOfIdentificationResults() const
KVIdentificationResult * GetIdentificationResult(Int_t i)
KVHashList fDetList
non-persistent list of pointers to detectors
const KVReconNucTrajectory * GetReconstructionTrajectory() const
Float_t fRealA
A returned by identification routine.
void SetIdentification(KVIdentificationResult *, KVIDTelescope *)
void Copy(TObject &) const override
void Clear(Option_t *option="") override
virtual Int_t GetIDCode() const
TClonesArray fIDResults
results of every identification attempt made for this nucleus, in order of the ID telescopes used
KVDetector * GetStoppingDetector() const
void SetDetector(int i, KVDetector *);
virtual void SetTargetEnergyLoss(Double_t e)
KVString fDetNames
list of names of detectors through which particle passed
void ModifyReconstructionTrajectory(const KVReconNucTrajectory *t)
virtual void GetAnglesFromReconstructionTrajectory(Option_t *opt="random")
void init()
default initialisation
KVString fIDTelName
name of identification telescope which identified this particle (if any)
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)
Int_t fNSegDet
number of segmented/independent detectors hit by particle
void ReplaceReconTraj(const TString &traj_name)
Double_t fTargetEnergyLoss
calculated energy lost in target
KVIDTelescope * GetIdentifyingTelescope() const
void SetIdentifyingTelescope(KVIDTelescope *i)
KVIDTelescope * fIDTelescope
non-persistent pointer to identification telescope
virtual Bool_t IsAMeasured() const
Int_t fAnalStatus
status of particle after analysis of reconstructed event
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)
virtual void Error(const char *method, const char *msgfmt,...) const
const char * Data() const
virtual void Streamer(TBuffer &)
TString & Remove(EStripType s, char c)
const Int_t n
TGraphErrors * gr
ClassImp(TPyArg)