9 #include <framework/core/HistoModule.h>
10 #include <framework/datastore/StoreArray.h>
11 #include <framework/datastore/StoreObjPtr.h>
12 #include <framework/dataobjects/EventMetaData.h>
13 #include <framework/gearbox/Const.h>
14 #include <beast/csi/modules/CsiModule.h>
15 #include <beast/csi/dataobjects/CsiSimHit.h>
16 #include <beast/csi/dataobjects/CsiHit.h>
17 #include <beast/csi/dataobjects/CsiDigiHit.h>
18 #include <beast/csi/modules/CsIStudyModule.h>
40 h_CrystalSpectrum(NULL),
41 h_CrystalRadDose(NULL),
42 h_CrystalRadDoseSH(NULL),
44 h_LightYieldCrystal(NULL),
54 setDescription(
"Analyze simulations of CsI readings in BEAST. Requires HistoManager module.");
57 addParam(
"nWFSamples", m_nWFSamples,
"Number of samples in the saved waveforms", 8000);
58 addParam(
"paramTemplate", m_paramTemplate,
"Template of an input parameter. Noop for now.", 0.0);
60 string rootfilepath =
"output/waveforms.root";
61 addParam(
"waveformFilename", m_waveformFilename,
"Path to the root file to save waveforms", rootfilepath);
65 CsIStudyModule::~CsIStudyModule()
69 void CsIStudyModule::defineHisto()
71 h_CrystalEdep =
new TH1F(
"Crystal_Edep",
"Energy distribution in each crystal;CellID", 16, -0.5, 15.5);
72 h_CrystalSpectrum =
new TH1F(
"Crystal_Edist",
"Photon energy distribution in all crystals;", 100, 0, 0.1);
73 h_NhitCrystal =
new TH1F(
"Crystal_HitRate",
"Number of hit per crystal;CellID; hit/s", 16, -0.5, 15.5);
74 h_CrystalRadDose =
new TH1F(
"Crystal_RadDose",
"Crystal Radiation Dose;CellID;Gy/yr", 16, -0.5, 15.5);
75 h_CrystalRadDoseSH =
new TH1F(
"Crystal_RadDose_SH",
"Crystal Radiation Dose from SimHits;CellID;Gy/yr", 16, -0.5, 15.5);
76 h_LightYieldCrystal =
new TH1F(
"Crystal_g_yield",
"Light yield each crystal;CellID;gamma/sample", 16, -0.5, 15.5);
77 h_Waveform =
new TH1S(
"Waveform",
"Recorded waveform;Time index;ADC bits", m_nWFSamples, 0, m_nWFSamples - 1);
78 h_Gate =
new TH1C(
"Gate",
"Recorded gate;Time index;ADC bits", m_nWFSamples, 0, m_nWFSamples - 1);
79 h_Charge =
new TH1F(
"Charge",
"log_{10} of integrated Charge", 200, 0, 10);
80 h_TrueEdep =
new TH1F(
"TrueEdep",
"log_{10} of true deposited energy/GeV", 200, -6, 0);
81 h_Height =
new TH1F(
"Height",
"log10 of pulse height", 200, 0, 6);
82 h_Weight =
new TH1F(
"Weight",
"Distribution of the event weights form the generator", 1000, 0, 10);
85 void CsIStudyModule::initialize()
90 m_simhits.isRequired();
91 m_digihits.isOptional();
93 fWF =
new TFile(m_waveformFilename.c_str(),
"recreate");
96 void CsIStudyModule::beginRun()
100 void CsIStudyModule::endRun()
107 void CsIStudyModule::event()
111 double eventWeight = eventMetaDataPtr->getGeneratedWeight();
113 h_Weight->Fill(eventWeight);
116 if (m_hits.getEntries() > 0) {
117 int hitNum = m_hits.getEntries();
119 double E_tmp[16] = {0};
122 double edeptodose = GeVtoJ / Mass * usInYr / Sampletime;
125 for (
int i = 0; i < hitNum; i++) {
126 CsiHit* aCsIHit = m_hits[i];
131 E_tmp[m_cellID] += edep;
134 h_CrystalSpectrum->Fill(edep, eventWeight);
135 h_CrystalEdep->Fill(m_cellID, edep * eventWeight);
136 h_CrystalRadDose->Fill(m_cellID, edep * edeptodose * eventWeight);
139 h_NhitCrystal->Fill(m_cellID, eventWeight * 1.0e9 / Sampletime);
144 if (m_simhits.getEntries() > 0) {
145 int hitNum = m_simhits.getEntries();
148 double edeptodose = GeVtoJ / Mass * usInYr / Sampletime;
151 for (
int i = 0; i < hitNum; i++) {
157 h_CrystalRadDoseSH->Fill(m_cellID, eventWeight * edep * edeptodose);
160 if (Const::photon.getPDGCode() == aCsIHit->
getPDGCode()) {
161 h_LightYieldCrystal->Fill(m_cellID, eventWeight);
167 if (m_digihits.getEntries() > 0) {
168 int hitNum = m_digihits.getEntries();
171 for (
int i = 0; i < hitNum; i++) {
176 double charge = (double) aCsIDigiHit->
getCharge();
177 double height = (double) aCsIDigiHit->
getMaxVal();
178 double baseline = (double) aCsIDigiHit->
getBaseline();
180 vector<uint16_t>* waveform = aCsIDigiHit->
getWaveform();
183 h_TrueEdep->Fill(log10(trueEdep), eventWeight);
184 h_Charge->Fill(log10(charge - baseline), eventWeight);
185 h_Height->Fill(log10(height), eventWeight);
192 if (waveform->size()) {
197 sprintf(histoTitle,
"Waveform Hit No. %i, Cell No %i", i, cellID);
198 h_Waveform->SetTitle(histoTitle);
201 for (uint iBin = 0; iBin < waveform->size(); iBin++) {
202 bool* statusBits = readDPPStatusBits(status->at(iBin));
203 h_Gate->Fill(iBin + 1, (
int) statusBits[1]);
204 h_Waveform->Fill(iBin + 1, waveform->at(iBin));
216 void CsIStudyModule::terminate()
222 bool* CsIStudyModule::readDPPStatusBits(
char data)
225 bool* bit =
new bool[8];
228 for (
int i = 0; i < 8; i++) {
229 bit[i] = ((data >> i) & 0x01);
Analyze simulations of CsI readings in BEAST.
Class to store Csi digitized hits (output of CsIDigitizer) relation to CsiHit filled in beast/csi/mod...
double getTrueEdep() const
Get true deposited energy.
std::vector< uint8_t > * getStatusBits()
Get Status bits array.
uint16_t getBaseline() const
Get Baseline.
uint32_t getCharge() const
Get Integrated Charge.
std::vector< uint16_t > * getWaveform()
Get Waveform array.
uint8_t getCellId() const
Get Cell ID.
uint16_t getMaxVal() const
Get Maximal Value.
Class to store simulated hits which equate to average of CsiSimHit on crystals Input for digitization...
int getCellId() const
Get Cell ID.
double getEnergyDep() const
Get deposit energy.
ClassCsiSimHit - Geant4 simulated hits in CsI crystals in BEAST.
int getPDGCode() const
Get Particle PDG (can be one of secondaries)
int getCellId() const
Get Cell ID.
double getEnergyDep() const
Get Deposit energy.
HistoModule.h is supposed to be used instead of Module.h for the modules with histogram definitions t...
Type-safe access to single objects in the data store.
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Abstract base class for different kinds of events.