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 
11 
12 
15 
17 {
18  //default initialisation
19  fReconTraj = nullptr;
20  fRealZ = fRealA = 0.;
21  fDetNames = "/";
22  fIDTelName = "";
23  fIDTelescope = nullptr;
24  fNSegDet = 0;
25  fAnalStatus = 99;
26  fTargetEnergyLoss = 0;
27  ResetBit(kIsIdentified);
28  ResetBit(kIsCalibrated);
29  ResetBit(kCoherency);
30  ResetBit(kZMeasured);
31  ResetBit(kAMeasured);
32 }
33 
34 
35 
36 
39 
40 KVReconstructedNucleus::KVReconstructedNucleus() : fIDResults("KVIdentificationResult", 5)
41 {
42  //default ctor.
43  init();
44 }
45 
46 
47 
50 
52  : KVNucleus(), fIDResults("KVIdentificationResult", 5)
53 {
54  //copy ctor
55  init();
56 #if ROOT_VERSION_CODE >= ROOT_VERSION(3,4,0)
57  obj.Copy(*this);
58 #else
59  ((KVReconstructedNucleus&) obj).Copy(*this);
60 #endif
61 }
62 
63 
64 
65 
69 
71 {
72  // Stream an object of class KVReconstructedNucleus.
73  //Customized streamer.
74 
75  UInt_t R__s, R__c;
76  if (R__b.IsReading()) {
77  Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
78  if (R__v < 17) {
79  // Before v17, fIDResults was a static array: KVIdentificationResult fIDresults[5]
80  // We convert this to the new TClonesArray format
81  KVNucleus::Streamer(R__b);
82  fDetNames.Streamer(R__b);
83  fIDTelName.Streamer(R__b);
84  if (R__v >= 16) {
85  R__b >> fNSegDet;
86  R__b >> fAnalStatus;
87  }
88  R__b >> fRealZ;
89  R__b >> fRealA;
90  R__b >> fTargetEnergyLoss;
91  int R__i;
92  KVIdentificationResult id_array[5];
93  for (R__i = 0; R__i < 5; R__i++) {
94  id_array[R__i].Streamer(R__b);
95  id_array[R__i].Copy(*GetIdentificationResult(R__i + 1));
96  }
97  R__b.CheckByteCount(R__s, R__c, KVReconstructedNucleus::IsA());
98  }
99  else
100  R__b.ReadClassBuffer(KVReconstructedNucleus::Class(), this, R__v, R__s, R__c);
101  // if the multidetector object exists, update some informations
102  // concerning the detectors etc. hit by this particle
103  if (gMultiDetArray) {
105  fReconTraj = nullptr;
107  fIDTelescope = nullptr;
108  if (fIDTelName != "") fIDTelescope = gMultiDetArray->GetIDTelescope(fIDTelName.Data());
109  if (fReconTraj) {
110  if (R__v < 16) fNSegDet = fReconTraj->GetNumberOfIndependentIdentifications(); // fNSegDet/fAnalStatus non-persistent before v.16
111  }
112  else {
113  TIter next_det(&fDetList);
114  KVDetector* det;
115  while ((det = (KVDetector*)next_det())) {
116  det->AddHit(this);
117  if (det->IsDetecting()) { //to be coherent with AddDetector() method
118  if (R__v < 16) fNSegDet += det->GetSegment(); // fNSegDet/fAnalStatus non-persistent before v.16
119  //modify detector's counters depending on particle's identification state
120  if (IsIdentified())
122  else
124  }
125  }
126  }
127  }
128  }
129  else {
131  }
132 }
133 
134 
135 
136 
138 
140 {
141  switch (GetStatus()) {
142  case kStatusOK:
143  cout <<
144  "Particle alone in group, or identification independently of other particles in group is directly possible." << endl;
145  break;
146 
147  case kStatusOKafterSub:
148  cout <<
149  "Particle reconstructed after identification of others in group and subtraction of their calculated energy losses in common detectors."
150  << endl;
151  break;
152 
153  case kStatusOKafterShare:
154  cout <<
155  "Particle identification estimated after arbitrary sharing of energy lost in common detectors between several reconstructed particles."
156  << endl;
157  break;
158 
160  cout <<
161  "Particle stopped in first stage of telescope. Estimation of minimum Z."
162  << endl;
163  break;
164 
165  case kStatusPileupDE:
166  cout <<
167  "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)."
168  << endl;
169  break;
170 
171  case kStatusPileupGhost:
172  cout <<
173  "Undetectable ghost particle in filtered simulation. Another particle passed through all of the same detectors (pile-up)."
174  << endl;
175  break;
176 
177 
178  default:
179  cout << GetStatus() << endl;
180  break;
181  }
182 }
183 
184 
185 
188 
190 {
191  // Returns kTRUE if particle was detected in array with given name
192  return GetArrayName() == name;
193 }
194 
195 
196 
199 
201 {
202  // Returns name of array particle was detected in (if known)
203  if (GetParameters()->HasStringParameter("ARRAY")) return GetParameters()->GetStringValue("ARRAY");
205  return "";
206 }
207 
208 
209 
211 
213 {
214 
215  int ndets = GetNumDet();
216  if (ndets) {
217 
218  for (int i = ndets - 1; i >= 0; i--) {
219  KVDetector* det = GetDetector(i);
220  if (det) det->Print("data");
221  }
222  for (int i = 1; i <= GetNumberOfIdentificationResults(); i++) {
224  if (idr->IDattempted) idr->Print();
225  }
226  }
227  if (GetStoppingDetector()) cout << "STOPPED IN : " <<
228  GetStoppingDetector()->GetName() << endl;
229  if (IsIdentified()) {
230  if (GetIdentifyingTelescope()) cout << "IDENTIFIED IN : " <<
231  GetIdentifyingTelescope()->GetName() << endl;
232  cout << " =======> ";
233  cout << " Z=" << GetZ() << " A=" << GetA();
234  if (IsAMeasured()) cout << " Areal=" << GetRealA();
235  else cout << " Zreal=" << GetRealZ();
236  }
237  else {
238  cout << "(unidentified)" << endl;
239  }
240  if (IsCalibrated()) {
241  cout << " Total Energy = " << GetEnergy() << " MeV, Theta=" << GetTheta() << " Phi=" << GetPhi() << endl;
242  cout << " Target energy loss correction : " << GetTargetEnergyLoss() << " MeV" << endl;
243  }
244  else {
245  cout << "(uncalibrated)" << endl;
246  }
247  cout << "RECONSTRUCTION STATUS : " << endl;
249  if (fReconTraj) fReconTraj->ls();
250  if (GetParameters()->GetNpar()) GetParameters()->Print();
251 }
252 
253 
254 
255 #if ROOT_VERSION_CODE >= ROOT_VERSION(3,4,0)
256 
261 
263 #else
265 #endif
266 {
267  //
268  //Copy this to obj
269  //
270  KVNucleus::Copy(obj);
272  robj.SetIdentifyingTelescope(GetIdentifyingTelescope());
273  robj.fDetNames = fDetNames;
274  robj.SetRealZ(GetRealZ());
275  robj.SetRealA(GetRealA());
276  robj.SetTargetEnergyLoss(GetTargetEnergyLoss());
277  robj.fReconTraj = fReconTraj;
278  robj.fIDTelescope = fIDTelescope;
279  robj.fNSegDet = fNSegDet;
280  robj.fAnalStatus = fAnalStatus;
281  // copy id results
282  Int_t nidres = GetNumberOfIdentificationResults();
283  for (int i = 1; i <= nidres; ++i) {
284  GetIdentificationResult(i)->Copy(*robj.GetIdentificationResult(i));
285  }
286  robj.SetBit(kIsIdentified, TestBit(kIsIdentified));
287  robj.SetBit(kIsCalibrated, TestBit(kIsCalibrated));
288  robj.SetBit(kCoherency, TestBit(kCoherency));
289  robj.SetBit(kZMeasured, TestBit(kZMeasured));
290  robj.SetBit(kAMeasured, TestBit(kAMeasured));
291 }
292 
293 
294 
299 
301 {
302  // Copy all characteristics of 'other' and also change all references to
303  // 'other' to references to 'this' (i.e. in detectors hit by particle).
304  // 'other' will not be fully valid after this operation (shouldn't be used further)
305 
306  other->Copy(*this);
307  KVGeoDetectorNode* node;
308  const KVReconNucTrajectory* traj = other->GetReconstructionTrajectory();
309  traj->IterateFrom();
310  while ((node = traj->GetNextNode())) {
311  KVDetector* d = node->GetDetector();
312  d->GetHits()->Remove(const_cast<KVReconstructedNucleus*>(other));
313  d->GetHits()->Add(this);
314  }
315 }
316 
317 
318 
322 
324 {
325  // Reset nucleus. Calls KVNucleus::Clear.
326  // if opt!="N": Calls KVGroup::Reset for the group where it was reconstructed.
327 
328  KVNucleus::Clear(opt);
329  if (GetGroup() && strncmp(opt, "N", 1))
330  GetGroup()->Reset();
331  fDetList.Clear();
332  fIDResults.Clear("C");
333  init();
334 }
335 
336 
337 
343 
345 {
346  //Add a detector to the list of those through which the particle passed.
347  //Put reference to detector into fDetectors array, increase number of detectors by one.
348  //As this is only used in initial particle reconstruction, we add 1 unidentified particle to the detector.
349 
350  //add name of detector to fDetNames
351  fDetNames += det->GetName();
352  fDetNames += "/";
353  // store pointer to detector
354  fDetList.Add(det);
355  if (det->IsDetecting()) {
356  //add segmentation index of detector to total segmentation index of particle
357  fNSegDet += det->GetSegment();
358  //add 1 unidentified particle to the detector
360  }
361 
362 }
363 
364 
365 
369 
371 {
372  // this method modifies the reconstructed trajectory
373  // probably called during the identification coherency check
374  fReconTraj = t;
375  fDetNames = t->GetPathString();//to store/retrieve reconstruction trajectory on file
376 }
377 
378 
379 
382 
384 {
385  // Method called in initial reconstruction of particle.
386 
387  fReconTraj = t;
389  t->AddUnidentifiedParticle(0);//add 1 unidentified particle to each detector on trajectory
390  fDetNames = t->GetPathString();//to store/retrieve reconstruction trajectory on file
391 }
392 
393 
394 
395 
408 
410 {
411  //Reconstruction of a detected nucleus from the successive energy losses
412  //measured in a series of detectors/telescopes.
413  //
414  //Starting from detector *kvd, collect information from all detectors placed directly
415  //in front of *kvd (kvd->GetAlignedDetectors()),
416  //these are the detectors the particle has passed through.
417  //
418  //Each one is added to the particle's list (KVReconstructedNucleus::AddDetector), and,
419  //if it is not an unsegmented detector, it is marked as having been "analysed"
420  //(KVDetector::SetAnalysed) in order to stop it being considered as a starting point for another
421  //particle reconstruction.
422 
423  fNSegDet = 0;
424  SetParameter("ARRAY", kvd->GetNameOfArray());
425  //get list of detectors through which particle passed
426  if (kvd->GetGroup()) {
427  TList* aligned = kvd->GetAlignedDetectors();
428  if (aligned) {
429 
430  TIter next_aligned(aligned);
431  KVDetector* d;
432  while ((d = (KVDetector*) next_aligned())) {
433  AddDetector(d);
434  d->AddHit(this); // add particle to list of particles hitting detector
435  d->SetAnalysed(kTRUE); //cannot be used to seed another particle
436  }
437  }
438  kvd->GetGroup()->AddHit(this);
439  }
440 }
441 
442 
443 
444 
453 
455 {
456  // Try to identify this nucleus by calling the Identify() function of each
457  // ID telescope crossed by it, starting with the telescope where the particle stopped, in order
458  // - only attempt identification in ID telescopes containing the stopping detector.
459  // - only telescopes which have been correctly initialised for the current run are used,
460  // i.e. those for which KVIDTelescope::IsReadyForID() returns kTRUE.
461  // This continues until a successful identification is achieved or there are no more ID telescopes to try.
462  // The identification code corresponding to the identifying telescope is set as the identification code of the particle.
463 
464 
466  if (idt_list && idt_list->GetSize() > 0) {
467 
468  KVIDTelescope* idt;
469  TIter next(idt_list);
470  Int_t idnumber = 1;
471  Int_t n_success_id = 0;//number of successful identifications
472  while ((idt = (KVIDTelescope*) next())) {
474 
475 
476  if (idt->IsReadyForID()) { // is telescope able to identify for this run ?
477 
478  IDR->IDattempted = kTRUE;
479  idt->Identify(IDR);
480 
481  if (IDR->IDOK) n_success_id++;
482  }
483  else
484  IDR->IDattempted = kFALSE;
485 
486  if (n_success_id < 1 &&
487  ((!IDR->IDattempted) || (IDR->IDattempted && !IDR->IDOK))) {
488  // the particle is less identifiable than initially thought
489  // we may have to wait for secondary identification
490  Int_t nseg = GetNSegDet();
491  SetNSegDet(TMath::Max(nseg - 1, 0));
492  //if there are other unidentified particles in the group and NSegDet is < 2
493  //then exact status depends on segmentation of the other particles : reanalyse
494  if (GetNSegDet() < 2 && GetNUnidentifiedInGroup(GetGroup()) > 1) {
496  return;
497  }
498  //if NSegDet = 0 it's hopeless
499  if (!GetNSegDet()) {
501  return;
502  }
503  }
504 
505 
506  }
507 
508  }
509 
510 }
511 
512 
513 
514 
520 
522 {
523  // First-order coherency analysis of reconstructed particles
524  //
525  // This method is kept for backwards compatibility. it is called by
526  // KVReconstructedEvent::Streamer when reading old data
527 
528  if (GetNUnidentifiedInGroup(grp) > 1) { //if there is more than one unidentified particle in the group
529 
530  UShort_t n_nseg_1 = 0;
531  if (!grp->GetParticles()) {
532  ::Error("KVReconstructedNucleus::AnalyseParticlesInGroup", "No particles in group ?");
533  return;
534  }
535  TIter next(grp->GetParticles());
537  //loop over particles counting up different cases
538  while ((nuc = (KVReconstructedNucleus*) next())) {
539  //ignore identified particles
540  if (nuc->IsIdentified())
541  continue;
542 
543  if (nuc->GetNSegDet() >= 2) {
544  //all part.s crossing 2 or more independent detectors are fine
546  }
547  else if (nuc->GetNSegDet() == 1) {
548  //only 1 independent detector hit => depends on what's in the rest
549  //of the group
550  n_nseg_1++;
551  }
552  else {
553  //part.s crossing 0 independent detectors (i.E. arret ChIo)
554  //can not be reconstructed
556  }
557  }
558  next.Reset();
559  //loop again, setting status
560  while ((nuc = (KVReconstructedNucleus*) next())) {
561  if (nuc->IsIdentified())
562  continue; //ignore identified particles
563 
564  if (nuc->GetNSegDet() == 1) {
565  if (n_nseg_1 == 1) {
566  //just the one ? then we can get it no problem
567  //after identifying the others and subtracting their calculated
568  //energy losses from the "dependent"/"non-segmented" detector
569  //(i.E. the ChIo)
571  }
572  else {
573  //more than one ? then we can make some wild guess by sharing the
574  //"non-segmented" (i.e. ChIo) contribution between them, but
575  //I wouldn't trust it as far as I can spit
577  }
578  //one possibility remains: the particle may actually have stopped e.g.
579  //in the DE detector of a DE-E telescope, in which case AnalStatus = 3
580  if (nuc->GetIDTelescopes()->GetSize() == 0) {
581  //no ID telescopes with which to identify particle
583  }
584  }
585  }
586  }
587  else if (GetNUnidentifiedInGroup(grp) == 1) {
588  //only one unidentified particle in group: if NSegDet>=1 then it's OK
589 
590  //loop over particles looking for the unidentified one
591  TIter next(grp->GetParticles());
593  while ((nuc = (KVReconstructedNucleus*) next()))
594  if (!nuc->IsIdentified())
595  break;
596 
597  if (nuc->GetNSegDet() > 0) {
598  //OK no problem
600  }
601  else {
602  //dead in the water
604  }
605  //one possibility remains: the particle may actually have stopped e.g. in the 1st member
606  //of a telescope, in which case AnalStatus = 3
607  if (nuc->GetIDTelescopes()->GetSize() == 0) {
608  //no ID telescopes with which to identify particle
610  }
611  }
612 #ifdef KV_DEBUG
613  Info("AnalyseGroups", "OK after analysis of particles in groups");
614 #endif
615 }
616 
617 
618 
619 
632 
634 {
635  // Calculate angles theta and phi for nucleus based on the detectors on its reconstruction trajectory.
636  // The momentum is set using these angles, its mass and its kinetic energy.
637  //
638  // The detector with the smallest solid angle along the trajectory is the one which defines the
639  // angles for the reconstructed particle.
640  //
641  // The (optional) option string can be "random" or "mean":
642  //
643  // If "random" (default) the angles are drawn at random between the over the surface of the detector.
644  //
645  // If "mean" the (theta,phi) position of the centre of the detector is used to fix the nucleus' direction.
646 
647 
648  if (GetEnergy() <= 0.0)//don't try if particle has no correctly defined energy
649  return;
651  return;
652 
653  KVDetector* angle_det = nullptr;
654  double small_solid = 1.e+09;
657  while ((n = GetReconstructionTrajectory()->GetNextNode())) {
658  if (n->GetDetector()->GetSolidAngle() < small_solid) {
659  angle_det = n->GetDetector();
660  small_solid = n->GetDetector()->GetSolidAngle();
661  }
662  }
663  if (!strcmp(opt, "random")) {
664  //random angles
665  TVector3 dir = angle_det->GetRandomDirection("random");
666  SetMomentum(GetEnergy(), dir);
667  }
668  else {
669  //middle of telescope
670  TVector3 dir = angle_det->GetDirection();
671  SetMomentum(GetEnergy(), dir);
672  }
673 }
674 
675 
676 
677 
692 
694 {
695  //Calculate and set the energy of a (previously identified) reconstructed particle,
696  //including an estimate of the energy loss in the target.
697  //
698  //Starting from the detector in which the particle stopped, we add up the
699  //'corrected' energy losses in all of the detectors through which it passed.
700  //Whenever possible, for detectors which are not calibrated or not working,
701  //we calculate the energy loss. Measured & calculated energy losses are also
702  //compared for each detector, and may lead to new particles being seeded for
703  //subsequent identification. This is done by KVIDTelescope::CalculateParticleEnergy().
704  //
705  //For particles whose energy before hitting the first detector in their path has been
706  //calculated after this step we then add the calculated energy loss in the target,
707  //using gMultiDetArray->GetTargetEnergyLossCorrection().
708 
710  idt->CalculateParticleEnergy(this);
712  SetIsCalibrated();
713  //add correction for target energy loss - moving charged particles only!
714  Double_t E_targ = 0.;
715  if (GetZ() && GetEnergy() > 0) {
716  E_targ = gMultiDetArray->GetTargetEnergyLossCorrection(this);
717  SetTargetEnergyLoss(E_targ);
718  }
719  Double_t E_tot = GetEnergy() + E_targ;
720  SetEnergy(E_tot);
721  // set particle momentum from telescope dimensions (random)
723  }
724 }
725 
726 
727 
732 
734 {
735  // Protected method, called when required to fill fDetList with pointers to
736  // the detectors whose names are stored in fDetNames.
737  // If gMultiDetArray=0x0, fDetList list will be empty.
738 
739  fDetList.Clear();
740  if (gMultiDetArray) gMultiDetArray->FillDetectorList(this, &fDetList, fDetNames);
741 }
742 
743 
744 
750 
752 {
753  // Called by Streamer when reading in data
754  // The fDetNames string is used to associate the particle with its reconstruction trajectory
755  //
756  // in_streamer=true: being called from KVReconstructedNucleus::Streamer()
757 
758  if (gMultiDetArray) {
759  // for old data, detnames was written as "/DET_1/DET_2/..."
760  // trajectory paths are written as "DET_1/DET_2/..."
761  if (fDetNames[0] == '/') fDetNames.Remove(0, 1);
762  fDetNames.Begin("/");
763  KVString n_stop_det = fDetNames.Next();
764  KVDetector* stop_det = gMultiDetArray->GetDetector(n_stop_det);
765  if (stop_det) {
766  KVGroup* gr = stop_det->GetGroup();
767  if (in_streamer) gr->AddHit(this); //for backwards compatibility, group coherency analysis performed in KVReconstructedEvent::Streamer (old data)
768  fReconTraj = (KVReconNucTrajectory*)gr->FindReconTraj(fDetNames);
769  if (in_streamer && fReconTraj) {
772  while ((n = fReconTraj->GetNextNode())) {
773  n->GetDetector()->AddHit(this);
774  if (IsIdentified()) n->GetDetector()->IncrementIdentifiedParticles();
775  else n->GetDetector()->IncrementUnidentifiedParticles();
776  }
777  }
778  }
779  }
780 }
781 
782 
783 
789 
791 {
792  // Change the particle's reconstruction trajectory to a different one starting from the
793  // same stopping detector (and therefore in the same group).
794  //
795  // trajectory paths are written as "DET_1/DET_2/..."
796 
798  if (!new_traj) {
799  Error("ReplaceReconTraj", "Trajectory %s not found - meant to replace %s", traj_name.Data(), fReconTraj->GetTitle());
800  return;
801  }
802  // first iterate over existing trajectory and reset detectors
805  while ((n = fReconTraj->GetNextNode())) {
806  n->GetDetector()->RemoveHit(this);
807  if (IsIdentified()) n->GetDetector()->IncrementIdentifiedParticles(-1);
808  else n->GetDetector()->IncrementUnidentifiedParticles(-1);
809  }
810  // set new trajectory
811  fReconTraj = new_traj;
813  while ((n = fReconTraj->GetNextNode())) {
814  n->GetDetector()->AddHit(this);
815  if (IsIdentified()) n->GetDetector()->IncrementIdentifiedParticles();
816  else n->GetDetector()->IncrementUnidentifiedParticles();
817  }
818 }
819 
820 
821 
829 
831 {
832  // Set identification of nucleus from informations in identification result object
833  // The mass (A) information in KVIdentificationResult is only used if the mass
834  // was measured as part of the identification. Otherwise the nucleus' mass formula
835  // will be used to calculate A from the measured Z.
836  //
837  // The identifying telescope is set to idt.
838 
840  SetIDCode(idr->IDcode);
841  SetZMeasured(idr->Zident);
842  SetAMeasured(idr->Aident);
843  SetZ(idr->Z);
844  if (idr->Aident) {
845  SetA(idr->A);
846  SetRealA(idr->PID);
847  }
848  else {
849  SetRealZ(idr->PID);
850  }
851 }
852 
853 
854 
858 
860 {
861  // Subtract the calculated energy loss of this particle from the measured energy
862  // loss of all detectors it passed through.
863 
864  Double_t Einc = GetEnergy() - GetTargetEnergyLoss(); // energy before first detector
865  if (fReconTraj) {
867  KVGeoDetectorNode* node;
868  while ((node = fReconTraj->GetNextNode())) {
869  KVDetector* det = node->GetDetector();
870  Double_t Edet = det->GetEnergy();
871  Double_t dE = det->GetDeltaE(GetZ(), GetA(), Einc); // calculate apparent energy loss in active layer
872  Double_t Eres = det->GetERes(GetZ(), GetA(), Einc); // calculate energy after detector
873  Edet -= dE;
874  if (Edet < 0.1) Edet = 0.;
875  det->SetEnergyLoss(Edet);
876  Einc = Eres;
877  if (Einc < 0.1) break;
878  }
879  return;
880  }
881  // backwards compatibility for old data
883  KVDetector* det;
884  while ((det = (KVDetector*)nxt())) {
885  Double_t Edet = det->GetEnergy();
886  Double_t dE = det->GetDeltaE(GetZ(), GetA(), Einc); // calculate apparent energy loss in active layer
887  Double_t Eres = det->GetERes(GetZ(), GetA(), Einc); // calculate energy after detector
888  Edet -= dE;
889  if (Edet < 0.1) Edet = 0.;
890  det->SetEnergyLoss(Edet);
891  Einc = Eres;
892  if (Einc < 0.1) break;
893  }
894 }
895 
896 
897 
899 
901 {
902  printf(" A:%6s", GetParameters()->GetStringValue("ARRAY"));
903  if (GetStoppingDetector()) printf(" D:%10s", GetStoppingDetector()->GetName());
904  printf(" IDCODE=%2d", GetIDCode());
905  if (IsIdentified()) {
906  if (GetIdentifyingTelescope()) printf(" ID:%15s", GetIdentifyingTelescope()->GetName());
907  if (IsZMeasured()) printf(" Z=%2d", GetZ());
908  else printf(" ");
909  if (IsAMeasured()) printf(" A=%3d : ", GetA());
910  else printf(" : ");
911  if (IsCalibrated()) printf(" E=%g MeV", GetEnergy());
912  if (GetParameters()->IsValue("Coherent", false)) printf("/not coherent/");
913  if (GetParameters()->IsValue("Pileup", true)) printf("/pileup/");
914  }
915  printf("\n");
916 }
917 
918 
int Int_t
unsigned int UInt_t
#define d(i)
bool Bool_t
unsigned short UShort_t
short Version_t
constexpr Bool_t kFALSE
double Double_t
constexpr Bool_t kTRUE
const char Option_t
const Bool_t kIterBackward
char name[80]
Base class for detector geometry description.
Definition: KVDetector.h:160
void IncrementIdentifiedParticles(Int_t n=1)
Definition: KVDetector.h:565
void IncrementUnidentifiedParticles(Int_t n=1)
Definition: KVDetector.h:559
virtual Double_t GetERes(Int_t Z, Int_t A, Double_t Einc)
KVList * GetAlignedIDTelescopes()
Definition: KVDetector.cpp:737
KVGroup * GetGroup() const
virtual void SetEnergyLoss(Double_t e) const
Definition: KVDetector.h:373
virtual Double_t GetEnergy() const
Definition: KVDetector.h:349
const Char_t * GetNameOfArray() const
Definition: KVDetector.h:780
UShort_t GetSegment() const
Definition: KVDetector.h:830
virtual Bool_t IsDetecting() const
Definition: KVDetector.h:672
TVector3 GetDirection()
Definition: KVDetector.h:732
virtual TList * GetAlignedDetectors(UInt_t direction=1)
virtual Double_t GetDeltaE(Int_t Z, Int_t A, Double_t Einc)
void AddHit(KVNucleus *part)
Definition: KVDetector.h:405
TVector3 GetRandomDirection(Option_t *t="isotropic")
Definition: KVDetector.h:720
virtual void Print(Option_t *option="") const
Definition: KVDetector.cpp:364
KVGeoDetectorNode * GetNextNode() const
TString GetPathString() const
void AddUnidentifiedParticle(int modify_identified=-1) const
void IterateFrom(const KVGeoDetectorNode *node0=nullptr) const
void IterateBackFrom(const KVGeoDetectorNode *node0=nullptr) const
Information on relative positions of detectors & particle trajectories.
KVDetector * GetDetector() const
KVDetector * GetDetector(const Char_t *name) const
Return detector in this structure with given name.
Group of detectors which can be treated independently of all others in array.
Definition: KVGroup.h:20
void Reset(Option_t *opt="")
Definition: KVGroup.cpp:114
const KVGeoDNTrajectory * FindReconTraj(const KVString &path)
Definition: KVGroup.h:98
KVGeoStrucElement * GetArray() const
Definition: KVGroup.h:45
KVList * GetParticles()
Definition: KVGroup.h:66
void AddHit(KVNucleus *kvd)
Definition: KVGroup.cpp:134
Base class for all detectors or associations of detectors in array which can identify charged particl...
Definition: KVIDTelescope.h:84
virtual Bool_t IsReadyForID()
@ kCalibStatus_NoCalibrations
virtual Bool_t Identify(KVIdentificationResult *, Double_t x=-1., Double_t y=-1.)
virtual void CalculateParticleEnergy(KVReconstructedNucleus *nuc)
virtual Int_t GetCalibStatus() const
Full result of one attempted particle identification.
Bool_t IDattempted
=kTRUE if identification was attempted
Bool_t IDOK
general quality of identification, =kTRUE if acceptable identification made
void Print(Option_t *opt="") const
void Copy(TObject &) const
Copy this to obj.
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
Bool_t Zident
=kTRUE if Z of particle established
Extended TList class which owns its objects by default.
Definition: KVList.h:28
virtual Double_t GetTargetEnergyLossCorrection(KVReconstructedNucleus *)
virtual void FillDetectorList(KVReconstructedNucleus *rnuc, KVHashList *DetList, const KVString &DetNames)
KVIDTelescope * GetIDTelescope(const Char_t *name) const
Return pointer to DeltaE-E ID Telescope with "name".
virtual void Print(Option_t *opt="") const
const Char_t * GetStringValue(const Char_t *name) const
Description of properties and kinematics of atomic nuclei.
Definition: KVNucleus.h:126
virtual void Clear(Option_t *opt="")
Definition: KVNucleus.cpp:301
Int_t GetA() const
Definition: KVNucleus.cpp:802
void SetA(Int_t a)
Definition: KVNucleus.cpp:658
void SetZ(Int_t z, Char_t mt=-1)
Definition: KVNucleus.cpp:707
virtual void Copy(TObject &) const
Copy this KVNucleus into the KVNucleus object referenced by "obj".
Definition: KVNucleus.cpp:837
Int_t GetZ() const
Return the number of proton / atomic number.
Definition: KVNucleus.cpp:773
KVNameValueList * GetParameters() const
Definition: KVParticle.h:815
Double_t GetTheta() const
Definition: KVParticle.h:680
const Char_t * GetName() const
return the field fName
Definition: KVParticle.cpp:423
Double_t GetEnergy() const
Definition: KVParticle.h:621
Double_t GetPhi() const
Definition: KVParticle.h:688
void SetMomentum(const TVector3 *v)
Definition: KVParticle.h:542
void SetParameter(const Char_t *name, ValType value) const
Definition: KVParticle.h:819
void SetEnergy(Double_t e)
Definition: KVParticle.h:599
Path through detector array used to reconstruct detected particle.
void ls(Option_t *="") const
Int_t GetNumberOfIndependentIdentifications() const
Nuclei reconstructed from data measured by a detector array .
virtual void SetIDCode(UShort_t s)
virtual void Reconstruct(KVDetector *kvd)
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 *)
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
void ls(Option_t *="") const
Int_t GetNumberOfIdentificationResults() const
const KVSeqCollection * GetDetectorList() const
virtual void Print(Option_t *option="") const
virtual void Copy(TObject &) const
KVIdentificationResult * GetIdentificationResult(Int_t i)
virtual void SubtractEnergyFromAllDetectors()
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 *)
static UInt_t GetNUnidentifiedInGroup(KVGroup *grp)
void RebuildReconTraj(bool in_streamer=true)
virtual Int_t GetIDCode() const
const KVSeqCollection * GetIDTelescopes() 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)
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
virtual void Clear(Option_t *option="")
KVIDTelescope * GetIdentifyingTelescope() const
static void AnalyseParticlesInGroup(KVGroup *grp)
@ 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.
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
virtual void Clear(Option_t *option="")
virtual Int_t GetSize() const
virtual void Add(TObject *obj)
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
void Reset()
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
virtual void Info(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
Double_t Max(Double_t a, Double_t b)
ClassImp(TPyArg)