9 #include <arich/modules/arichDigitizer/ARICHDigitizerModule.h>
12 #include <arich/dataobjects/ARICHSimHit.h>
13 #include <arich/dataobjects/ARICHDigit.h>
16 #include <framework/datastore/DataStore.h>
17 #include <framework/datastore/StoreArray.h>
20 #include <framework/logging/Logger.h>
23 #include <framework/geometry/BFieldManager.h>
25 #include <framework/dataobjects/BackgroundInfo.h>
34 using namespace boost;
58 setDescription(
"This module creates ARICHDigits from ARICHSimHits. Here spatial digitization is done, channel-by-channel QE is applied, and readout time window cut is applied.");
61 setPropertyFlags(c_ParallelProcessingCertified);
64 addParam(
"TimeWindow", m_timeWindow,
"Readout time window width in ns", 250.0);
65 addParam(
"BackgroundHits", m_bkgLevel,
"Number of background hits per hapd per readout (electronics noise)", 0.066);
66 addParam(
"MagneticFieldDistorsion", m_bdistort,
"Apply image distortion due to non-perp. magnetic field", 0);
69 ARICHDigitizerModule::~ARICHDigitizerModule()
74 void ARICHDigitizerModule::initialize()
80 m_maxQE = m_simPar->getQE(3.1);
83 digits.registerInDataStore();
88 if (bgInfo->getMethod() == BackgroundInfo::c_Overlay) m_bgOverlay =
true;
93 void ARICHDigitizerModule::beginRun()
95 if (m_simPar->getNBkgHits() > 0) m_bkgLevel = m_simPar->getNBkgHits();
98 void ARICHDigitizerModule::event()
118 std::map<pair<int, int>,
int> photoElectrons;
119 std::map<pair<int, int>,
int> chipHits;
125 for (
int iHit = 0; iHit < nHits; ++iHit) {
132 if (globaltime < 0. || globaltime > m_timeWindow)
continue;
139 if (m_bdistort) magFieldDistorsion(locpos, moduleID);
142 if (!m_modInfo->isActive(moduleID))
continue;
146 m_geoPar->getHAPDGeometry().getXYChannel(locpos.X(), locpos.Y(), chX, chY);
148 if (chX < 0 && chY < 0)
continue;
150 int asicChannel = m_chnMap->getAsicFromXY(chX, chY);
159 double qe_scale = m_modInfo->getChannelQE(moduleID,
asicChannel) / m_maxQE;
161 if (qe_scale > 1.) B2ERROR(
"Channel QE is higher than QE applied in SensitiveDetector");
162 if (gRandom->Uniform(1.) > qe_scale)
continue;
165 chipHits[make_pair(moduleID,
asicChannel / 36)] += 1;
166 photoElectrons[make_pair(moduleID,
asicChannel)] += 1;
173 for (std::map<std::pair<int, int> ,
int>::iterator it = photoElectrons.begin(); it != photoElectrons.end(); ++it) {
175 std::pair<int, int> modch = it->first;
176 double npe = double(it->second);
179 npe /= (1.0 + m_simPar->getChipNegativeCrosstalk() * (double(chipHits[make_pair(modch.first, modch.second / 36)]) - 1.0));
180 if (npe < 1.0 && gRandom->Uniform(1) > npe)
continue;
185 for (
int i = 0; i < npe; i++) {
191 arichDigits.
appendNew(modch.first, modch.second, bitmap);
196 if (m_bgOverlay)
return;
198 unsigned nSlots = m_geoPar->getDetectorPlane().getNSlots();
199 for (
unsigned id = 1;
id < nSlots + 1;
id++) {
200 if (!m_modInfo->isActive(
id))
continue;
201 int nbkg = gRandom->Poisson(m_bkgLevel);
202 for (
int i = 0; i < nbkg; i++) {
203 arichDigits.
appendNew(
id, gRandom->Integer(144), bitmap);
209 void ARICHDigitizerModule::magFieldDistorsion(TVector2& hit,
int copyno)
213 double phi = m_geoPar->getDetectorPlane().getSlotPhi(copyno);
214 double r = m_geoPar->getDetectorPlane().getSlotR(copyno);
215 double z = m_geoPar->getDetectorZPosition() + m_geoPar->getHAPDGeometry().getWinThickness();
216 hitGlob.SetMagPhi(r, phi);
217 TVector2 shift = hit;
218 hitGlob += shift.Rotate(phi);
219 TVector3 Bfield = BFieldManager::getField(m_geoPar->getMasterVolume().pointToGlobal(TVector3(hitGlob.X(), hitGlob.Y(), z)));
220 double cc = m_geoPar->getHAPDGeometry().getPhotocathodeApdDistance() / abs(Bfield.Z());
221 shift.SetX(cc * Bfield.X());
222 shift.SetY(cc * Bfield.Y());
223 shift = shift.Rotate(-phi);
224 hit.SetX(hit.X() + shift.X());
225 hit.SetY(hit.Y() + shift.Y());
228 void ARICHDigitizerModule::endRun()
232 void ARICHDigitizerModule::terminate()
Class ARICHSimHit - Geant4 simulated hit for ARICH.
float getGlobalTime() const override
Get global time of hit.
int getModuleID() const
Get ID number of module that registered hit.
TVector2 getLocalPosition() const
Get local position of hit (in module coordinates)
Accessor to arrays stored in the data store.
T * appendNew()
Construct a new T object at the end of the array.
int getEntries() const
Get the number of objects in the array.
Type-safe access to single objects in the data store.
bool isValid() const
Check whether the object was created.
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Abstract base class for different kinds of events.
record to be used to store ASIC info