KaliVeda
Toolkit for HIC analysis
Loading...
Searching...
No Matches
KVINDRAEtalonGroupReconstructor.cpp
1//Created by KVClassFactory on Wed Feb 21 13:43:10 2018
2//Author: John Frankland,,,
3
4#include "KVINDRAEtalonGroupReconstructor.h"
5#include <string>
6#include <unordered_map>
7#include <iostream>
8#include <KVSilicon.h>
9#include "KVIDGCsI.h"
10using namespace std;
11
13
14
15
16
32
34{
35 // \param traj trajectory currently being scanned
36 // \param node current detector on trajectory to test
37 // \returns pointer to a new reconstructed particle added to this group's event; nullptr if nothing is to be done
38 //
39 // Specialised particle reconstruction for INDRA groups with etalon telescopes (Rings 10-17).
40 //
41 // If node is a CsI detector with more than one trajectory passing through it (in front of it),
42 // we are behind the etalons Si(75)-Si(Li).
43 //
44 // As the Si(75)-Si(Li) coders are opened by every firing of the CsI directly behind them,
45 // their acquisition parameters are present in the event whether the particle went through them
46 // or passed directly from ChIo to CsI.
47 //
48 // The best way to choose the right reconstruction trajectory is to see if Si(Li)-CsI
49 // provides an identification, and if so is it coherent with that of the CsI.
50
51 if (!node->GetDetector()->IsAnalysed() &&
52 node->GetDetector()->Fired(GetPartSeedCond()) &&
53 node->GetDetector()->IsType("CSI") &&
54 node->GetNTrajForwards() > 1) {
55 ++nfireddets;
56 const KVSeqCollection* idt_list = traj->GetIDTelescopes();
57 TIter next_idt(idt_list);
58 KVIDTelescope* idt;
59 bool with_etalon = (traj->GetN() == 4);
60
61 std::unordered_map<std::string, KVIdentificationResult> IDR;
62 while ((idt = (KVIDTelescope*)next_idt())) {
63 if (idt->IsReadyForID()) { // is telescope able to identify for this run ?
64 idt->Identify(&IDR[idt->GetType()]);
65 }
66 }
67 // cases:
68 // gamma in CsI: * same as general INDRA reconstruction: count the gammmas, do not
69 // reconstruct a particle (but set CsI analysed state)
70 // particle identified in CsI:
71 // * if this is the long trajectory, check the SILI-CSI identification
72 // if SILI-CSI identification no good, then short trajectory should be used
73 // so we return nullptr
74 // * if this is the short trajectory, we accept it
75 KVIdentificationResult& idcsi = IDR["CSI_R_L"];
76 if (idcsi.IDattempted) {
77 if (idcsi.IDOK) {
79 // gamma
80 //Info("ReconstructTrajectory","Gamma in CsI: with_etalon=%d",with_etalon);
81 GetEventFragment()->GetParameters()->IncrementValue("INDRA_GAMMA_MULT", 1);
82 GetEventFragment()->GetParameters()->IncrementValue("INDRA_GAMMA_DETS", node->GetName());
83 node->GetDetector()->SetAnalysed();
84 return nullptr;
85 }
86 else { // charged particle identified
87 //Info("ReconstructTrajectory","Charged particle in CsI: with_etalon=%d",with_etalon);
88 if (with_etalon) {
89 if (IDR["SILI_CSI"].IDattempted && IDR["SILI_CSI"].IDOK) {
90 //Info("ReconstructTrajectory","Charged particle in SILI too Zcsi=%d Zsili=%d",idcsi.Z,IDR["SILI_CSI"].Z);
91 return GetEventFragment()->AddParticle();
92 }
93 else return nullptr;
94 }
95 else
96 return GetEventFragment()->AddParticle();
97 }
98 }
99 }
100 return nullptr;
101 }
102 // standard non-etalon treatment
104}
105
106
107
112
114{
115 // Coherency analysis for etalon groups on rings 10-17 of INDRA
116 // Note that the treatment of all modules in the group except the one with the etalons
117 // is standard (KVINDRABackwardGroupReconstructor), but all modules will call here first
118
119 if (!GetSi75(&PART) && !GetSiLi(&PART)) // => no etalons in particle trajectory
121
122 PART.SetParameter("UseFullChIoEnergyForCalib", !(theChio && theChio->GetNHits() > 1));
123 bool ok = CoherencyEtalons(PART);
124
125 return ok;
126}
127
128
129
132
134{
135 // Calibration of particle stopping in etalon modules
136
137 fESiLi = fESi75 = 0;
138
139 if (!GetSi75(PART) && !GetSiLi(PART)) // => no etalons in particle trajectory
141
142 // change fUseFullChioenergyforcalib for "coherency" particles
143 // we assume they are calibrated after all other particles in group have
144 // been identified, calibrated, and their energy contributions removed
145 // from the ChIo
149 PART->SetParameter("UseFullChIoEnergyForCalib", kTRUE);
150
151 Bool_t stopped_in_chio = kTRUE;
152 auto csi = GetCsI(PART);
153 if (csi) {
154 stopped_in_chio = kFALSE;
155 if (csi->IsCalibrated()) {
156 /* CSI ENERGY CALIBRATION */
157 if (PART->GetIDCode() == KVINDRA::IDCodes::ID_CSI_PSA && PART->IsIsotope(4, 8)) {
159 }
160 else
161 fECsI = csi->GetCorrectedEnergy(PART, -1., kFALSE);
162 }
163 else {
165 return;
166 }
167 if (fECsI <= 0 && (PART->GetECode() != KVINDRA::ECodes::SOME_ENERGY_LOSSES_CALCULATED)) { // DoBeryllium8Calibration returns fECsI<0 with ECode=SOME_ENERGY_LOSSES_CALCULATED if OK
168 SetBadCalibrationStatus(PART);// problem with CsI energy - no calibration
169 return;
170 }
171 }
172 if (PART->GetParameters()->GetBoolValue("IncludeEtalonsInCalibration")) {
173 auto sili = GetSiLi(PART);
174 if (sili) {
175 bool stopped_in_sili = PART->GetStoppingDetector()->IsType("SILI");
176 Double_t ERES = TMath::Abs(fECsI);
177 if (!PART->GetParameters()->GetBoolValue("PileupSiLi") && sili->IsCalibrated()) {
178 Bool_t si_transmission = kTRUE;
179 if (stopped_in_sili) {
180 si_transmission = kFALSE;
181 }
182 else {
183 sili->SetEResAfterDetector(ERES);
184 }
185 fESiLi = sili->GetCorrectedEnergy(PART, -1., si_transmission);
186 if (fESiLi <= 0) {
187 if (!stopped_in_sili && ERES > 0.0) {
188 if (!CalculateSiLiDEFromResidualEnergy(ERES, sili, PART)) return;
189 }
190 else {
192 return;
193 }
194 }
195 }
196 else {
197 if (!CalculateSiLiDEFromResidualEnergy(ERES, sili, PART)) return;
198 }
199 }
200 auto si75 = GetSi75(PART);
201 if (si75) {
202 bool stopped_in_si75 = PART->GetStoppingDetector()->IsType("SI75");
204 if (!PART->GetParameters()->GetBoolValue("PileupSi75")
205 && !PART->GetParameters()->GetBoolValue("PileupSiLi")
206 && si75->IsCalibrated()) {
207 Bool_t si_transmission = kTRUE;
208 if (stopped_in_si75) {
209 si_transmission = kFALSE;
210 }
211 else {
212 si75->SetEResAfterDetector(ERES);
213 }
214 fESi75 = si75->GetCorrectedEnergy(PART, -1., si_transmission);
215 if (fESi75 <= 0) {
216 if (!stopped_in_si75 && ERES > 0.0) {
217 if (!CalculateSi75DEFromResidualEnergy(ERES, si75, PART)) return;
218 }
219 else {
221 return;
222 }
223 }
224 }
225 else {
226 if (!CalculateSi75DEFromResidualEnergy(ERES, si75, PART)) return;
227 }
228 }
229 }
230 if (theChio) {
231 /* IONISATION CHAMBER ENERGY CONTRIBUTION */
232 // if fUseFullChIoEnergyForCalib = kFALSE, ChIo was hit by other particles in group
233 // therefore we have to estimate the ChIo energy for this particle using the CsI energy
234 // if fPileupChIo = kTRUE, there appears to be another particle stopped in the ChIo
235 // therefore we have to estimate the ChIo energy for this particle using the CsI energy
237 if (!PART->GetParameters()->GetBoolValue("PileupChIo")
238 && PART->GetParameters()->GetBoolValue("UseFullChIoEnergyForCalib")
239 && theChio->IsCalibrated()) {
240 // all is apparently well
241 Bool_t ci_transmission = kTRUE;
242 if (stopped_in_chio) {
243 ci_transmission = kFALSE;
244 }
245 else {
247 }
248 fEChIo = theChio->GetCorrectedEnergy(PART, -1., ci_transmission);
249 if (fEChIo <= 0) {
250 if (!stopped_in_chio && ERES > 0) {
251 if (!CalculateChIoDEFromResidualEnergy(PART, ERES)) return;
252 }
253 }
254 }
255 else {
256 if (!stopped_in_chio && ERES > 0) {
257 if (!CalculateChIoDEFromResidualEnergy(PART, ERES)) return;
258 }
259 }
260 }
261
263}
264
265
266
269
271{
272 // Called by Identify() for particles stopping in etalon modules of Rings 10-17.
273
274 KVIdentificationResult* IDcsi, *IDsilicsi, *IDsi75sili, *IDcisi75, *IDcicsi;
275 IDcsi = IDsilicsi = IDsi75sili = IDcisi75 = IDcicsi = nullptr;
276 if (PART.GetStoppingDetector()->IsType("CSI")) {
277 IDcsi = PART.GetIdentificationResult("CSI_R_L");
278 IDcicsi = PART.GetIdentificationResult("CI_CSI");
279 IDsilicsi = PART.GetIdentificationResult("SILI_CSI");
280 }
281 IDsi75sili = PART.GetIdentificationResult("SI75_SILI");
282 IDcisi75 = PART.GetIdentificationResult("CI_SI75");
283
284 PART.SetParameter("PileupChIo", kFALSE);
285 PART.SetParameter("IncludeEtalonsInCalibration", kTRUE);
286
287 Bool_t haveCsI = IDcsi && IDcsi->IDOK;
288 Bool_t haveSiLiCsI = IDsilicsi && IDsilicsi->IDOK;
289 Bool_t haveSi75SiLi = IDsi75sili && IDsi75sili->IDOK;
290 Bool_t haveChIoSi75 = IDcisi75 && IDcisi75->IDOK;
291
292 KVIDTelescope* idt_csi, *idt_silicsi, *idt_si75sili, *idt_cisi75, *idt_cicsi;
293 idt_csi = idt_silicsi = idt_si75sili = idt_cisi75 = idt_cicsi = nullptr;
294 if (PART.GetStoppingDetector()->IsType("CSI")) {
295 idt_csi =
297 idt_silicsi =
299 idt_cicsi =
301 }
302 idt_si75sili = (KVIDTelescope*)PART.GetReconstructionTrajectory()->GetIDTelescopes()->FindObjectByType(IDsi75sili->GetType());
304
305 // Treat cases where particle hit etalon telescope
306 if (idt_csi) {
307 if (haveCsI) {
308
309 partID = *IDcsi;
310 identifying_telescope = idt_csi;
311
312 if (haveSi75SiLi) {
313 // check for heavy fragment in Si75-SiLi
314 if (IDsi75sili->Z > partID.Z) {
315 if (haveChIoSi75) {
316 // check we don't have a better identification in ChIo-Si75
317 if (IDcisi75->IDquality < IDsi75sili->IDquality && IDcisi75->Z > partID.Z) {
318 PART.SetParameter("PileupSi75", kTRUE);
319 IDcisi75->SetComment("CsI identification with another particle stopped in Si75");
320 PART.SetParameter("UseFullChIoEnergyForCalib", kFALSE); // calculate ChIo energy for this particle
321 }
322 else {
323 PART.SetParameter("PileupSiLi", kTRUE);
324 IDsi75sili->SetComment("CsI identification with another particle stopped in SiLi");
325 PART.SetParameter("UseFullChIoEnergyForCalib", kFALSE); // calculate ChIo energy for this particle
326 }
327 }
328 }
329 }
330 else if (haveChIoSi75) {
331 // check for heavy fragment in ChIo-Si75
332 if (IDcisi75->Z > partID.Z) {
333 PART.SetParameter("PileupSi75", kTRUE);
334 IDcisi75->SetComment("CsI identification with another particle stopped in Si75");
335 PART.SetParameter("UseFullChIoEnergyForCalib", kFALSE); // calculate ChIo energy for this particle
336 }
337 }
338 return kTRUE;
339 }
340 else if (haveSiLiCsI) {
341 partID = *IDsilicsi;
342 identifying_telescope = idt_silicsi;
343 if (haveChIoSi75) {
344 // check for heavy fragment in ChIo-Si75
345 if (IDcisi75->Z > partID.Z) {
346 PART.SetParameter("PileupSi75", kTRUE);
347 IDcisi75->SetComment("CsI identification with another particle stopped in Si75");
348 PART.SetParameter("UseFullChIoEnergyForCalib", kFALSE); // calculate ChIo energy for this particle
349 }
350 }
351 return kTRUE;
352 }
353 }
354 else if (PART.GetStoppingDetector()->IsType("SILI")) {
355 if (haveSi75SiLi) {
356 partID = *IDsi75sili;
357 identifying_telescope = idt_si75sili;
358 // check ChIo-Si75 id is coherent (either no id or Z<=this one)
359 if (haveChIoSi75) {
360 if (IDcisi75->Z > partID.Z) PART.SetParameter("PileupChIo", kTRUE);
361 }
362 return kTRUE;
363 }
364 else if (haveChIoSi75) {
365 partID = *IDcisi75;
366 identifying_telescope = idt_cisi75;
367 return kTRUE;
368 }
369 }
370 else if (PART.GetStoppingDetector()->IsType("SI75")) { // MFR march 2014 SiLi is not the real stopping detector
371 if (haveChIoSi75) {
372 partID = *IDcisi75;
373 identifying_telescope = idt_cisi75;
374 return kTRUE;
375 } // end MFR march 2014
376 }
377
378 return kFALSE;
379}
380
381
382
386
388{
389 // Etalon modules
390 // calculate fESiLi from residual CsI energy
391 Double_t e0 = sili->GetDeltaEFromERes(n->GetZ(), n->GetA(), ERES);
392 sili->SetEResAfterDetector(ERES);
393 fESiLi = sili->GetCorrectedEnergy(n, e0);
394 if (fESiLi <= 0) {
395 fESiLi = 0;
397 return kFALSE;
398 }
401 return kTRUE;
402}
403
404
405
409
411{
412 // Etalon modules
413 // calculate fESi75 from residual CsI+SiLi energy
414 Double_t e0 = si75->GetDeltaEFromERes(n->GetZ(), n->GetA(), ERES);
415 si75->SetEResAfterDetector(ERES);
416 fESi75 = si75->GetCorrectedEnergy(n, e0);
417 if (fESi75 <= 0) {
418 fESi75 = 0;
420 return kFALSE;
421 }
424 return kTRUE;
425}
426
427
bool Bool_t
constexpr Bool_t kFALSE
double Double_t
constexpr Bool_t kTRUE
virtual Bool_t IsType(const Char_t *typ) const
Definition KVBase.h:185
virtual const Char_t * GetType() const
Definition KVBase.h:177
Base class for detector geometry description.
Definition KVDetector.h:160
Int_t GetNHits() const
Return the number of particles hitting this detector in an event.
Definition KVDetector.h:436
Bool_t IsCalibrated() const
Definition KVDetector.h:390
virtual void SetEResAfterDetector(Double_t e)
Definition KVDetector.h:630
virtual Double_t GetDeltaEFromERes(Int_t Z, Int_t A, Double_t Eres)
virtual Double_t GetCorrectedEnergy(KVNucleus *, Double_t e=-1., Bool_t transmission=kTRUE)
Path taken by particles through multidetector geometry.
const KVSeqCollection * GetIDTelescopes() const
Information on relative positions of detectors & particle trajectories.
KVIDTelescope * identifying_telescope
telescope which identified current particle
void SetCalibrationStatus(KVReconstructedNucleus &PART, UShort_t code)
KVIdentificationResult partID
identification to be applied to current particle
Base class for all detectors or associations of detectors in array which can identify charged particl...
virtual Bool_t IsReadyForID()
virtual Bool_t Identify(KVIdentificationResult *, Double_t x=-1., Double_t y=-1.)
void DoCalibration(KVReconstructedNucleus *PART)
bool DoCoherencyAnalysis(KVReconstructedNucleus &PART)
Coherency analysis for backward rings 10-17 of INDRA.
Reconstruct particles in INDRA groups with etalon telescopes.
Bool_t CoherencyEtalons(KVReconstructedNucleus &PART)
Called by Identify() for particles stopping in etalon modules of Rings 10-17.
void DoCalibration(KVReconstructedNucleus *PART)
Calibration of particle stopping in etalon modules.
KVDetector * GetSi75(KVReconstructedNucleus *n)
Bool_t CalculateSi75DEFromResidualEnergy(Double_t ERES, KVDetector *si75, KVReconstructedNucleus *n)
Bool_t CalculateSiLiDEFromResidualEnergy(Double_t ERES, KVDetector *sili, KVReconstructedNucleus *n)
KVDetector * GetSiLi(KVReconstructedNucleus *n)
bool DoCoherencyAnalysis(KVReconstructedNucleus &PART)
void SetNoCalibrationStatus(KVReconstructedNucleus *n)
Bool_t CalculateChIoDEFromResidualEnergy(KVReconstructedNucleus *n, Double_t ERES)
double DoBeryllium8Calibration(KVReconstructedNucleus *n)
KVDetector * GetCsI(KVReconstructedNucleus *n)
void SetBadCalibrationStatus(KVReconstructedNucleus *n)
KVReconstructedNucleus * ReconstructTrajectory(const KVGeoDNTrajectory *traj, const KVGeoDetectorNode *node)
KVDetector * theChio
the ChIo of the group
@ SOME_ENERGY_LOSSES_CALCULATED
particle calibration OK, with some detector energies calculated
Definition KVINDRA.h:210
@ ID_CI_SI_COHERENCY
particle identified in ChIo-Si telescope in coincidence with light particle identified in CsI
Definition KVINDRA.h:172
@ ID_CSI_PSA
particle identified in CsI detector by pulse shape analysis
Definition KVINDRA.h:165
@ ID_CI_COHERENCY
particle stopped in ChIo revealed by coherency tests (Zmin)
Definition KVINDRA.h:173
@ ID_CI_MULTIHIT
particles stopped in multiple Si (ring<10) or CsI (ring>9) behind same ChIo, bad identification
Definition KVINDRA.h:174
@ ID_GAMMA
'gamma' particle detected in CsI
Definition KVINDRA.h:162
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 SetComment(const Char_t *c)
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 GetBoolValue(const Char_t *name) const
Bool_t IsIsotope(Int_t Z, Int_t A) const
Definition KVNucleus.h:334
void SetParameter(const Char_t *name, ValType value) const
Definition KVParticle.h:819
KVNameValueList * GetParameters() const
Definition KVParticle.h:815
void SetEnergy(Double_t e)
Definition KVParticle.h:599
Nuclei reconstructed from data measured by a detector array .
KVIdentificationResult * GetIdentificationResult(Int_t i)
virtual Int_t GetECode() const
KVDetector * GetStoppingDetector() const
void SetDetector(int i, KVDetector *);
virtual Int_t GetIDCode() const
const KVReconNucTrajectory * GetReconstructionTrajectory() const
KaliVeda extensions to ROOT collection classes.
virtual TObject * FindObjectByType(const Char_t *) const
const Int_t n
Double_t Abs(Double_t d)
ClassImp(TPyArg)