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};
26 PART->
SetECode(KVFAZIA::ECodes::NO_CALIBRATION_ATTEMPTED);
28 if (det == csi && PART->
GetIDCode() == KVFAZIA::IDCodes::ID_GAMMA) {
38 SetCalibrationStatus(*PART, KVFAZIA::ECodes::NORMAL_CALIBRATION);
43 if (PART->
GetIDCode() == KVFAZIA::IDCodes::ID_STOPPED_IN_FIRST_STAGE) {
47 SetCalibrationStatus(*PART, KVFAZIA::ECodes::NORMAL_CALIBRATION);
53 if (PART->
GetIDCode() == KVFAZIA::IDCodes::ID_SI1_PSA) {
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) {
68 int calculatedstatus = 0;
74 switch (calibstatus) {
80 calculatedstatus = SI1d;
85 calculatedstatus = SI2d;
92 PART->
SetParameter(
"FAZIA.ESI1", ((calculatedstatus & SI1d) ? -esi1 : esi1));
93 PART->
SetParameter(
"FAZIA.ESI2", ((calculatedstatus & SI2d) ? -esi2 : 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) {
110 int calculatedstatus = 0;
117 switch (calibstatus) {
118 case SI1d|SI2d|CSId: {
123 calculatedstatus = SI1d | SI2d;
125 else if (si1_pileup) {
128 calculatedstatus = SI1d;
134 if (si1_pileup || si2_pileup)
break;
137 ecsi = si1si2.GetEResFromDeltaE(PART->
GetZ(), PART->
GetA(), deltaE);
139 calculatedstatus = CSId;
144 if (si2_pileup)
break;
145 double eres = esi2 + ecsi;
148 calculatedstatus = SI1d;
153 if (si1_pileup)
break;
155 calculatedstatus = SI2d;
161 if (si2_pileup)
break;
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));
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);
188 E_targ = GetTargetEnergyLossCorrection(PART);
201 SetCalibrationStatus(*PART, KVFAZIA::ECodes::WARNING_CSI_MAX_ENERGY);
244 PART->
SetECode(KVFAZIA::ECodes::NO_CALIBRATION_ATTEMPTED);
247 if (PART->
GetIDCode() == KVFAZIA::IDCodes::ID_SI1_PSA) {
252 "IDCODE=11 Z=%d A=%d calibrated SI1 E=%f",
258 SetCalibrationStatus(*PART, KVFAZIA::ECodes::SOME_ENERGY_LOSSES_CALCULATED);
263 if (PART->
GetIDCode() == KVFAZIA::IDCodes::ID_SI1_SI2) {
278 if (e1 > 0 && e2 > 0) {
280 SetCalibrationStatus(*PART, KVFAZIA::ECodes::SOME_ENERGY_LOSSES_CALCULATED);
290 E_targ = GetTargetEnergyLossCorrection(PART);
326 void KVFAZIAGroupReconstructor::PostReconstructionProcessing()
387 KVGroupReconstructor::IdentifyParticle(PART);
390 auto si1si2 = id_by_type.find(
"Si-Si");
391 if (si1si2 != id_by_type.end()) HandleSI1SI2PunchThrough(si1si2->second, PART);
393 bool si1_pileup(
false), si2_pileup(
false);
400 TreatStatusStopFirstStage(PART);
407 if (partID.IsType(
"CsI")) {
408 bool coherency_particle_added_in_si1si2 =
false;
409 if (partID.IDcode == KVFAZIA::IDCodes::ID_GAMMA) {
415 if (si1si2 != id_by_type.end()) {
416 if (si1si2->second->IDOK) {
419 ChangeReconstructedTrajectory(PART);
420 partID = *(si1si2->second);
428 else if (partID.IDOK) {
432 auto si2csi = id_by_type.find(
"Si-CsI");
433 if (si2csi != id_by_type.end()) {
441 if ((si2csi->second->Z > partID.Z)) {
446 if (si1si2 != id_by_type.end()) {
454 if (si1si2->second->Z > partID.Z) {
457 if (si1si2->second->IDOK) {
461 coherency_particles.push_back({
462 &PART, si2->
GetNode(), theTrajectory,
467 coherency_particle_added_in_si1si2 =
true;
471 auto sipsa = id_by_type.find(
"SiPSA");
472 if (sipsa != id_by_type.end()) {
474 if ((sipsa->second->Z > partID.Z)) {
476 if (sipsa->second->IDOK && !coherency_particle_added_in_si1si2) {
481 coherency_particles.push_back({
482 &PART, si1->
GetNode(), theTrajectory,
494 else if (partID.IsType(
"Si-CsI")) {
502 if (si1si2 != id_by_type.end()) {
504 if (idr_si1si2->
IDOK && idr_si1si2->
IDcode == KVFAZIA::IDCodes::ID_SI1_SI2) {
505 if (zz < idr_si1si2->Z) {
508 ChangeReconstructedTrajectory(PART);
509 partID = *(si1si2->second);
521 if (si1si2 != id_by_type.end()) {
522 if (si1si2->second->IDOK) {
526 ChangeReconstructedTrajectory(PART);
527 partID = *(si1si2->second);
541 auto sipsa = id_by_type.find(
"SiPSA");
542 if (sipsa != id_by_type.end()) {
543 if (sipsa->second->IDOK) {
545 ChangeReconstructedTrajectory(PART);
546 partID = *(sipsa->second);
549 partID.Zident =
false;
550 partID.Aident =
false;
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);
689 assert(fSi1Si2IDTelescope !=
nullptr);
702 void KVFAZIAGroupReconstructor::AddCoherencyParticles()
711 for (
auto& part : coherency_particles) {
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"))
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) {
745 part.original_particle->GetIdentificationResult(i)->
Copy(*IDR);
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);
801 if (part.original_particle->GetIdentificationResult(5)->IDOK) {
806 auto idt = (
KVIDTelescope*)Rtraj->GetIDTelescopes()->First();
825 CalibrateCoherencyParticle(rnuc);
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,...)
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, 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
Double_t GetMaxDeltaE(Int_t Z, Int_t A) override
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 SetGroup(const KVGroup *g) 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
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
KVReconstructedEvent * GetEventFragment() const
virtual void SetGroup(const KVGroup *g)
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)
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
void Copy(TObject &) const override
Copy this to obj.
Bool_t Zident
=kTRUE if Z of particle established
virtual Double_t GetThickness() const
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 GetBoolValue(const Char_t *name) const
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.
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 .
void SetReconstructionTrajectory(const KVReconNucTrajectory *t)
Method called in initial reconstruction of particle.
@ kStatusStopFirstStage
(arbitrarily) between this and the other particle(s) with Status=2
Int_t GetNumberOfIdentificationResults() const
Bool_t IsCalibrated() const
KVIdentificationResult * GetIdentificationResult(Int_t i)
const KVReconNucTrajectory * GetReconstructionTrajectory() const
void SetIdentification(KVIdentificationResult *, KVIDTelescope *)
Bool_t IsIdentified() const
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")
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
void Warning(UserClass p, const char *location, const char *va_(fmt),...)
Double_t Max(Double_t a, Double_t b)