Belle II Software development
ECLBackgroundModule.cc
1/**************************************************************************
2 * basf2 (Belle II Analysis Software Framework) *
3 * Author: The Belle II Collaboration *
4 * *
5 * See git log for contributors and copyright holders. *
6 * This file is licensed under LGPL-3.0, see LICENSE.md. *
7 **************************************************************************/
8
9/* Own header. */
10#include <ecl/modules/eclBackgroundStudy/ECLBackgroundModule.h>
11
12/* ECL headers. */
13#include <ecl/dataobjects/ECLShower.h>
14#include <ecl/dataobjects/ECLSimHit.h>
15#include <ecl/modules/eclBackgroundStudy/ECLCrystalData.h>
16
17/* Basf2 headers. */
18#ifdef DOARICH
19# include <arich/geometry/ARICHGeometryPar.h>
20#endif
21#include <framework/logging/Logger.h>
22#include <mdst/dataobjects/MCParticle.h>
23#include <simulation/dataobjects/BeamBackHit.h>
24
25/* ROOT headers. */
26#include <Math/Vector3D.h>
27#include <TH1F.h>
28#include <TH2F.h>
29#include <TMath.h>
30
31using namespace std;
32using namespace Belle2;
33
34//-----------------------------------------------------------------
35// Register the Module
36//-----------------------------------------------------------------
37REG_MODULE(ECLBackground);
38
39//-----------------------------------------------------------------
40// Implementation
41//-----------------------------------------------------------------
42
43
45{
46 //Set module properties
47 setDescription("Processes background campaigns and produces histograms. Requires HistoManager");
48
49 std::vector<int> empty;
50 addParam("sampleTime", m_sampleTime, "Length of sample, in us", 1000);
51 addParam("doARICH", m_doARICH, "If true, some ARICH plots (for shielding studies) will be produced", false);
52 addParam("crystalsOfInterest", m_CryInt, "Cell ID of crystals of interest. Dose will be printed at end of run", empty);
53
54}
55
59
60//If a histogram is initialized here, it will be saved.
62{
63 std::ostringstream s;
64 s << m_sampleTime;
65
66 //initialize histograms
67 h_nECLSimHits = new TH1F("ECL_Sim_Hits", "ECL Sim Hits", 100, 0, 100);
68
69
70 //Radiation dose
71 h_CrystalRadDose = new TH1F("Crystal_Rad_Dose", "Crystal Radiation Dose vs #theta_{ID};#theta_{ID};Gy/yr", 69, -0.5, 68.5);
72 h_CrystalRadDoseTheta = new TH1F("Crystal_Rad_Dose_Theta", "Crystal Radiation Dose vs #theta;#theta (deg);Gy/yr", 100, 12, 152);
73 h_CrystalThetaID2 = new TH1F("Crystal_Dose_ThetaID_2", "Crystal Radiation Dose vs #phi_{ID}, #theta_{ID}=2; #phi_{ID};Gy/yr", 64,
74 -0.5, 63.5);
75 h_CrystalThetaID67 = new TH1F("Crystal_Dose_ThetaID_67", "Crystal Radiation Dose vs #phi_{ID}, #theta_{ID}=67; #phi_{ID};Gy/yr", 64,
76 -0.5, 63.5);
77 h_BarrelDose = new TH1F("Crystal_Dose_Barrel", "Crystal Radiation Dose in Barrel, 12<#theta_{ID}<59; #phi_{ID}; Gy/yr", 144, -0.5,
78 143.5);
79 h_DiodeRadDose = new TH1F("Diode_Rad_Dose", "Diode Radiation Dose vs #theta_{ID};#theta_{ID};Gy/yr", 69, -0.5, 68.5);
80
81 //hit locations
82 h_ProdVert = new TH1F("MCProd_Vert", "Production Vertex;z (cm)", 125, -200, 300);
83 h_HitLocations = new TH2F("Hit_Locations", "Hit locations;z (cm); r (cm)", 250, -200, 300, 80, 0, 160);
84 h_ProdVertvsThetaId = new TH2F("MCProd_Vert_vs_ThetaID", "Production Vertex vs #theta_{ID};#theta_{ID};z (cm)", 69, -0.5, 68.5, 125,
85 -200, 300);
86 hEdepPerRing = new TH1F("hEdepPerRing", "Energy deposited per #theta_{ID};#theta_{ID}; GeV", 69, -0.5, 68.5);
87 hNevtPerRing = new TH1F("hNevtPerRing", "Number of events #theta_{ID} (for pile-up);#theta_{ID};N_{event}", 69, -0.5, 68.5);
88
89
90
91 //Neutrons
92 h_NeutronFluxThetaID2 = new TH1F("Neutron_Flux_ThetaID_2", "Diode Neutron Flux, #theta_{ID}=2;#phi_{ID}; yr^{-1}/cm^{-2}", 64, -0.5,
93 63.5);
94 h_NeutronFluxThetaID67 = new TH1F("Neutron_Flux_ThetaID_67", "Diode Neutron Flux, #theta_{ID}=67;#phi_{ID}; yr^{-1}/cm^{-2}", 64,
95 -0.5, 63.5);
96 h_NeutronFlux = new TH1F("Neutron_Flux", "Diode Neutron Flux vs #theta_{ID};#theta_{ID}; yr^{-1}/cm^{-2}", 69, -0.5, 68.5);
97 h_NeutronE = new TH1F("Neutron_Energy", "Neutron Energy; Energy (MeV)", 200, 0, 0.5);
98 h_NeutronEThetaID0 = new TH1F("Neutron_Energy_ThetaID0", "Neutron Energy, First Crystal; Energy (MeV)", 50, 0, 0.5);
99
100 h_PhotonE = new TH1F("Photon_Energy", "Energy of photons creating hits in ECL; Energy (MeV)", 200, 0, 10);
101
102 //showers
103 TString stime = s.str();
104 h_Shower = new TH1F("Shower_E_Dist", "Shower Energy distribution " + stime + " #mu s;GeV;# of showers", 100, 0, 0.5);
105 h_ShowerVsTheta = new TH2F("Shower_E_Dist_vs_theta", "Shower Energy distribution " + stime + " #mu s;GeV;#theta (deg)", 100, 0, 0.5,
106 180, 0, 180);
107
108
109
110 //
111 // Below are for the ECL shields studies
112 //
114
115 //Doses
116 hEMDose = new TH1F("hEMDose", "Crystal Radiation Dose; Cell ID ; Gy/yr", ECLElementNumbers::c_NCrystals, 0,
118 hEnergyPerCrystal = new TH1F("hEnergyPerCrystal", "Energy per crystal; Cell ID; GeV", ECLElementNumbers::c_NCrystals, 0,
120
121 //Diodes
122 hDiodeFlux = new TH1F("hDiodeFlux", "Diode Neutron Flux ; Cell ID ; 1MeV-equiv / cm^{2} yr", ECLElementNumbers::c_NCrystals, 0,
124
125 //Radiation spectra
126 hEgamma = new TH1F("hEgamma", "Log Spectrum of the photons hitting the crystals / 1 MeV; log_{10}(E_{#gamma}/1MeV) ", 500, -4, 3);
127 hEneu = new TH1F("hEneu", "Log Spectrum of the neutrons hitting the diodes / 1 MeV; log_{10}(E_{n}/1MeV)", 500, -10, 2);
128
129 //ARICH plots
130 if (m_doARICH) {
131 hARICHDoseBB = new TH1F("hARICHDoseBB", "Radiation dose in ARICH boards (cBB); Ring-ID; Gy/yr", 7, -0.5, 6.5);
132 hHAPDFlux = new TH1F("hARICHnFlux", "1-MeV equivalent neutron flux in ARICH diodes (BB) ; Ring-ID ; 1-MeV-equiv / cm^{2} yr", 7,
133 -0.5, 6.5);
134 }
135
136 hEMDoseECF = new TH2F();
137 hEMDoseECB = new TH2F();
138 hEMDoseBAR = new TH2F();
139 hEMDoseWideTID = new TH1F();
140
141 hDiodeFluxECF = new TH2F();
142 hDiodeFluxECB = new TH2F();
143 hDiodeFluxBAR = new TH2F();
144 hDiodeFluxWideTID = new TH1F();
145
146 hEnergyPerCrystalECF = new TH2F();
147 hEnergyPerCrystalECB = new TH2F();
148 hEnergyPerCrystalBAR = new TH2F();
149 hEnergyPerCrystalWideTID = new TH1F();
150
151
152
153}
154
156{
157
158 REG_HISTOGRAM
159
160 if (m_doARICH) {
161 B2INFO("ECLBackgroundModule: ARICH plots are being produced");
162 // Initialize variables
163#ifdef DOARICH
164 m_arichgp = ARICHGeometryPar::Instance();
165#endif
166 }
167
168 m_nEvent = 0;
169 BuildECL();
170
171}
172
174{
175
176
177
178 //some variables that will be used many times
179 int m_cellID, m_thetaID, m_phiID, pid, NperRing;
180 double edep, theta, Energy, diodeDose, weightedFlux;
181
182 //ignore events with huge number of SimHits (usually a glitchy event)
183 if (m_eclArray.getEntries() > 4000) {
184 B2INFO("ECLBackgroundModule: Skipping event #" << m_nEvent << " due to large number of ECLSimHits");
185 m_nEvent++;
186 return;
187 }
188
189 bool isE = false;
190 //bool EinTheta[nECLThetaID] = {false};
191
192 double edepSum = 0;
193 //double edepSumTheta[nECLThetaID] = {0};
194 //double E_tot[ECLElementNumbers::c_NCrystals] = {0};
195
196
197 auto edepSumTheta = new double[nECLThetaID]();
198 auto E_tot = new double[ECLElementNumbers::c_NCrystals]();
199
200 auto EinTheta = new bool[nECLThetaID]();
201 std::fill_n(EinTheta, nECLThetaID, false);
202
203
204 h_nECLSimHits->Fill(m_eclArray.getEntries()); //number of ECL hits in an event
205
206 //MC ID of photon hits
207 vector<int> MCPhotonIDs;
208
209 int hitNum = m_eclArray.getEntries();
210 for (int i = 0; i < hitNum; i++) { //loop over ECLSimHits
211 const ECLSimHit* aECLHit = m_eclArray[i];
212 m_cellID = aECLHit->getCellId() - 1; //cell ID
213 edep = aECLHit->getEnergyDep(); //energy deposited
214 G4ThreeVector hitPosn = aECLHit->getPosition(); //position of hit
215 pid = aECLHit->getPDGCode();
216 float Mass = Crystal[m_cellID]->GetMass();
217 m_thetaID = Crystal[m_cellID]->GetThetaID();
218 m_phiID = Crystal[m_cellID]->GetPhiID();
219 NperRing = Crystal[m_cellID]->GetNperThetaID(); //number of crystals in this theta ring
220 theta = Crystal[m_cellID]->GetTheta();
221
222
223 //get Track ID of photons which create the SimHits
224 if (pid == 22) MCPhotonIDs.push_back(aECLHit->getTrackId());
225
226 edepSum = edepSum + edep;
227 E_tot[m_cellID] = edep + E_tot[m_cellID]; //sum energy deposited in this crystal
228 edepSumTheta[m_thetaID] = edepSumTheta[m_thetaID] + edep; //sum of energy for this thetaID value
229 EinTheta[m_thetaID] = true; //there is an energy deposit in this theta ring. used later
230 isE = true;
231
232
233 //fill histograms
234 //radiation dose for this SimHit
235 double dose = edep * GeVtoJ * usInYr / (m_sampleTime * Mass);
236
237 h_CrystalRadDoseTheta->Fill(theta, dose / NperRing);
238 h_CrystalRadDose->AddBinContent(m_thetaID + 1, dose / NperRing);
239 hEMDose->AddBinContent(m_cellID + 1, dose);
240 hEnergyPerCrystal->AddBinContent(m_cellID + 1, edep);
241
242 //2nd thetaID ring
243 if (m_thetaID == 2) {
244 h_CrystalThetaID2->AddBinContent(m_phiID + 1, dose);
245 }
246 //67th thetaID ring
247 if (m_thetaID == 67) {
248 h_CrystalThetaID67->AddBinContent(m_phiID + 1, dose);
249 }
250 //Barrel
251 if (m_thetaID < 59 && m_thetaID > 12) {
252 h_BarrelDose->AddBinContent(m_phiID + 1, dose / 46);
253 }
254
255 //location of the hit
256 h_HitLocations->Fill(hitPosn.z(), hitPosn.perp());
257
258 }
259
260
261 //for pileup noise estimation. To properly produce pileup noise plot, see comment at EOF.
262 for (int iECLCell = 0; iECLCell < ECLElementNumbers::c_NCrystals; iECLCell++) {
263 edep = E_tot[iECLCell];
264 m_thetaID = Crystal[iECLCell]->GetThetaID();
265 NperRing = Crystal[iECLCell]->GetNperThetaID();
266 if (edep > 0.000000000001) {
267 hNevtPerRing->Fill(m_thetaID, 1.0 / NperRing);
268 hEdepPerRing->Fill(m_thetaID, edep / NperRing);
269 }
270
271 }
272
273
274 //One track can create several ECLSimHits. Remove the duplicates
275 sort(MCPhotonIDs.begin(), MCPhotonIDs.end());
276 vector<int>::iterator it;
277 it = std::unique(MCPhotonIDs.begin(), MCPhotonIDs.end());
278 MCPhotonIDs.resize(std::distance(MCPhotonIDs.begin(), it));
279
280
281 //loop over MCParticles to find the photons that caused the simhits
282 for (int i = 0; i < (int)MCPhotonIDs.size(); i++) {
283 for (int j = 0; j < m_mcParticles.getEntries(); j++) {
284 if (m_mcParticles[j]->getIndex() == MCPhotonIDs[i]) {
285 h_PhotonE->Fill(m_mcParticles[j]->getEnergy() * 1000);
286 hEgamma->Fill(log10(m_mcParticles[j]->getEnergy() * 1000));
287 break; //once the correct MCParticle is found, stop looping over MCParticles
288 }
289 }
290 }
291
292 //*****************end of crystal analysis
293
294 //start of diode analysis
295 int neuHits = m_BeamBackArray.getEntries();
296 for (int iHits = 0; iHits < neuHits; iHits++) { //loop over m_BeamBackArray
297 BeamBackHit* aBeamBackSimHit = m_BeamBackArray[iHits];
298
299 //get relevant values
300 m_cellID = aBeamBackSimHit->getIdentifier();
301 double damage = aBeamBackSimHit->getNeutronWeight();
302 edep = aBeamBackSimHit->getEnergyDeposit();
303 pid = aBeamBackSimHit->getPDG();
304 int SubDet = aBeamBackSimHit->getSubDet();
305 Energy = aBeamBackSimHit->getEnergy();
306 //ROOT::Math::XYZVector rHit = aBeamBackSimHit->getPosition(); //currently not used
307
308
309 if (SubDet == 6) { //ECL
310
311 m_thetaID = Crystal[m_cellID]->GetThetaID();
312 m_phiID = Crystal[m_cellID]->GetPhiID();
313 NperRing = Crystal[m_cellID]->GetNperThetaID();
314 diodeDose = edep * GeVtoJ * usInYr / (m_sampleTime * DiodeMass);
315 h_DiodeRadDose->AddBinContent(m_thetaID + 1, diodeDose / NperRing); //diode radiation dose plot
316
317 if (pid == 2112) {
318
319 weightedFlux = damage * usInYr / (m_sampleTime * DiodeArea) ; //neutrons per cm^2 per year
320
321 //neutron plots
322 if (m_thetaID == 0) h_NeutronEThetaID0->Fill(Energy * 1000);
323 h_NeutronE->Fill(Energy * 1000);
324 hEneu->Fill(log10(Energy * 1000));
325
326 h_NeutronFlux->AddBinContent(m_thetaID + 1, weightedFlux / NperRing);
327 hDiodeFlux->AddBinContent(m_cellID + 1, weightedFlux);
328
329 if (m_thetaID == 2) h_NeutronFluxThetaID2->AddBinContent(m_phiID + 1, weightedFlux);
330 if (m_thetaID == 67) h_NeutronFluxThetaID67->AddBinContent(m_phiID + 1, weightedFlux);
331
332
333 }
334
335 } else if (SubDet == 4 && m_doARICH) { //ARICH
336 FillARICHBeamBack(aBeamBackSimHit);
337 }
338 }
339
340 int nShower = m_eclShowerArray.getEntries();
341 for (int i = 0; i < nShower; i++) {
342 const ECLShower* aShower = m_eclShowerArray[i];
343
344 Energy = aShower->getEnergy();
345 theta = aShower->getTheta();
346
347 //get number of background showers with energy above 20MeV
348 if (Energy > 0.02) {
349 h_Shower->Fill(Energy);
350 h_ShowerVsTheta->Fill(Energy, theta * TMath::RadToDeg());
351 }
352 }
353
354
355 for (int i = 0; i < nECLThetaID; i++) {
356 if (EinTheta[i]) {
357 //0th McParticle in an event is the origin of all particles
358 h_ProdVertvsThetaId->Fill(i, m_mcParticles[0]->getProductionVertex().z(), edepSumTheta[i]);
359 }
360 }
361
362
363 if (isE) {
364 h_ProdVert->Fill(m_mcParticles[0]->getProductionVertex().z(), edepSum);
365 }
366
367 if (m_nEvent % ((int)m_sampleTime * 100) == 0) B2INFO("ECLBackgroundModule: At Event #" << m_nEvent);
368 m_nEvent++;
369
370 delete[] edepSumTheta;
371 delete[] E_tot;
372 delete[] EinTheta;
373
374}
375
377{
378 B2INFO("ECLBackgroundModule: Total Number of events: " << m_nEvent);
379
380 //print doses of crystals of interest
381 for (int i = 0; i < (int)m_CryInt.size(); i++) {
383 B2WARNING("ECLBackgroundModule: Invalid cell ID. must be less than 8736");
384 continue;
385 }
386 double dose = hEMDose->GetBinContent(m_CryInt[i] + 1); //add 1 since bin #1 corresponds to cell ID #0
387 int thetaID = Crystal[m_CryInt[i]]->GetThetaID();
388 int phiID = Crystal[m_CryInt[i]]->GetPhiID();
389 B2RESULT("Dose in Crystal " << m_CryInt[i] << ": " << dose << " ThetaID=" << thetaID << ", PhiID=" << phiID);
390 }
391
392
397
398
399 hEMDoseECF = BuildPosHisto(hEMDose, "forward");
400 hEMDoseECB = BuildPosHisto(hEMDose, "backward");
401 hEMDoseBAR = BuildPosHisto(hEMDose, "barrel");
403
408
409 hEMDose->SetTitle("Crystal Radiation Dose vs Cell ID");
410 hDiodeFlux->SetTitle("Diode Neutron Flux vs Cell ID");
411
412}
413
414
415//
416// Methods to study performance of ECL shields
417// and potential impact on ARICH doses
419#ifdef DOARICH
421{
422
423 double _damage = aBBHit->getNeutronWeight();
424 double _eDep = aBBHit->getEnergyDeposit();
425 float _trlen = aBBHit->getTrackLength();
426 int _pid = aBBHit->getPDG();
427 ROOT::Math::XYZVector _posHit = aBBHit->getPosition();
428
429 int _moduleID = m_arichgp->getCopyNo(_posHit);
430
431 double r = _posHit.Rho();
432 int _ring = 0;
433
434 _ring = ARICHmod2row(_moduleID);
435
436 B2DEBUG(200, "Filling ARICH BeamBackHit");
437 B2DEBUG(200, " PDG = " << _pid);
438 B2DEBUG(200, " Edep = " << _eDep);
439 B2DEBUG(200, " Ring = " << _ring);
440 B2DEBUG(200, " Radius = " << r);
441 B2DEBUG(200, " Module = " << _moduleID);
442
443 if (2112 == _pid) {
444 hHAPDFlux->Fill(_ring, _damage * _trlen / HAPDthickness * usInYr / (m_sampleTime * HAPDarea * nHAPDperRing[_ring]));
445 } else {
446 hARICHDoseBB->Fill(_ring, _eDep / (HAPDmass * nHAPDperRing[_ring]) * GeVtoJ * usInYr / m_sampleTime);
447 }
448
449 return 1;
450}
451
452#else
453// cppcheck-suppress functionStatic ; the DOARICH version of this function uses members
454int ECLBackgroundModule::FillARICHBeamBack(BeamBackHit* aBBHit) { return 1;} // cppcheck-suppress constParameterPointer ; the DOARICH version reads through it
455#endif
456
458{
459 for (int i = 0; i < ECLElementNumbers::c_NCrystals; i++) {
460 Crystal[i] = new ECLCrystalData(i);
461 }
462 return 1;
463}
464
465//Method used for debugging.
466int ECLBackgroundModule::SetPosHistos(TH1F* h, TH2F* hFWD, TH2F* hBAR, TH2F* hBWD)
467{
468 // Currently not used
469 //std::string FWDtitle = h->GetTitle() + std::string(" -- Forward Endcap");
470 //std::string BWDtitle = h->GetTitle() + std::string(" -- Backward Endcap");
471 //std::string BARtitle = h->GetTitle() + std::string(" -- Barrel");
472 //std::string FWDname = h->GetTitle() + std::string("FWD");
473 //std::string BWDname = h->GetTitle() + std::string("BWD");
474 //std::string BARname = h->GetTitle() + std::string("BAR");
475
476 // Fill 2D histograms with the values in the 1D histogram
477 for (int i = 0; i < ECLElementNumbers::c_NCrystals; i++) {
478 float value = h->GetBinContent(i + 1);
479
481 hFWD->Fill(floor(Crystal[i]->GetX()), floor(Crystal[i]->GetY()), value);
482
484 hBWD->Fill(floor(Crystal[i]->GetX()), floor(Crystal[i]->GetY()), value);
485
486 } else
487 hBAR->Fill(floor(Crystal[i]->GetZ()), floor(Crystal[i]->GetR() * (Crystal[i]->GetPhi() - 180) * TMath::DegToRad()), value);
488 }
489
490 return 1;
491}
492
493
494TH2F* ECLBackgroundModule::BuildPosHisto(TH1F* h, const char* sub)
495{
496
497 // Initialize variables
498 TH2F* h_out = nullptr;
499
500 // Forward endcap value vs (x,y)
501 if (!strcmp(sub, "forward")) {
502 std::string _name = h->GetName() + std::string("FWD");
503 std::string _title = h->GetTitle() + std::string(" -- Forward Endcap;x(cm);y(cm)");
504 h_out = new TH2F(_name.c_str(), _title.c_str(), 90, -150, 150, 90, -150, 150); //position in cm
505 h_out->Sumw2();
506 for (int i = 0; i < ECLElementNumbers::c_NCrystalsForward; i++) {
507 double value = h->GetBinContent(i + 1);
508 h_out->Fill(floor(Crystal[i]->GetX()),
509 floor(Crystal[i]->GetY()),
510 value);
511 }
512
513 // Backward endcap value vs (x,y)
514 } else if (!strcmp(sub, "backward")) {
515 std::string _name = h->GetName() + std::string("BWD");
516 std::string _title = h->GetTitle() + std::string(" -- Backward Endcap;x(cm);y(cm)");
517 h_out = new TH2F(_name.c_str(), _title.c_str(), 90, -150, 150, 90, -150, 150); //position in cm
518 h_out->Sumw2();
520 double value = h->GetBinContent(i + 1);
521 h_out->Fill(floor(Crystal[i]->GetX()),
522 floor(Crystal[i]->GetY()),
523 value);
524 }
525
526
527 // The rest: barrel value vs (theta_ID, phi_ID)
528 } else if (!strcmp(sub, "barrel")) {
529 std::string _name = h->GetName() + std::string("BAR");
530 std::string _title = h->GetTitle() + std::string(" -- Barrel;#theta_{ID};#phi_{ID}");
531 h_out = new TH2F(_name.c_str(), _title.c_str(), 47, 12, 59, 144, 0, 144); //position in cm (along z and along r*phi)
532 h_out->Sumw2();
534 double value = h->GetBinContent(i + 1);
535 h_out->Fill(Crystal[i]->GetThetaID(), Crystal[i]->GetPhiID(), value);
536 }
537
538 } else {
539 B2WARNING("ECLBackgroundModule: Unable to BuildPosHisto. Check Arguments.");
540 h_out = new TH2F("(empty)", "(empty)", 1, 0, 1, 1, 0, 1);
541 }
542
543 return h_out;
544}
545
546
548{
549
550 //Define the boundaries of the bins
551 static const int _nbins = 21;
552 static const double _xbins[] = { -0.5, 0.5, 4.5, 8.5, 11.5, 12.5,
553 16.5, 20.5, 24.5, 28.5, 32.5,
554 36.5, 40.5, 44.5, 48.5, 52.5,
555 56.5, 58.5, 59.5, 63.5, 67.5, 68.5
556 };
557
558
559 std::string _title = h_cry->GetTitle() + std::string(" vs #theta_{ID} -- averages");
560 std::string _name = h_cry->GetName() + std::string("vsTheWide");
561
562 //New pointer to the returned histogram ...
563 TH1F* h_out = new TH1F(_name.c_str(), _title.c_str(), 1, 0, 1);
564 // ... but only temp variables to the temporary ones
565 TH1F h_mass("h_mass", "Total Mass per Theta-ID", 1, 0, 1);
566 TH1F h_N("h_N", "Entries (unweighted) per Theta-ID bin", 1, 0, 1);
567
568 //Apply all the same binning
569 h_out->SetBins(_nbins, _xbins);
570 h_mass.SetBins(_nbins, _xbins);
571 h_N.SetBins(_nbins, _xbins);
572
573 h_out->SetTitle(_title.c_str());
574 h_out->Sumw2();
575
576 //Make histo for total mass, then divide!
577 for (int i = 0; i < ECLElementNumbers::c_NCrystals; i++) {
578 h_out->Fill(Crystal[i]->GetThetaID(), h_cry->GetBinContent(i + 1) * Crystal[i]->GetMass());
579 h_mass.Fill(Crystal[i]->GetThetaID(), Crystal[i]->GetMass());
580 h_mass.SetBinError(Crystal[i]->GetThetaID(), 0);
581 h_N.Fill(Crystal[i]->GetThetaID());
582 }
583 h_out->SetXTitle("#theta_{ID}");
584 h_out->SetYTitle(h_cry->GetYaxis()->GetTitle());
585 h_out->Divide(&h_mass);
586
587 return h_out;
588}
589
590
592{
593 if (modID <= 42) return 0;
594 else if (modID <= 90) return 1;
595 else if (modID <= 144) return 2;
596 else if (modID <= 204) return 3;
597 else if (modID <= 270) return 4;
598 else if (modID <= 342) return 5;
599 else if (modID <= 420) return 6;
600
601 B2WARNING("ECLBackgroundModule: ARICHmod2row: modID out of bound; can't get ring index");
602 return -1;
603}
604
605
606
607
608/*
609// In order to produce the pileup noise estimate, use this function (paste into another file):
610void PileUpNoise(){
611
612 const int numOfTypes = 8;
613 TString Filetypes[] = {"Touschek_HER", "Touschek_LER", "Coulomb_HER", "Coulomb_LER", "RBB_HER", "RBB_LER", "BHWide_HER", "BHWide_LER"};
614 TFile *f;
615
616 double hEdepPerRing[69] = {};
617 double hNevtPerRing[69] = {};
618 double sampletime=1000;
619
620 TH1F *h_Pileup = new TH1F("Pile_up", "Estimated Pile up Noise vs #theta_{ID}; #theta_{ID}; MeV", 69, -0.5, 68.5);
621
622 for(int i=0; i<numOfTypes; i++){
623 f = new TFile(Filetypes[i]+".root"); //loads the sample files (eg, Touschek_HER.root, RBB_LER.root, etc)
624 TH1F *hNevt = (TH1F*)gROOT->FindObject("hNevtPerRing");
625 TH1F *hEdep = (TH1F*)gROOT->FindObject("hEdepPerRing");
626 for(int j=1; j<70; j++){
627 hEdepPerRing[j-1] = hEdepPerRing[j-1] + hEdep->GetBinContent(j);
628 hNevtPerRing[j-1] = hNevtPerRing[j-1] + hNevt->GetBinContent(j);
629 }
630 }
631
632 for(int i=1; i<70; i++){
633 double Eavg = hEdepPerRing[i-1] / hNevtPerRing[i-1];
634 double pileup = sqrt( hNevtPerRing[i-1] / sampletime ) * Eavg * 1000;
635 h_Pileup->SetBinContent(i, pileup);
636 }
637
638}
639*/
Class BeamBackHit - Stores hits from beam background simulation.
Definition BeamBackHit.h:28
double getNeutronWeight() const
get the effective neutron weight
double getEnergy() const
Get energy of the particle.
double getEnergyDeposit() const
Get particle energy deposit in sensitive volume.
int getPDG() const
Get the lund code of the particle that hit the sensitive area.
Definition BeamBackHit.h:89
double getTrackLength() const
the length of the track in the volume
ROOT::Math::XYZVector getPosition() const
Get global position of the particle hit.
Definition BeamBackHit.h:95
int getIdentifier() const
Get the identifier of subdetector component in which hit occurred.
Definition BeamBackHit.h:83
int getSubDet() const
Det the index of subdetector in which hit occurred.
Definition BeamBackHit.h:86
bool m_doARICH
Whether or not the ARICH plots are produced.
TH1F * h_DiodeRadDose
Diode Radiation Dose.
int SetPosHistos(TH1F *h, TH2F *hFWD, TH2F *hBAR, TH2F *hBWD)
Create 2D histograms indicating the position of each crystals.
StoreArray< ECLShower > m_eclShowerArray
Store array: ECLShower.
const double HAPDthickness
ARICH: Thickness (cm) of the HAPD boards.
TH2F * hEMDoseECF
Radiation Dose Forward Calorimeter.
TH2F * h_ShowerVsTheta
Shower Energy distribution vs theta.
TH2F * hEnergyPerCrystalBAR
Energy per crystal Barrel.
TH1F * hEnergyPerCrystal
Energy per cell.
static const int nECLThetaID
Number of thetaID values.
virtual void initialize() override
Initialize variables.
TH2F * hEnergyPerCrystalECB
Energy per crystal Backward Calorimeter.
TH1F * hEMDoseWideTID
Radiation Dose Wide bins.
const double HAPDmass
ARICH: Mass (kg) of the HAPD boards.
TH1F * hEneu
Log Spectrum of the neutrons hitting the diodes / 1 MeV.
virtual void event() override
Event method.
virtual ~ECLBackgroundModule() override
Destructor.
TH1F * hARICHDoseBB
ARICH Yearly dose (rad) vs module index.
TH2F * hDiodeFluxECF
Diode Neutron Flux Forward Calorimeter.
const double HAPDarea
ARICH geometry parameters.
TH2F * hEMDoseBAR
Radiation Dose Barrel.
virtual void endRun() override
endRun
TH2F * hEMDoseECB
Radiation Dose Backward Calorimeter.
TH2F * h_ProdVertvsThetaId
Production Vertex vs thetaID.
int BuildECL()
Builds geometry (fill Crystal look-up arrays)
std::vector< int > m_CryInt
Cell ID of crystal(s) of interest.
TH1F * h_CrystalRadDoseTheta
Crystal Radiation Dose, actual Theta.
TH1F * h_ProdVert
Production Vertex.
TH1F * hNevtPerRing
Event counter averaged per ring (theta-id)
static int ARICHmod2row(int modID)
Get ARICH ring ID from the module index.
const double DiodeArea
Frontal area [cm*cm] of Diodes.
TH2F * h_HitLocations
Hit locations.
const double usInYr
us in a year
int FillARICHBeamBack(BeamBackHit *aBBHit)
Populate ARICH HAPD dose and flux histograms (from the BeamBack hits array)
TH2F * BuildPosHisto(TH1F *h, const char *sub)
Convert histogram vs crystal index to geometrical positions.
TH1F * h_NeutronFluxThetaID67
Neutron flux in Diodes, ThetaID=67.
TH1F * hHAPDFlux
ARICH Yearly neutron flux vs module index.
TH1F * h_NeutronFluxThetaID2
Neutron flux in Diodes, ThetaID=2.
const int nHAPDperRing[7]
ARICH parameter.
TH1F * h_Shower
Shower Energy distribution.
const double DiodeMass
Mass [kg] of Diodes.
TH2F * hEnergyPerCrystalECF
Energy per crystal Forward Calorimeter.
StoreArray< BeamBackHit > m_BeamBackArray
Store array: BeamBackHit.
TH1F * hEdepPerRing
Energy averaged per ring.
StoreArray< ECLSimHit > m_eclArray
Store array: ECLSimHit.
TH1F * hEnergyPerCrystalWideTID
Energy per crystal Wide bins.
TH1F * hDiodeFluxWideTID
Diode Neutron Flux Wide bins.
StoreArray< MCParticle > m_mcParticles
Store array: MCParticle.
TH1F * h_CrystalThetaID2
Crystal Radiation Dose, ThetaID=2.
TH2F * hDiodeFluxECB
Diode Neutron Flux Backward Calorimeter.
TH1F * BuildThetaIDWideHisto(TH1F *h_cry)
Convert histogram vs crystal index to average per theta-ID (wide binning)
TH1F * h_CrystalThetaID67
Crystal Radiation Dose, ThetaID=67.
ECLCrystalData * Crystal[ECLElementNumbers::c_NCrystals]
Store crystal geometry and mass data.
TH1F * h_BarrelDose
Crystal Radiation Dose in Barrel, 12<thetaID<59.
TH1F * hEgamma
Log Spectrum of the photons hitting the crystals / 1 MeV.
TH1F * hEMDose
Radiation Dose per cell.
TH1F * h_NeutronFlux
Neutron Flux in Diodes.
TH2F * hDiodeFluxBAR
Diode Neutron Flux Barrel.
TH1F * h_NeutronE
Neutron Energy.
const double GeVtoJ
Joules in a GeV.
TH1F * hDiodeFlux
Diode Neutron Flux per cell.
TH1F * h_CrystalRadDose
Crystal Radiation Dose.
TH1F * h_nECLSimHits
ECL Sim Hits.
int m_sampleTime
length of sample in us
virtual void defineHisto() override
Initialize the histograms.
TH1F * h_NeutronEThetaID0
Neutron Energy, First Crystal.
Class for obtaining crystal details for a given crystal cell An evolved look-up table.
Class to store ECL Showers.
Definition ECLShower.h:30
double getEnergy() const
Get Energy.
Definition ECLShower.h:287
double getTheta() const
Get Theta.
Definition ECLShower.h:297
ClassECLSimHit - Geant4 simulated hit for the ECL.
Definition ECLSimHit.h:29
int getPDGCode() const
Get Particle PDG (can be one of secondaries)
Definition ECLSimHit.h:96
int getTrackId() const
Get Track ID.
Definition ECLSimHit.h:91
int getCellId() const
Get Cell ID.
Definition ECLSimHit.h:86
double getEnergyDep() const
Get Deposit energy.
Definition ECLSimHit.h:106
G4ThreeVector getPosition() const
Get Position.
Definition ECLSimHit.h:126
HistoModule()
Constructor.
Definition HistoModule.h:32
void setDescription(const std::string &description)
Sets the description of the module.
Definition Module.cc:214
static ARICHGeometryPar * Instance()
Static method to get a reference to the ARICHGeometryPar instance.
void addParam(const std::string &name, T &paramVariable, const std::string &description, const T &defaultValue)
Adds a new parameter to the module.
Definition Module.h:559
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition Module.h:649
const int c_NCrystals
Number of crystals.
const int c_NCrystalsForwardBarrel
Number of crystals in the forward and barrel ECL.
const int c_NCrystalsForward
Number of crystals in the forward ECL.
Abstract base class for different kinds of events.
STL namespace.