11#include <pxd/modules/pxdBackground/PXDMCBgTupleProducerModule.h>
12#include <framework/datastore/DataStore.h>
13#include <framework/datastore/StoreObjPtr.h>
14#include <framework/datastore/StoreArray.h>
15#include <framework/dataobjects/BackgroundMetaData.h>
16#include <pxd/reconstruction/PXDGainCalibrator.h>
17#include <pxd/reconstruction/PXDPixelMasker.h>
19#include <pxd/dataobjects/PXDDigit.h>
20#include <pxd/dataobjects/PXDCluster.h>
21#include <boost/format.hpp>
44 , m_hasPXDData(false), m_componentTime(0)
51 addParam(
"nBinsU",
m_nBinsU,
"Number of regions per sensor along u side",
int(1));
52 addParam(
"nBinsV",
m_nBinsV,
"Number of regions per sensor along v side",
int(6));
79 if (gTools->getNumberOfPXDLayers() == 0) {
80 B2WARNING(
"Missing geometry for PXD, PXD-masking is skiped.");
82 int nPXDSensors = gTools->getNumberOfPXDSensors();
85 for (
int i = 0; i < nPXDSensors; i++) {
86 VxdID sensorID = gTools->getSensorIDFromPXDIndex(i);
101 auto const& sensorID = pair2.first;
109 for (
int uBin = 0; uBin <
m_nBinsU; ++uBin) {
110 for (
int vBin = 0; vBin <
m_nBinsV; ++vBin) {
111 std::pair<VxdID, int> key(sensorID,
getRegionID(uBin, vBin));
120 for (
int ui = 0; ui < info.getUCells(); ++ui) {
121 for (
int vi = 0; vi < info.getVCells(); ++vi) {
125 m_sensitiveAreaMap[sensorID] -= info.getVPitch(info.getVCellPosition(vi)) * info.getUPitch();
128 std::pair<VxdID, int> key(sensorID,
getRegionID(uBin, vBin));
137 B2WARNING(
"All pixels from Sensor=" << sensorID <<
" are masked.");
140 for (
int uBin = 0; uBin <
m_nBinsU; ++uBin) {
141 for (
int vBin = 0; vBin <
m_nBinsV; ++vBin) {
142 std::pair<VxdID, int> key(sensorID,
getRegionID(uBin, vBin));
144 B2WARNING(
"All pixels from subregion uBin=" << uBin <<
" vBin=" << vBin <<
" on Sensor=" << sensorID <<
" are masked.");
163 std::map<VxdID, double> occupancyMap;
170 for (
const PXDDigit& storeDigit : storeDigits) {
171 VxdID sensorID = storeDigit.getSensorID();
173 double hitEnergy = storeDigit.getCharge() * ADUToEnergy;
185 m_sensorData[sensorID].m_regionExpoMap[regionID] += hitEnergy;
189 auto& sensorID = pair.first;
190 auto& bgdata = pair.second;
193 if (occupancyMap.find(sensorID) != occupancyMap.end()) {
194 bgdata.m_meanOccupancy += occupancyMap[sensorID];
198 for (
const PXDCluster& cluster : storeClusters) {
200 VxdID sensorID = cluster.getSensorID();
203 auto cluster_uID = info.getUCellID(cluster.getU());
204 auto cluster_vID = info.getVCellID(cluster.getV());
209 double clusterEnergy = cluster.getCharge() * ADUToEnergy;
211 if (cluster.getSize() == 1 && clusterEnergy < 10000 * Unit::eV && clusterEnergy > 6000 *
Unit::eV) {
213 m_sensorData[sensorID].m_regionSoftPhotonFluxMap[regionID] += 1.0;
214 }
else if (cluster.getSize() == 1 && clusterEnergy > 10000 *
Unit::eV) {
216 m_sensorData[sensorID].m_regionHardPhotonFluxMap[regionID] += 1.0;
217 }
else if (cluster.getSize() > 1 && clusterEnergy > 10000 *
Unit::eV) {
219 m_sensorData[sensorID].m_regionChargedParticleFluxMap[regionID] += 1.0;
229 TTree* treeBEAST =
new TTree(
"tout",
"BEAST data tree");
234 B2RESULT(
"Total real time is " << currentComponentTime /
Unit::us <<
" microseconds.");
235 B2RESULT(
"This is equivalent to " << currentComponentTime /
m_integrationTime <<
" random triggered events.");
238 auto& sensorID = pair.first;
239 auto& bgdata = pair.second;
247 if (currentSensorArea > 0) {
248 m_sensorData[sensorID].m_dose *= (1.0 / (currentComponentTime /
Unit::s)) * (1000 / currentSensorMass);
249 m_sensorData[sensorID].m_expo *= (1.0 / currentSensorArea) * (1.0 / (currentComponentTime /
Unit::s));
250 m_sensorData[sensorID].m_softPhotonFlux *= (1.0 / currentSensorArea) * (1.0 / (currentComponentTime /
Unit::s));
251 m_sensorData[sensorID].m_hardPhotonFlux *= (1.0 / currentSensorArea) * (1.0 / (currentComponentTime /
Unit::s));
252 m_sensorData[sensorID].m_chargedParticleFlux *= (1.0 / currentSensorArea) * (1.0 / (currentComponentTime /
Unit::s));
255 std::pair<VxdID, int> key(sensorID, regionID);
258 if (currentRegionArea > 0) {
259 m_sensorData[sensorID].m_regionDoseMap[regionID] *= (1.0 / currentComponentTime) * (1000 / currentRegionMass);
260 m_sensorData[sensorID].m_regionExpoMap[regionID] *= (1.0 / currentRegionArea) * (1.0 / (currentComponentTime /
Unit::s));
261 m_sensorData[sensorID].m_regionSoftPhotonFluxMap[regionID] *= (1.0 / currentRegionArea) * (1.0 / (currentComponentTime /
Unit::s));
262 m_sensorData[sensorID].m_regionHardPhotonFluxMap[regionID] *= (1.0 / currentRegionArea) * (1.0 / (currentComponentTime /
Unit::s));
263 m_sensorData[sensorID].m_regionChargedParticleFluxMap[regionID] *= (1.0 / currentRegionArea) * (1.0 /
264 (currentComponentTime /
Unit::s));
270 string sensorDescr = sensorID;
271 treeBEAST->Branch(str(format(
"pxd_%1%_meanOccupancy") % sensorDescr).c_str(), &(bgdata.m_meanOccupancy));
272 treeBEAST->Branch(str(format(
"pxd_%1%_exposition") % sensorDescr).c_str(), &(bgdata.m_expo));
273 treeBEAST->Branch(str(format(
"pxd_%1%_dose") % sensorDescr).c_str(), &(bgdata.m_dose));
274 treeBEAST->Branch(str(format(
"pxd_%1%_softPhotonFlux") % sensorDescr).c_str(), &(bgdata.m_softPhotonFlux));
275 treeBEAST->Branch(str(format(
"pxd_%1%_hardPhotonFlux") % sensorDescr).c_str(), &(bgdata.m_hardPhotonFlux));
276 treeBEAST->Branch(str(format(
"pxd_%1%_chargedParticleFlux") % sensorDescr).c_str(),
277 &(bgdata.m_chargedParticleFlux));
279 for (
int uBin = 0; uBin <
m_nBinsU; ++uBin) {
280 for (
int vBin = 0; vBin <
m_nBinsV; ++vBin) {
282 treeBEAST->Branch(str(format(
"pxd_%1%_region_%2%_%3%_exposition") % sensorDescr % uBin % vBin).c_str(),
283 &(bgdata.m_regionExpoMap[regionID]));
284 treeBEAST->Branch(str(format(
"pxd_%1%_region_%2%_%3%_dose") % sensorDescr % uBin % vBin).c_str(),
285 &(bgdata.m_regionDoseMap[regionID]));
286 treeBEAST->Branch(str(format(
"pxd_%1%_region_%2%_%3%_softPhotonFlux") % sensorDescr % uBin % vBin).c_str(),
287 &(bgdata.m_regionSoftPhotonFluxMap[regionID]));
288 treeBEAST->Branch(str(format(
"pxd_%1%_region_%2%_%3%_hardPhotonFlux") % sensorDescr % uBin % vBin).c_str(),
289 &(bgdata.m_regionHardPhotonFluxMap[regionID]));
290 treeBEAST->Branch(str(format(
"pxd_%1%_region_%2%_%3%_chargedParticleFlux") % sensorDescr % uBin % vBin).c_str(),
291 &(bgdata.m_regionChargedParticleFluxMap[regionID]));
@ c_Persistent
Object is available during entire execution time.
void setDescription(const std::string &description)
Sets the description of the module.
The PXD Cluster class This class stores all information about reconstructed PXD clusters The position...
unsigned short getBinV(VxdID id, unsigned int vid) const
Get gain correction bin along sensor v side.
unsigned short getBinU(VxdID id, unsigned int uid, unsigned int vid) const
Get gain correction bin along sensor u side.
float getADUToEnergy(VxdID id, unsigned int uid, unsigned int vid) const
Get conversion factor from ADU to energy.
static PXDGainCalibrator & getInstance()
Main (and only) way to access the PXDGainCalibrator.
std::map< std::pair< VxdID, int >, int > m_regionSensitivePixelMap
Struct to hold region-wise number of sensitive pixels.
void initialize() override final
Initialize module.
bool m_maskDeadPixels
Correct bg rates by taking into account masked pixels.
std::map< VxdID, SensorData > m_sensorData
Struct to hold sensor-wise background data.
std::map< VxdID, double > m_sensitiveAreaMap
Struct to hold sensor-wise sensitive area.
double m_integrationTime
Integration time of PXD.
int m_nBinsV
Number of regions per sensor along v side.
const double c_densitySi
Density of crystalline Silicon.
void terminate() override final
Final summary and cleanup.
int getRegionID(int uBin, int vBin) const
Get region id from region uBin and vBin.
const PXD::SensorInfo & getInfo(VxdID sensorID) const
This is a shortcut to getting PXD::SensorInfo from the GeoCache.
void event() override final
Event processing.
int m_nBinsU
Number of regions per sensor along u side.
std::map< std::pair< VxdID, int >, double > m_regionSensitiveAreaMap
Struct to hold region-wise sensitive area.
std::map< VxdID, int > m_sensitivePixelMap
Struct to hold sensor-wise number of sensitive pixels.
double getRegionArea(VxdID sensorID, int vBin) const
Return area of the region with the given sensor ID and region vBin.
std::string m_storeBgMetaDataName
Name of the persistent BackgroundMetaDta object.
double getSensorArea(VxdID sensorID) const
Return area of the sensor with the given sensor ID.
std::string m_storeDigitsName
PXDDigits StoreArray name.
std::string m_storeClustersName
PXDClusters StoreArray name.
double m_overrideComponentTime
Time of current component given by user.
bool m_hasPXDData
Flag to indicate there was at least one PXDDigit in the run.
void beginRun() override final
Start-of-run initializations.
PXDMCBgTupleProducerModule()
Constructor.
double m_componentTime
Time of current component.
std::string m_outputFileName
output tuple file name
static PXDPixelMasker & getInstance()
Main (and only) way to access the PXDPixelMasker.
Specific implementation of SensorInfo for PXD Sensors which provides additional pixel specific inform...
const std::string & getName() const
Return name under which the object is saved in the DataStore.
Accessor to arrays stored in the data store.
int getEntries() const
Get the number of objects in the array.
Type-safe access to single objects in the data store.
static const double us
[microsecond]
static const double eV
[electronvolt]
static const double J
[joule]
static const double s
[second]
static GeoCache & getInstance()
Return a reference to the singleton instance.
const GeoTools * getGeoTools()
Return a raw pointer to a GeoTools object.
Class to uniquely identify a any structure of the PXD and SVD.
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.
Namespace to encapsulate code needed for simulation and reconstrucion of the PXD.
Abstract base class for different kinds of events.
Struct to hold data of an PXD sensor.