9 #include <ecl/modules/eclDigitizer/ECLDigitizerPureCsIModule.h>
18 #include <framework/gearbox/Unit.h>
19 #include <framework/logging/Logger.h>
20 #include <framework/utilities/FileSystem.h>
23 #include <ecl/digitization/ECLDspFitterPure.h>
24 #include <ecl/dataobjects/ECLHit.h>
25 #include <ecl/dataobjects/ECLDigit.h>
26 #include <ecl/dataobjects/ECLDsp.h>
27 #include <ecl/dataobjects/ECLPureCsIInfo.h>
28 #include <ecl/geometry/ECLGeometryPar.h>
29 #include <ecl/dbobjects/ECLWaveformData.h>
47 setDescription(
"Creates ECLDigiHits from ECLHits for Pure CsI.");
48 setPropertyFlags(c_ParallelProcessingCertified);
49 addParam(
"FirstRing", m_thetaIdMin,
"First ring (0-12)", 0);
50 addParam(
"LastRing", m_thetaIdMax,
"Last ring (0-12)", 12);
51 addParam(
"Background", m_background,
"Flag to use the DigitizerPureCsI configuration with backgrounds; Default is no background",
53 addParam(
"Calibration", m_calibration,
54 "Flag to use the DigitizerPureCsI for Waveform fit Covariance Matrix calibration; Default is false",
56 addParam(
"adcTickFactor", m_tickFactor,
"multiplication factor to get adc tick from trigger tick", 8);
57 addParam(
"sigmaTrigger", m_sigmaTrigger,
"Trigger resolution used", 0.);
58 addParam(
"elecNoise", m_elecNoise,
"Electronics noise energy equivalent in MeV", 0.5);
62 addParam(
"photostatresolution", m_photostatresolution,
"sigma for 1 MeV energy deposit", 0.22);
63 addParam(
"Debug", m_debug,
"debug mode on (default off)",
false);
64 addParam(
"debugtrgtime", m_testtrg,
"set fixed trigger time for testing purposes", 0);
65 addParam(
"debugsigtimeshift", m_testsig,
"shift signal arrival time for testing purposes (in microsec)", 0.);
66 addParam(
"debugenergydeposit", m_testenedep,
"energy deposit in all crystals for testing purposes", 0.);
67 addParam(
"NoCovMatrix", m_NoCovMatrix,
"Use a diagonal (neutral) Covariance matrix",
true);
71 ECLDigitizerPureCsIModule::~ECLDigitizerPureCsIModule()
75 void ECLDigitizerPureCsIModule::initialize()
78 EclConfigurationPure::m_tickPure = m_tickFactor * EclConfiguration::m_tick / EclConfiguration::m_ntrg;
80 m_ecldsps.registerInDataStore(eclDspArrayName());
82 m_ecldigits.registerInDataStore(eclDigitArrayName());
84 m_ecldigits.registerRelationTo(m_ecldsps);
87 m_eclpurecsiinfo.registerInDataStore(eclPureCsIInfoArrayName());
88 m_ecldigits.registerRelationTo(m_eclpurecsiinfo);
91 m_ecldigits.registerRelationTo(m_hitLists);
94 m_adc.resize(EclConfigurationPure::m_nch);
99 void ECLDigitizerPureCsIModule::beginRun()
103 void ECLDigitizerPureCsIModule::event()
108 double deltaT = m_sigmaTrigger == 0 ? 0 : gRandom->Gaus(0, m_sigmaTrigger);
114 vector< vector< const ECLHit*> > hitmap(EclConfigurationPure::m_nch);
116 for (
const auto& eclHit : m_hitLists) {
117 int j = eclHit.getCellId() - 1;
118 if (isPureCsI(j + 1)) {
119 assert(j < EclConfigurationPure::m_nch);
120 double hitE = eclHit.getEnergyDep() / Unit::GeV;
121 double hitTime = eclHit.getTimeAve() / Unit::us;
122 if (m_photostatresolution > 0) {
123 double nphotavg1MeV = 1 / (m_photostatresolution * m_photostatresolution);
124 int nphotavg = round((hitE / 0.001) * nphotavg1MeV);
125 int nphot = gRandom->Poisson(nphotavg);
126 hitE = (nphot / nphotavg1MeV) / 1000;
130 m_adc[j].AddHit(hitE , hitTime + deltaT, m_ss[m_tbl[j].iss]);
131 if (eclHit.getBackgroundTag() == BackgroundMetaData::bg_none) hitmap[j].push_back(&eclHit);
137 for (
int j = 0; j < EclConfigurationPure::m_nch; j++) {
138 if (! isPureCsI(j + 1))
continue;
141 m_adc[j].AddHit(m_testenedep, m_testsig, m_ss[m_tbl[j].iss]);
145 if (! m_calibration && a.total < 0.0001)
continue;
148 float adcNoise[EclConfigurationPure::m_nsmp];
149 memset(adcNoise, 0,
sizeof(adcNoise));
150 if (m_elecNoise > 0) {
151 float z[EclConfigurationPure::m_nsmp];
152 for (
int i = 0; i < EclConfigurationPure::m_nsmp; i++)
153 z[i] = gRandom->Gaus(0, 1);
154 m_noise[0].generateCorrelatedNoise(z, adcNoise);
157 int FitA[EclConfigurationPure::m_nsmp];
158 for (
int i = 0; i < EclConfigurationPure::m_nsmp; i++) {
159 FitA[i] = 20 * (1000 * a.c[i] + adcNoise[i]) + 3000;
166 if (! m_calibration) {
169 DSPFitterPure(m_fitparams[m_tbl[j].idn], FitA, m_testtrg, energyFit, tFit, fitChi2, qualityFit);
177 DSPFitterPure(m_fitparams[m_tbl[j].idn], FitA, 0, energyFit, tFit, fitChi2, qualityFit);
187 if (m_calibration || energyFit > 0) {
189 auto eclDsp = m_ecldsps.appendNew();
190 eclDsp->setCellId(CellId);
191 eclDsp->setDspA(FitA);
193 auto eclDigit = m_ecldigits.appendNew();
194 eclDigit->setCellId(CellId);
195 eclDigit->setAmp(energyFit);
196 eclDigit->setTimeFit(
int(tFit * 10));
197 eclDigit->setQuality(qualityFit);
199 auto AeclPureCsIInfo = m_eclpurecsiinfo.appendNew();
200 eclDigit->addRelationTo(AeclPureCsIInfo);
201 AeclPureCsIInfo->setPureCsI(1);
202 AeclPureCsIInfo->setCellId(CellId);
204 eclDigit->addRelationTo(eclDsp);
205 for (
const auto& hit : hitmap[j])
206 eclDigit->addRelationTo(hit);
215 for (
const auto& eclDigit : baselineDigits) {
216 int cellid = eclDigit.getCellId();
217 if (! isPureCsI(cellid)) {
218 auto eclDigitClone = m_ecldigits.appendNew();
219 eclDigitClone->setCellId(cellid);
220 eclDigitClone->setAmp(eclDigit.getAmp());
221 eclDigitClone->setTimeFit(eclDigit.getTimeFit());
222 eclDigitClone->setQuality(eclDigit.getQuality());
224 auto AeclPureCsIInfo = m_eclpurecsiinfo.appendNew();
225 eclDigitClone->addRelationTo(AeclPureCsIInfo);
226 AeclPureCsIInfo->setPureCsI(0);
227 AeclPureCsIInfo->setCellId(cellid);
235 void ECLDigitizerPureCsIModule::endRun()
239 void ECLDigitizerPureCsIModule::terminate()
243 void ECLDigitizerPureCsIModule::readDSPDB()
245 string dataFileName, dataFileName2;
247 dataFileName = FileSystem::findFile(
"/data/ecl/ECL-WF-Pure.root");
249 dataFileName2 = FileSystem::findFile(
"/data/ecl/ECL-WF-cov-Pure-BG.root");
250 B2INFO(
"ECLDigitizerPureCsI: Reading configuration data with background from: " << dataFileName);
251 B2INFO(
"ECLDigitizerPureCsI: Reading configuration data with background from: " << dataFileName2);
254 dataFileName = FileSystem::findFile(
"/data/ecl/ECL-WF-Pure.root");
256 dataFileName2 = FileSystem::findFile(
"/data/ecl/ECL-WF-cov-Pure.root");
257 B2INFO(
"ECLDigitizerPureCsI: Reading configuration data without background from: " << dataFileName);
258 B2INFO(
"ECLDigitizerPureCsI: Reading configuration data without background from: " << dataFileName2);
260 assert(! dataFileName.empty());
262 TFile rootfile(dataFileName.c_str());
263 const TH1F* sampledWF =
dynamic_cast<TH1F*
>(rootfile.Get(
"sampleddsp"));
264 assert(sampledWF !=
nullptr);
265 const TH1F* sampledWF1 =
dynamic_cast<TH1F*
>(rootfile.Get(
"sampleddsp1"));
266 assert(sampledWF1 !=
nullptr);
268 m_tbl.resize(EclConfigurationPure::m_nch);
273 m_ss[0].InitSample(sampledWF, sampledWF1);
275 for (
int i = 0; i < EclConfigurationPure::m_nch; i++) m_tbl[i].iss = 0;
276 B2INFO(
"ECLDigitizerPureCsI: " << m_ss.size() <<
" sampled signal templates were created.");
280 if (!(m_calibration || m_NoCovMatrix)) {
281 TFile rootfile2(dataFileName2.c_str());
282 TTree* tree = (TTree*) rootfile2.Get(
"EclWF");
284 const int maxncellid = 512;
286 vector<int> cellId(maxncellid);
288 tree->SetBranchAddress(
"ncellId", &ncellId);
289 tree->SetBranchAddress(
"cellId", cellId.data());
290 tree->SetBranchAddress(
"CovarianceM", &eclWFData);
291 for (Long64_t j = 0, jmax = tree->GetEntries(); j < jmax; j++) {
293 assert(ncellId <= maxncellid);
294 for (
int i = 0; i < ncellId; ++i)
295 m_tbl[cellId[i]].idn = m_fitparams.size();
298 m_fitparams.push_back(params);
301 B2INFO(
"ECLDigitizerPureCsI: parameters vector size : " << m_fitparams.size());
304 m_fitparams.resize(1);
305 for (
int i = 0; i < EclConfigurationPure::m_nch; i++)
307 for (
int i = 0; i < 16; i++)
308 for (
int j = 0; j < 16; j++)
309 if (i != j) m_fitparams[0].invC[i][j] = 0;
310 else m_fitparams[0].invC[i][j] = 1.0;
311 initParams(m_fitparams[0], m_ss[0]);
313 for (
auto& param : m_fitparams) {
314 initParams(param, m_ss[0]);
321 for (
int i = 0; i < EclConfigurationPure::m_nsmp; i++)
322 for (
int j = 0; j <= i; j++)
323 if (i == j) m_noise[0].setMatrixElement(index++, m_elecNoise);
324 else m_noise[0].setMatrixElement(index++, 0.);
327 m_noise[0].getMatrix(testM);
330 void ECLDigitizerPureCsIModule::mapGeometry()
333 for (
int cellId0 = 0; cellId0 < EclConfigurationPure::m_nch; cellId0++) {
The ECLDigitizerPureCsI module.
The Class for ECL Geometry Parameters.
void Mapping(int cid)
Mapping theta, phi Id.
int GetThetaID()
Get Theta Id.
Accessor to arrays stored 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.
a struct for the fit parameters for the pure CsI calorimeter
a struct for the fit parameters for the pure CsI calorimeter