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) {
37 PART->SetEnergy(ecsi);
38 SetCalibrationStatus(*PART, KVFAZIA::ECodes::NORMAL_CALIBRATION);
39 PART->SetParameter(
"FAZIA.ECSI", ecsi);
43 if (PART->GetIDCode() == KVFAZIA::IDCodes::ID_STOPPED_IN_FIRST_STAGE) {
46 PART->SetEnergy(esi1);
47 SetCalibrationStatus(*PART, KVFAZIA::ECodes::NORMAL_CALIBRATION);
48 PART->SetParameter(
"FAZIA.ESI1", esi1);
53 if (PART->GetIDCode() == KVFAZIA::IDCodes::ID_SI1_PSA) {
54 if (si1->IsCalibrated()) {
55 double esi1 = si1->GetEnergy();
56 PART->SetParameter(
"FAZIA.ESI1", esi1);
57 PART->SetEnergy(esi1);
58 SetCalibrationStatus(*PART, KVFAZIA::ECodes::NORMAL_CALIBRATION);
63 if (PART->GetIDCode() == KVFAZIA::IDCodes::ID_SI1_SI2
64 || PART->GetIDCode() == KVFAZIA::IDCodes::ID_SI1_SI2_MAYBE_PUNCH_THROUGH
65 || PART->GetIDCode() == KVFAZIA::IDCodes::ID_SI1_SI2_PUNCH_THROUGH) {
67 int calibstatus = (si1->IsCalibrated() << 0) + (si2->IsCalibrated() << 1);
68 int calculatedstatus = 0;
71 double esi1 = (si1->IsCalibrated() ? si1->GetEnergy() : 0);
72 double esi2 = (si2->IsCalibrated() ? si2->GetEnergy() : 0);
74 switch (calibstatus) {
79 esi1 = si1->GetDeltaEFromERes(PART->GetZ(), PART->GetA(), esi2);
80 calculatedstatus = SI1d;
84 esi2 = si1->GetEResFromDeltaE(PART->GetZ(), PART->GetA(), esi1);
85 calculatedstatus = SI2d;
92 PART->SetParameter(
"FAZIA.ESI1", ((calculatedstatus & SI1d) ? -esi1 : esi1));
93 PART->SetParameter(
"FAZIA.ESI2", ((calculatedstatus & SI2d) ? -esi2 : esi2));
94 PART->SetEnergy(esi1 + esi2);
95 SetCalibrationStatus(*PART, (calculatedstatus) ? KVFAZIA::ECodes::SOME_ENERGY_LOSSES_CALCULATED : KVFAZIA::ECodes::NORMAL_CALIBRATION);
100 if (PART->GetIDCode() == KVFAZIA::IDCodes::ID_SI1_CSI
101 || PART->GetIDCode() == KVFAZIA::IDCodes::ID_SI2_CSI
102 || PART->GetIDCode() == KVFAZIA::IDCodes::ID_SI12_CSI
103 || PART->GetIDCode() == KVFAZIA::IDCodes::ID_CSI_PSA) {
106 bool si1_pileup = PART->GetParameters()->GetBoolValue(
"si1_pileup");
107 bool si2_pileup = PART->GetParameters()->GetBoolValue(
"si2_pileup");
109 int calibstatus = (si1->IsCalibrated() << 0) + (si2->IsCalibrated() << 1) + (csi->IsCalibrated(part_id) << 2);
110 int calculatedstatus = 0;
113 double esi1 = (si1->IsCalibrated() ? si1->GetEnergy() : 0.);
114 double esi2 = (si2->IsCalibrated() ? si2->GetEnergy() : 0.);
115 double ecsi = (csi->IsCalibrated(part_id) ? csi->GetDetectorSignalValue(
"Energy", part_id) : 0.);
117 switch (calibstatus) {
118 case SI1d|SI2d|CSId: {
120 esi2 = si2->GetDeltaEFromERes(PART->GetZ(), PART->GetA(), ecsi);
121 esi1 = si1->GetDeltaEFromERes(PART->GetZ(), PART->GetA(), esi2 + ecsi);
123 calculatedstatus = SI1d | SI2d;
125 else if (si1_pileup) {
126 esi1 = si1->GetDeltaEFromERes(PART->GetZ(), PART->GetA(), esi2 + ecsi);
128 calculatedstatus = SI1d;
134 if (si1_pileup || si2_pileup)
break;
135 double deltaE = si1->GetEnergy() + si2->GetEnergy();
136 KVDetector si1si2(
"Si", si1->GetThickness() + si2->GetThickness());
139 calculatedstatus = CSId;
144 if (si2_pileup)
break;
145 double eres = esi2 + ecsi;
146 esi1 = si1->GetDeltaEFromERes(PART->GetZ(), PART->GetA(), eres);
148 calculatedstatus = SI1d;
153 if (si1_pileup)
break;
154 esi2 = si2->GetDeltaEFromERes(PART->GetZ(), PART->GetA(), ecsi);
155 calculatedstatus = SI2d;
161 if (si2_pileup)
break;
162 ecsi = si2->GetEResFromDeltaE(PART->GetZ(), PART->GetA(), esi2);
163 esi1 = si1->GetDeltaEFromERes(PART->GetZ(), PART->GetA(), esi2 + ecsi);
165 calculatedstatus = SI1d | CSId;
173 PART->SetParameter(
"FAZIA.ESI1", ((calculatedstatus & SI1d) ? -esi1 : esi1));
174 PART->SetParameter(
"FAZIA.ESI2", ((calculatedstatus & SI2d) ? -esi2 : esi2));
175 PART->SetParameter(
"FAZIA.ECSI", ((calculatedstatus & CSId) ? -ecsi : ecsi));
176 PART->SetEnergy(esi1 + esi2 + ecsi);
177 if (PART->GetZ() <= 2 && calculatedstatus == CSId) SetCalibrationStatus(*PART, KVFAZIA::ECodes::ENERGY_LOSSES_TENTATIVELY_CALCULATED);
178 else SetCalibrationStatus(*PART, calculatedstatus ? KVFAZIA::ECodes::SOME_ENERGY_LOSSES_CALCULATED : KVFAZIA::ECodes::NORMAL_CALIBRATION);
183 if (PART->IsCalibrated()) {
187 if (PART->GetZ() && PART->GetEnergy() > 0) {
188 E_targ = GetTargetEnergyLossCorrection(PART);
189 PART->SetTargetEnergyLoss(E_targ);
191 Double_t E_tot = PART->GetEnergy() + E_targ;
192 PART->SetEnergy(E_tot);
195 PART->GetAnglesFromReconstructionTrajectory();
200 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())))
201 SetCalibrationStatus(*PART, KVFAZIA::ECodes::WARNING_CSI_MAX_ENERGY);
205 avatar.
SetZAandE(PART->GetZ(), PART->GetA(), PART->GetKE());
213 PART->GetReconstructionTrajectory()->IterateBackFrom();
214 while ((node = PART->GetReconstructionTrajectory()->GetNextNode())) {
217 PART->SetParameter(
Form(
"FAZIA.avatar.E%s", det->
GetLabel()), temp);
244 PART->
SetECode(KVFAZIA::ECodes::NO_CALIBRATION_ATTEMPTED);
247 if (PART->
GetIDCode() == KVFAZIA::IDCodes::ID_SI1_PSA) {
251 Warning(
"CalibrateCoherencyParticle",
252 "IDCODE=11 Z=%d A=%d calibrated SI1 E=%f",
263 if (PART->
GetIDCode() == KVFAZIA::IDCodes::ID_SI1_SI2) {
278 if (e1 > 0 && e2 > 0) {
393 bool si1_pileup(
false), si2_pileup(
false);
408 bool coherency_particle_added_in_si1si2 =
false;
416 if (si1si2->second->IDOK) {
420 partID = *(si1si2->second);
441 if ((si2csi->second->Z >
partID.
Z)) {
454 if (si1si2->second->Z >
partID.
Z) {
457 if (si1si2->second->IDOK) {
467 coherency_particle_added_in_si1si2 =
true;
474 if ((sipsa->second->Z >
partID.
Z)) {
476 if (sipsa->second->IDOK && !coherency_particle_added_in_si1si2) {
504 if (idr_si1si2->
IDOK && idr_si1si2->
IDcode == KVFAZIA::IDCodes::ID_SI1_SI2) {
505 if (zz < idr_si1si2->Z) {
509 partID = *(si1si2->second);
522 if (si1si2->second->IDOK) {
527 partID = *(si1si2->second);
543 if (sipsa->second->IDOK) {
546 partID = *(sipsa->second);
552 partID.
SetComment(
"particle partially identified by pulse shape analysis in SI1, although it is punching through (no SI2 signal or SI1-SI2 id)");
635 bool treat_punch_through =
true;
641 assert(!pt_flag.
End());
644 treat_punch_through = zrange.
Contains(idr->
Z);
646 if (treat_punch_through) {
647 bool pt_treated =
false;
650 idr->
IDcode = KVFAZIA::IDCodes::ID_SI1_SI2_MAYBE_PUNCH_THROUGH;
651 idr->
SetComment(
"Apparently well-identified particle, but could be punching through to CsI (in which case Z is a minimum)");
656 idr->
IDcode = KVFAZIA::IDCodes::ID_SI1_SI2_PUNCH_THROUGH;
657 idr->
SetComment(
"Particle punching through SI2, identified Z is only a minimum estimation");
680 assert(
csi !=
nullptr);
686 assert(
si1 !=
nullptr);
687 assert(
si2 !=
nullptr);
719 TMath::Abs(part.original_particle->GetParameters()->GetDoubleValue(
"FAZIA.ESI1"))
721 auto ESI2_parent = part.original_particle->GetParameters()->HasDoubleParameter(
"FAZIA.ESI2") ?
722 TMath::Abs(part.original_particle->GetParameters()->GetDoubleValue(
"FAZIA.ESI2"))
736 rnuc->SetReconstructionTrajectory(Rtraj);
738 rnuc->SetParameter(
"COHERENCY",
739 "Particle added to event after consistency checks between identifications and calibrations of other nuclei");
742 for (
int i = part.first_id_result_to_copy; i <= part.max_id_result_index; ++i) {
743 auto IDR = rnuc->GetIdentificationResult(idnumber++);
745 part.original_particle->GetIdentificationResult(i)->
Copy(*IDR);
747 rnuc->SetIsIdentified();
748 rnuc->SetIdentification(rnuc->GetIdentificationResult(1), part.identifying_telescope);
764 double new_q2{0}, new_qh1{0}, new_ql1{0};
778 if (rnuc->GetIDCode() == KVFAZIA::IDCodes::ID_SI1_SI2) {
786 part.identifying_telescope->Identify(&IDR);
790 *(rnuc->GetIdentificationResult(1)) = IDR;
791 rnuc->SetIdentification(rnuc->GetIdentificationResult(1), part.identifying_telescope);
801 if (part.original_particle->GetIdentificationResult(5)->IDOK) {
804 rnuc->ModifyReconstructionTrajectory(Rtraj);
805 part.original_particle->GetIdentificationResult(5)->
Copy(*rnuc->GetIdentificationResult(1));
806 auto idt = (
KVIDTelescope*)Rtraj->GetIDTelescopes()->First();
807 rnuc->SetIdentification(rnuc->GetIdentificationResult(1), idt);
824 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
void Warning(const char *method, const char *msgfmt,...) const override
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, interface to energy-loss calculations.
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
Bool_t IsCalibrated(const KVNameValueList ¶ms={}) const
virtual Double_t GetEnergy() const
Bool_t HasDetectorSignal(const KVString &type) const
Double_t GetDetectorSignalValue(const KVString &type, const KVNameValueList ¶ms="") const
virtual Double_t GetCalibratedEnergy() const
const KVSeqCollection & GetListOfDetectorSignals() const
KVGeoDetectorNode * GetNode()
Double_t GetDeltaEFromERes(Int_t Z, Int_t A, Double_t Eres) override
Double_t GetELostByParticle(KVNucleus *, TVector3 *norm=0) override
Base class for FAZIA detectors.
Reconstruction of particles detected in FAZIA telescopes.
void CalibrateCoherencyParticle(KVReconstructedNucleus *PART) override
void SetGroup(const KVGroup *g) override
KVGeoDNTrajectory * theTrajectory
1 FAZIA group = 1 telescope with 1 unique trajectory SI1 - SI2 - CSI
KVIDTelescope * fSi1Si2IDTelescope
SI1-SI2 ID Telescope.
void ChangeReconstructedTrajectory(KVReconstructedNucleus &PART)
void AddCoherencyParticles() override
void HandleSI1SI2PunchThrough(KVIdentificationResult *, KVReconstructedNucleus &)
void IdentifyParticle(KVReconstructedNucleus &PART) override
void PostReconstructionProcessing() override
@ 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
void Copy(TObject &obj) const override
const KVSeqCollection * GetIDTelescopes() const
void IterateBackFrom(const KVGeoDetectorNode *node0=nullptr) const
Information on relative positions of detectors & particle trajectories.
const KVSeqCollection * GetTrajectories() const
KVDetector * GetDetector() const
const KVSeqCollection * GetForwardTrajectories() const
KVGeoStrucElement * GetParentStructure(const Char_t *type, const Char_t *name="") const
KVGroup * GetGroup() const
std::unordered_map< std::string, KVIdentificationResult * > id_by_type
identification results by type for current particle
KVReconstructedEvent * GetEventFragment() const
virtual void SetGroup(const KVGroup *g)
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 &)
std::vector< particle_to_add_from_coherency_analysis > coherency_particles
Group of detectors which can be treated independently of all others in array.
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)
Base class for describing the geometry of a detector array.
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 .
@ kStatusStopFirstStage
(arbitrarily) between this and the other particle(s) with Status=2
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")
virtual void SetECode(UChar_t s)
TObject * First() const override
TObject * Last() const override
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
Double_t Max(Double_t a, Double_t b)