11 #include <arich/modules/arichDigitizer/ARICHDigitizerModule.h>
14 #include <arich/dataobjects/ARICHSimHit.h>
15 #include <arich/dataobjects/ARICHDigit.h>
18 #include <framework/datastore/DataStore.h>
19 #include <framework/datastore/StoreArray.h>
22 #include <framework/logging/Logger.h>
25 #include <framework/geometry/BFieldManager.h>
27 #include <framework/dataobjects/BackgroundInfo.h>
36 using namespace boost;
60 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.");
63 setPropertyFlags(c_ParallelProcessingCertified);
66 addParam(
"TimeWindow", m_timeWindow,
"Readout time window width in ns", 250.0);
67 addParam(
"BackgroundHits", m_bkgLevel,
"Number of background hits per hapd per readout (electronics noise)", 0.066);
68 addParam(
"MagneticFieldDistorsion", m_bdistort,
"Apply image distortion due to non-perp. magnetic field", 0);
71 ARICHDigitizerModule::~ARICHDigitizerModule()
76 void ARICHDigitizerModule::initialize()
82 m_maxQE = m_simPar->getQE(3.1);
85 digits.registerInDataStore();
90 if (bgInfo->getMethod() == BackgroundInfo::c_Overlay) m_bgOverlay =
true;
95 void ARICHDigitizerModule::beginRun()
97 if (m_simPar->getNBkgHits() > 0) m_bkgLevel = m_simPar->getNBkgHits();
100 void ARICHDigitizerModule::event()
120 std::map<pair<int, int>,
int> photoElectrons;
121 std::map<pair<int, int>,
int> chipHits;
127 for (
int iHit = 0; iHit < nHits; ++iHit) {
134 if (globaltime < 0. || globaltime > m_timeWindow)
continue;
141 if (m_bdistort) magFieldDistorsion(locpos, moduleID);
144 if (!m_modInfo->isActive(moduleID))
continue;
148 m_geoPar->getHAPDGeometry().getXYChannel(locpos.X(), locpos.Y(), chX, chY);
150 if (chX < 0 && chY < 0)
continue;
152 int asicChannel = m_chnMap->getAsicFromXY(chX, chY);
161 double qe_scale = m_modInfo->getChannelQE(moduleID,
asicChannel) / m_maxQE;
163 if (qe_scale > 1.) B2ERROR(
"Channel QE is higher than QE applied in SensitiveDetector");
164 if (gRandom->Uniform(1.) > qe_scale)
continue;
167 chipHits[make_pair(moduleID,
asicChannel / 36)] += 1;
168 photoElectrons[make_pair(moduleID,
asicChannel)] += 1;
175 for (std::map<std::pair<int, int> ,
int>::iterator it = photoElectrons.begin(); it != photoElectrons.end(); ++it) {
177 std::pair<int, int> modch = it->first;
178 double npe = double(it->second);
181 npe /= (1.0 + m_simPar->getChipNegativeCrosstalk() * (double(chipHits[make_pair(modch.first, modch.second / 36)]) - 1.0));
182 if (npe < 1.0 && gRandom->Uniform(1) > npe)
continue;
187 for (
int i = 0; i < npe; i++) {
193 arichDigits.
appendNew(modch.first, modch.second, bitmap);
198 if (m_bgOverlay)
return;
200 unsigned nSlots = m_geoPar->getDetectorPlane().getNSlots();
201 for (
unsigned id = 1;
id < nSlots + 1;
id++) {
202 if (!m_modInfo->isActive(
id))
continue;
203 int nbkg = gRandom->Poisson(m_bkgLevel);
204 for (
int i = 0; i < nbkg; i++) {
205 arichDigits.
appendNew(
id, gRandom->Integer(144), bitmap);
211 void ARICHDigitizerModule::magFieldDistorsion(TVector2& hit,
int copyno)
215 double phi = m_geoPar->getDetectorPlane().getSlotPhi(copyno);
216 double r = m_geoPar->getDetectorPlane().getSlotR(copyno);
217 double z = m_geoPar->getDetectorZPosition() + m_geoPar->getHAPDGeometry().getWinThickness();
218 hitGlob.SetMagPhi(r, phi);
219 TVector2 shift = hit;
220 hitGlob += shift.Rotate(phi);
221 TVector3 Bfield = BFieldManager::getField(m_geoPar->getMasterVolume().pointToGlobal(TVector3(hitGlob.X(), hitGlob.Y(), z)));
222 double cc = m_geoPar->getHAPDGeometry().getPhotocathodeApdDistance() / abs(Bfield.Z());
223 shift.SetX(cc * Bfield.X());
224 shift.SetY(cc * Bfield.Y());
225 shift = shift.Rotate(-phi);
226 hit.SetX(hit.X() + shift.X());
227 hit.SetY(hit.Y() + shift.Y());
230 void ARICHDigitizerModule::endRun()
234 void ARICHDigitizerModule::terminate()