10#include <ecl/modules/eclBackgroundStudy/ECLBackgroundModule.h>
13#include <ecl/dataobjects/ECLShower.h>
14#include <ecl/dataobjects/ECLSimHit.h>
15#include <ecl/modules/eclBackgroundStudy/ECLCrystalData.h>
19# include <arich/geometry/ARICHGeometryPar.h>
21#include <framework/logging/Logger.h>
22#include <mdst/dataobjects/MCParticle.h>
23#include <simulation/dataobjects/BeamBackHit.h>
26#include <Math/Vector3D.h>
47 setDescription(
"Processes background campaigns and produces histograms. Requires HistoManager");
49 std::vector<int> empty;
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);
67 h_nECLSimHits =
new TH1F(
"ECL_Sim_Hits",
"ECL Sim Hits", 100, 0, 100);
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,
75 h_CrystalThetaID67 =
new TH1F(
"Crystal_Dose_ThetaID_67",
"Crystal Radiation Dose vs #phi_{ID}, #theta_{ID}=67; #phi_{ID};Gy/yr", 64,
77 h_BarrelDose =
new TH1F(
"Crystal_Dose_Barrel",
"Crystal Radiation Dose in Barrel, 12<#theta_{ID}<59; #phi_{ID}; Gy/yr", 144, -0.5,
79 h_DiodeRadDose =
new TH1F(
"Diode_Rad_Dose",
"Diode Radiation Dose vs #theta_{ID};#theta_{ID};Gy/yr", 69, -0.5, 68.5);
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,
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);
92 h_NeutronFluxThetaID2 =
new TH1F(
"Neutron_Flux_ThetaID_2",
"Diode Neutron Flux, #theta_{ID}=2;#phi_{ID}; yr^{-1}/cm^{-2}", 64, -0.5,
94 h_NeutronFluxThetaID67 =
new TH1F(
"Neutron_Flux_ThetaID_67",
"Diode Neutron Flux, #theta_{ID}=67;#phi_{ID}; yr^{-1}/cm^{-2}", 64,
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);
100 h_PhotonE =
new TH1F(
"Photon_Energy",
"Energy of photons creating hits in ECL; Energy (MeV)", 200, 0, 10);
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,
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);
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,
161 B2INFO(
"ECLBackgroundModule: ARICH plots are being produced");
179 int m_cellID, m_thetaID, m_phiID, pid, NperRing;
180 double edep, theta, Energy, diodeDose, weightedFlux;
184 B2INFO(
"ECLBackgroundModule: Skipping event #" <<
m_nEvent <<
" due to large number of ECLSimHits");
207 vector<int> MCPhotonIDs;
210 for (
int i = 0; i < hitNum; i++) {
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();
220 theta =
Crystal[m_cellID]->GetTheta();
224 if (pid == 22) MCPhotonIDs.push_back(aECLHit->
getTrackId());
226 edepSum = edepSum + edep;
227 E_tot[m_cellID] = edep + E_tot[m_cellID];
228 edepSumTheta[m_thetaID] = edepSumTheta[m_thetaID] + edep;
229 EinTheta[m_thetaID] =
true;
239 hEMDose->AddBinContent(m_cellID + 1, dose);
243 if (m_thetaID == 2) {
247 if (m_thetaID == 67) {
251 if (m_thetaID < 59 && m_thetaID > 12) {
263 edep = E_tot[iECLCell];
264 m_thetaID =
Crystal[iECLCell]->GetThetaID();
265 NperRing =
Crystal[iECLCell]->GetNperThetaID();
266 if (edep > 0.000000000001) {
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));
282 for (
int i = 0; i < (int)MCPhotonIDs.size(); i++) {
296 for (
int iHits = 0; iHits < neuHits; iHits++) {
303 pid = aBeamBackSimHit->
getPDG();
304 int SubDet = aBeamBackSimHit->
getSubDet();
311 m_thetaID =
Crystal[m_cellID]->GetThetaID();
312 m_phiID =
Crystal[m_cellID]->GetPhiID();
313 NperRing =
Crystal[m_cellID]->GetNperThetaID();
315 h_DiodeRadDose->AddBinContent(m_thetaID + 1, diodeDose / NperRing);
324 hEneu->Fill(log10(Energy * 1000));
326 h_NeutronFlux->AddBinContent(m_thetaID + 1, weightedFlux / NperRing);
327 hDiodeFlux->AddBinContent(m_cellID + 1, weightedFlux);
341 for (
int i = 0; i < nShower; i++) {
370 delete[] edepSumTheta;
378 B2INFO(
"ECLBackgroundModule: Total Number of events: " <<
m_nEvent);
381 for (
int i = 0; i < (int)
m_CryInt.size(); i++) {
383 B2WARNING(
"ECLBackgroundModule: Invalid cell ID. must be less than 8736");
389 B2RESULT(
"Dose in Crystal " <<
m_CryInt[i] <<
": " << dose <<
" ThetaID=" << thetaID <<
", PhiID=" << phiID);
409 hEMDose->SetTitle(
"Crystal Radiation Dose vs Cell ID");
410 hDiodeFlux->SetTitle(
"Diode Neutron Flux vs Cell ID");
426 int _pid = aBBHit->
getPDG();
427 ROOT::Math::XYZVector _posHit = aBBHit->
getPosition();
429 int _moduleID = m_arichgp->getCopyNo(_posHit);
431 double r = _posHit.Rho();
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);
478 float value = h->GetBinContent(i + 1);
481 hFWD->Fill(floor(
Crystal[i]->GetX()), floor(
Crystal[i]->GetY()), value);
484 hBWD->Fill(floor(
Crystal[i]->GetX()), floor(
Crystal[i]->GetY()), value);
487 hBAR->Fill(floor(
Crystal[i]->GetZ()), floor(
Crystal[i]->GetR() * (
Crystal[i]->GetPhi() - 180) * TMath::DegToRad()), value);
498 TH2F* h_out =
nullptr;
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);
507 double value = h->GetBinContent(i + 1);
508 h_out->Fill(floor(
Crystal[i]->GetX()),
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);
520 double value = h->GetBinContent(i + 1);
521 h_out->Fill(floor(
Crystal[i]->GetX()),
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);
534 double value = h->GetBinContent(i + 1);
535 h_out->Fill(
Crystal[i]->GetThetaID(),
Crystal[i]->GetPhiID(), value);
539 B2WARNING(
"ECLBackgroundModule: Unable to BuildPosHisto. Check Arguments.");
540 h_out =
new TH2F(
"(empty)",
"(empty)", 1, 0, 1, 1, 0, 1);
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
559 std::string _title = h_cry->GetTitle() + std::string(
" vs #theta_{ID} -- averages");
560 std::string _name = h_cry->GetName() + std::string(
"vsTheWide");
563 TH1F* h_out =
new TH1F(_name.c_str(), _title.c_str(), 1, 0, 1);
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);
569 h_out->SetBins(_nbins, _xbins);
570 h_mass.SetBins(_nbins, _xbins);
571 h_N.SetBins(_nbins, _xbins);
573 h_out->SetTitle(_title.c_str());
578 h_out->Fill(
Crystal[i]->GetThetaID(), h_cry->GetBinContent(i + 1) *
Crystal[i]->GetMass());
580 h_mass.SetBinError(
Crystal[i]->GetThetaID(), 0);
581 h_N.Fill(
Crystal[i]->GetThetaID());
583 h_out->SetXTitle(
"#theta_{ID}");
584 h_out->SetYTitle(h_cry->GetYaxis()->GetTitle());
585 h_out->Divide(&h_mass);
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;
601 B2WARNING(
"ECLBackgroundModule: ARICHmod2row: modID out of bound; can't get ring index");
Class BeamBackHit - Stores hits from beam background simulation.
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.
double getTrackLength() const
the length of the track in the volume
ROOT::Math::XYZVector getPosition() const
Get global position of the particle hit.
int getIdentifier() const
Get the identifier of subdetector component in which hit occurred.
int getSubDet() const
Det the index of subdetector in which hit occurred.
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.
ECLBackgroundModule()
Constructor.
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_PhotonE
Photon Energy.
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)
int m_nEvent
Event counter.
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.
double getEnergy() const
Get Energy.
double getTheta() const
Get Theta.
ClassECLSimHit - Geant4 simulated hit for the ECL.
int getPDGCode() const
Get Particle PDG (can be one of secondaries)
int getTrackId() const
Get Track ID.
int getCellId() const
Get Cell ID.
double getEnergyDep() const
Get Deposit energy.
G4ThreeVector getPosition() const
Get Position.
HistoModule()
Constructor.
void setDescription(const std::string &description)
Sets the description of the module.
static ARICHGeometryPar * Instance()
Static method to get a reference to the ARICHGeometryPar instance.
void addParam(const std::string &name, T ¶mVariable, const std::string &description, const T &defaultValue)
Adds a new parameter to the module.
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
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.