1 #include "KVFAZIAGroupReconstructor.h"
4 #include <KVFAZIADetector.h>
6 #include <KVLightEnergyCsIFull.h>
7 #include <KVLightEnergyCsI.h>
8 #include <KVCalibrator.h>
10 #include <KVCalibratedSignal.h>
23 enum detcode {SI1d = 1 << 0, SI2d = 1 << 1, CSId = 1 << 2};
25 PART->SetIsUncalibrated();
26 PART->SetECode(KVFAZIA::ECodes::NO_CALIBRATION_ATTEMPTED);
28 if (det == csi && PART->GetIDCode() == KVFAZIA::IDCodes::ID_GAMMA) {
34 PART->SetEnergy(ecsi);
35 SetCalibrationStatus(*PART, KVFAZIA::ECodes::NORMAL_CALIBRATION);
36 PART->SetParameter(
"FAZIA.ECSI", ecsi);
41 if (PART->GetIDCode() == KVFAZIA::IDCodes::ID_STOPPED_IN_FIRST_STAGE) {
44 PART->SetEnergy(esi1);
45 SetCalibrationStatus(*PART, KVFAZIA::ECodes::NORMAL_CALIBRATION);
46 PART->SetParameter(
"FAZIA.ESI1", esi1);
51 if (PART->GetIDCode() == KVFAZIA::IDCodes::ID_SI1_PSA) {
52 if (si1->IsCalibrated()) {
53 double esi1 = si1->GetEnergy();
54 PART->SetParameter(
"FAZIA.ESI1", esi1);
55 PART->SetEnergy(esi1);
56 SetCalibrationStatus(*PART, KVFAZIA::ECodes::NORMAL_CALIBRATION);
61 if (PART->GetIDCode() == KVFAZIA::IDCodes::ID_SI1_SI2
62 || PART->GetIDCode() == KVFAZIA::IDCodes::ID_SI1_SI2_MAYBE_PUNCH_THROUGH
63 || PART->GetIDCode() == KVFAZIA::IDCodes::ID_SI1_SI2_PUNCH_THROUGH) {
65 int calibstatus = (si1->IsCalibrated() << 0) + (si2->IsCalibrated() << 1);
66 int calculatedstatus = 0;
69 double esi1 = (si1->IsCalibrated() ? si1->GetEnergy() : 0);
70 double esi2 = (si2->IsCalibrated() ? si2->GetEnergy() : 0);
72 switch (calibstatus) {
77 esi1 = si1->GetDeltaEFromERes(PART->GetZ(), PART->GetA(), esi2);
78 calculatedstatus = SI1d;
82 esi2 = si1->GetEResFromDeltaE(PART->GetZ(), PART->GetA(), esi1);
83 calculatedstatus = SI2d;
90 PART->SetParameter(
"FAZIA.ESI1", ((calculatedstatus & SI1d) ? -esi1 : esi1));
91 PART->SetParameter(
"FAZIA.ESI2", ((calculatedstatus & SI2d) ? -esi2 : esi2));
92 PART->SetEnergy(esi1 + esi2);
93 SetCalibrationStatus(*PART, (calculatedstatus) ? KVFAZIA::ECodes::SOME_ENERGY_LOSSES_CALCULATED : KVFAZIA::ECodes::NORMAL_CALIBRATION);
98 if (PART->GetIDCode() == KVFAZIA::IDCodes::ID_SI1_CSI
99 || PART->GetIDCode() == KVFAZIA::IDCodes::ID_SI2_CSI
100 || PART->GetIDCode() == KVFAZIA::IDCodes::ID_SI12_CSI
101 || PART->GetIDCode() == KVFAZIA::IDCodes::ID_CSI_PSA) {
104 bool si1_pileup = PART->GetParameters()->GetBoolValue(
"si1_pileup");
105 bool si2_pileup = PART->GetParameters()->GetBoolValue(
"si2_pileup");
107 int calibstatus = (si1->IsCalibrated() << 0) + (si2->IsCalibrated() << 1) + (csi->IsCalibrated(part_id) << 2);
108 int calculatedstatus = 0;
111 double esi1 = (si1->IsCalibrated() ? si1->GetEnergy() : 0.);
112 double esi2 = (si2->IsCalibrated() ? si2->GetEnergy() : 0.);
113 double ecsi = (csi->IsCalibrated() ? csi->GetDetectorSignalValue(
"Energy", part_id) : 0.);
115 switch (calibstatus) {
116 case SI1d|SI2d|CSId: {
118 esi2 = si2->GetDeltaEFromERes(PART->GetZ(), PART->GetA(), ecsi);
119 esi1 = si1->GetDeltaEFromERes(PART->GetZ(), PART->GetA(), esi2 + ecsi);
121 calculatedstatus = SI1d | SI2d;
123 else if (si1_pileup) {
124 esi1 = si1->GetDeltaEFromERes(PART->GetZ(), PART->GetA(), esi2 + ecsi);
126 calculatedstatus = SI1d;
132 if (si1_pileup || si2_pileup)
break;
133 double deltaE = si1->GetEnergy() + si2->GetEnergy();
134 KVDetector si1si2(
"Si", si1->GetThickness() + si2->GetThickness());
137 calculatedstatus = CSId;
142 if (si2_pileup)
break;
143 double eres = esi2 + ecsi;
144 esi1 = si1->GetDeltaEFromERes(PART->GetZ(), PART->GetA(), eres);
146 calculatedstatus = SI1d;
151 if (si1_pileup)
break;
152 esi2 = si2->GetDeltaEFromERes(PART->GetZ(), PART->GetA(), ecsi);
153 calculatedstatus = SI2d;
159 if (si2_pileup)
break;
160 ecsi = si2->GetEResFromDeltaE(PART->GetZ(), PART->GetA(), esi2);
161 esi1 = si1->GetDeltaEFromERes(PART->GetZ(), PART->GetA(), esi2 + ecsi);
163 calculatedstatus = SI1d | CSId;
171 PART->SetParameter(
"FAZIA.ESI1", ((calculatedstatus & SI1d) ? -esi1 : esi1));
172 PART->SetParameter(
"FAZIA.ESI2", ((calculatedstatus & SI2d) ? -esi2 : esi2));
173 PART->SetParameter(
"FAZIA.ECSI", ((calculatedstatus & CSId) ? -ecsi : ecsi));
174 PART->SetEnergy(esi1 + esi2 + ecsi);
175 SetCalibrationStatus(*PART, calculatedstatus ? KVFAZIA::ECodes::ENERGY_LOSSES_TENTATIVELY_CALCULATED : KVFAZIA::ECodes::NORMAL_CALIBRATION);
180 if (PART->IsCalibrated()) {
184 if (PART->GetZ() && PART->GetEnergy() > 0) {
185 E_targ = GetTargetEnergyLossCorrection(PART);
186 PART->SetTargetEnergyLoss(E_targ);
188 Double_t E_tot = PART->GetEnergy() + E_targ;
189 PART->SetEnergy(E_tot);
192 PART->GetAnglesFromReconstructionTrajectory();
197 if ((det == csi) && (PART->GetZ() > 0) && (PART->GetZ() < 3) && (csi->GetDetectorSignalValue(
"Energy",
Form(
"Z=%d,A=%d", PART->GetZ(), PART->GetA())) > csi->GetMaxDeltaE(PART->GetZ(), PART->GetA())))
198 SetCalibrationStatus(*PART, KVFAZIA::ECodes::WARNING_CSI_MAX_ENERGY);
202 avatar.
SetZAandE(PART->GetZ(), PART->GetA(), PART->GetKE());
210 PART->GetReconstructionTrajectory()->IterateBackFrom();
211 while ((node = PART->GetReconstructionTrajectory()->GetNextNode())) {
214 PART->SetParameter(
Form(
"FAZIA.avatar.E%s", det->
GetLabel()), temp);
241 PART->
SetECode(KVFAZIA::ECodes::NO_CALIBRATION_ATTEMPTED);
244 if (PART->
GetIDCode() == KVFAZIA::IDCodes::ID_SI1_PSA) {
248 Warning(
"CalibrateCoherencyParticle",
249 "IDCODE=11 Z=%d A=%d calibrated SI1 E=%f",
260 if (PART->
GetIDCode() == KVFAZIA::IDCodes::ID_SI1_SI2) {
275 if (e1 > 0 && e2 > 0) {
390 bool si1_pileup(
false), si2_pileup(
false);
405 bool coherency_particle_added_in_si1si2 =
false;
413 if (si1si2->second->IDOK) {
417 partID = *(si1si2->second);
438 if ((si2csi->second->Z >
partID.
Z)) {
451 if (si1si2->second->Z >
partID.
Z) {
454 if (si1si2->second->IDOK) {
464 coherency_particle_added_in_si1si2 =
true;
471 if ((sipsa->second->Z >
partID.
Z)) {
473 if (sipsa->second->IDOK && !coherency_particle_added_in_si1si2) {
501 if (idr_si1si2->
IDOK && idr_si1si2->
IDcode == KVFAZIA::IDCodes::ID_SI1_SI2) {
502 if (zz < idr_si1si2->Z) {
506 partID = *(si1si2->second);
519 if (si1si2->second->IDOK) {
524 partID = *(si1si2->second);
540 if (sipsa->second->IDOK) {
543 partID = *(sipsa->second);
549 partID.
SetComment(
"particle partially identified by pulse shape analysis in SI1, although it is punching through (no SI2 signal or SI1-SI2 id)");
632 bool treat_punch_through =
true;
638 assert(!pt_flag.
End());
641 treat_punch_through = zrange.
Contains(idr->
Z);
643 if (treat_punch_through) {
644 bool pt_treated =
false;
647 idr->
IDcode = KVFAZIA::IDCodes::ID_SI1_SI2_MAYBE_PUNCH_THROUGH;
648 idr->
SetComment(
"Apparently well-identified particle, but could be punching through to CsI (in which case Z is a minimum)");
653 idr->
IDcode = KVFAZIA::IDCodes::ID_SI1_SI2_PUNCH_THROUGH;
654 idr->
SetComment(
"Particle punching through SI2, identified Z is only a minimum estimation");
677 assert(
csi !=
nullptr);
683 assert(
si1 !=
nullptr);
684 assert(
si2 !=
nullptr);
716 TMath::Abs(part.original_particle->GetParameters()->GetDoubleValue(
"FAZIA.ESI1"))
718 auto ESI2_parent = part.original_particle->GetParameters()->HasDoubleParameter(
"FAZIA.ESI2") ?
719 TMath::Abs(part.original_particle->GetParameters()->GetDoubleValue(
"FAZIA.ESI2"))
733 rnuc->SetReconstructionTrajectory(Rtraj);
735 rnuc->SetParameter(
"COHERENCY",
736 "Particle added to event after consistency checks between identifications and calibrations of other nuclei");
739 for (
int i = part.first_id_result_to_copy; i <= part.max_id_result_index; ++i) {
740 auto IDR = rnuc->GetIdentificationResult(idnumber++);
742 part.original_particle->GetIdentificationResult(i)->
Copy(*IDR);
744 rnuc->SetIsIdentified();
745 rnuc->SetIdentification(rnuc->GetIdentificationResult(1), part.identifying_telescope);
761 double new_q2{0}, new_qh1{0}, new_ql1{0};
775 if (rnuc->GetIDCode() == KVFAZIA::IDCodes::ID_SI1_SI2) {
783 part.identifying_telescope->Identify(&IDR);
787 *(rnuc->GetIdentificationResult(1)) = IDR;
788 rnuc->SetIdentification(rnuc->GetIdentificationResult(1), part.identifying_telescope);
798 if (part.original_particle->GetIdentificationResult(5)->IDOK) {
801 rnuc->ModifyReconstructionTrajectory(Rtraj);
802 part.original_particle->GetIdentificationResult(5)->
Copy(*rnuc->GetIdentificationResult(1));
803 auto idt = (
KVIDTelescope*)Rtraj->GetIDTelescopes()->First();
804 rnuc->SetIdentification(rnuc->GetIdentificationResult(1), idt);
821 if (rnuc->IsIdentified()) {
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t g
char * Form(const char *fmt,...)
virtual Bool_t IsType(const Char_t *typ) const
const Char_t * GetLabel() const
virtual void SetNumber(UInt_t num)
Bool_t IsLabelled(const Char_t *l) const
Base class for output signal data produced by a detector.
virtual Bool_t IsExpression() const
virtual Bool_t IsRaw() const
virtual Double_t GetValue(const KVNameValueList ¶ms="") const
Base class for detector geometry description.
void SetDetectorSignalValue(const KVString &type, Double_t val) const
Double_t GetInverseDetectorSignalValue(const KVString &output, Double_t value, const KVString &input, const KVNameValueList ¶ms="") const
virtual Double_t GetELostByParticle(KVNucleus *, TVector3 *norm=0)
virtual Double_t GetEnergy() const
Bool_t HasDetectorSignal(const KVString &type) const
Bool_t IsCalibrated() const
Double_t GetDetectorSignalValue(const KVString &type, const KVNameValueList ¶ms="") const
virtual Double_t GetCalibratedEnergy() const
const KVSeqCollection & GetListOfDetectorSignals() const
KVGeoDetectorNode * GetNode()
virtual Double_t GetDeltaEFromERes(Int_t Z, Int_t A, Double_t Eres)
Base class for FAZIA detectors.
Reconstruction of particles detected in FAZIA telescopes.
KVGeoDNTrajectory * theTrajectory
1 FAZIA group = 1 telescope with 1 unique trajectory SI1 - SI2 - CSI
KVIDTelescope * fSi1Si2IDTelescope
SI1-SI2 ID Telescope.
void AddCoherencyParticles()
void CalibrateCoherencyParticle(KVReconstructedNucleus *PART)
void ChangeReconstructedTrajectory(KVReconstructedNucleus &PART)
void SetGroup(KVGroup *g)
void IdentifyParticle(KVReconstructedNucleus &PART)
void HandleSI1SI2PunchThrough(KVIdentificationResult *, KVReconstructedNucleus &)
void PostReconstructionProcessing()
@ ID_INCOHERENT
particle with incoherent identifications (CCode>=0)
Path taken by particles through multidetector geometry.
KVGeoDetectorNode * GetNextNode() const
void IterateFrom(const KVGeoDetectorNode *node0=nullptr) const
const KVSeqCollection * GetIDTelescopes() const
void IterateBackFrom(const KVGeoDetectorNode *node0=nullptr) const
void Copy(TObject &obj) const
Information on relative positions of detectors & particle trajectories.
KVSeqCollection * GetTrajectories() const
KVSeqCollection * GetForwardTrajectories() const
KVDetector * GetDetector() const
KVGroup * GetGroup() const
std::unordered_map< std::string, KVIdentificationResult * > id_by_type
identification results by type for current particle
KVReconstructedEvent * GetEventFragment() const
Double_t GetTargetEnergyLossCorrection(KVReconstructedNucleus *ion)
void SetCalibrationStatus(KVReconstructedNucleus &PART, UShort_t code)
virtual void IdentifyParticle(KVReconstructedNucleus &)
KVIdentificationResult partID
identification to be applied to current particle
void TreatStatusStopFirstStage(KVReconstructedNucleus &)
virtual void SetGroup(KVGroup *g)
std::vector< particle_to_add_from_coherency_analysis > coherency_particles
Group of detectors which can be treated independently of all others in array.
KVGeoStrucElement * GetArray() const
const KVGeoDNTrajectory * GetTrajectoryForReconstruction(const KVGeoDNTrajectory *t, const KVGeoDetectorNode *n) const
Base class for all detectors or associations of detectors in array which can identify charged particl...
Full result of one attempted particle identification.
Bool_t IDOK
general quality of identification, =kTRUE if acceptable identification made
void SetComment(const Char_t *c)
Bool_t IdentifyingGridHasFlagWhichBegins(TString flag_beginning)
Bool_t Aident
= kTRUE if A of particle established
TString IdentifyingGridGetFlagWhichBegins(TString flag_beginning)
Int_t Z
Z of particle found (if Zident==kTRUE)
Int_t IDquality
specific quality code returned by identification procedure
Int_t IDcode
a general identification code for this type of identification
Bool_t Zident
=kTRUE if Z of particle established
virtual Double_t GetEResFromDeltaE(Int_t Z, Int_t A, Double_t dE=-1.0, enum SolType type=kEmax)
Handles lists of named parameters with different types, a list of KVNamedParameter objects.
void SetValue(const Char_t *name, value_type value)
Bool_t HasDoubleParameter(const Char_t *name) const
Description of properties and kinematics of atomic nuclei.
void SetZAandE(Int_t z, Int_t a, Double_t ekin)
Set atomic number, mass number, and kinetic energy in MeV.
Int_t GetZ() const
Return the number of proton / atomic number.
Strings used to represent a set of ranges of values.
Bool_t Contains(Int_t val) const
returns kTRUE if the value 'val' is contained in the ranges defined by the number list
KVNameValueList * GetParameters() const
Double_t GetEnergy() const
void SetKE(Double_t ecin)
void SetParameter(const Char_t *name, ValType value) const
void SetEnergy(Double_t e)
Path through detector array used to reconstruct detected particle.
Nuclei reconstructed from data measured by a detector array .
Int_t GetNumberOfIdentificationResults() const
Bool_t IsCalibrated() const
const KVReconNucTrajectory * GetReconstructionTrajectory() const
void SetIdentification(KVIdentificationResult *, KVIDTelescope *)
Bool_t IsIdentified() const
virtual Int_t GetIDCode() const
KVDetector * GetStoppingDetector() const
void SetDetector(int i, KVDetector *);
virtual void SetTargetEnergyLoss(Double_t e)
void ModifyReconstructionTrajectory(const KVReconNucTrajectory *t)
virtual void GetAnglesFromReconstructionTrajectory(Option_t *opt="random")
@ kStatusStopFirstStage
(arbitrarily) between this and the other particle(s) with Status=2
virtual void SetECode(UChar_t s)
virtual TObject * Last() const
virtual TObject * First() const
virtual TObject * FindObjectByType(const Char_t *) const
Extension of ROOT TString class which allows backwards compatibility with ROOT v3....
void Begin(TString delim) const
KVString Next(Bool_t strip_whitespace=kFALSE) const
Int_t GetNValues(TString delim) const
const char * GetName() const override
virtual void Warning(const char *method, const char *msgfmt,...) const
Double_t Max(Double_t a, Double_t b)