11#include <pxd/modules/pxdBackground/PXDBgTupleProducerModule.h>
12#include <framework/datastore/StoreObjPtr.h>
13#include <framework/datastore/StoreArray.h>
14#include <framework/dataobjects/EventMetaData.h>
15#include <pxd/reconstruction/PXDGainCalibrator.h>
16#include <pxd/reconstruction/PXDPixelMasker.h>
18#include <pxd/dataobjects/PXDDigit.h>
19#include <pxd/dataobjects/PXDCluster.h>
20#include <boost/format.hpp>
43 , m_nPXDSensors(0), m_hasPXDData(false)
48 addParam(
"timePeriod",
m_timePeriod,
"Period for background time series in seconds.",
double(1));
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.");
86 VxdID sensorID = gTools->getSensorIDFromPXDIndex(i);
103 auto const& sensorID = pair2.first;
111 for (
int uBin = 0; uBin <
m_nBinsU; ++uBin) {
112 for (
int vBin = 0; vBin <
m_nBinsV; ++vBin) {
113 std::pair<VxdID, int> key(sensorID,
getRegionID(uBin, vBin));
122 for (
int ui = 0; ui < info.getUCells(); ++ui) {
123 for (
int vi = 0; vi < info.getVCells(); ++vi) {
127 m_sensitiveAreaMap[sensorID] -= info.getVPitch(info.getVCellPosition(vi)) * info.getUPitch();
130 std::pair<VxdID, int> key(sensorID,
getRegionID(uBin, vBin));
139 B2WARNING(
"All pixels from Sensor=" << sensorID <<
" are masked.");
142 for (
int uBin = 0; uBin <
m_nBinsU; ++uBin) {
143 for (
int vBin = 0; vBin <
m_nBinsV; ++vBin) {
144 std::pair<VxdID, int> key(sensorID,
getRegionID(uBin, vBin));
146 B2WARNING(
"All pixels from subregion uBin=" << uBin <<
" vBin=" << vBin <<
" on Sensor=" << sensorID <<
" are masked.");
164 unsigned long long int ts = eventMetaDataPtr->getTime() /
m_timePeriod;
173 std::map<VxdID, double> occupancyMap;
176 VxdID sensorID = gTools->getSensorIDFromPXDIndex(i);
177 occupancyMap[sensorID] = 0.0;
185 for (
const PXDDigit& storeDigit : storeDigits) {
186 VxdID sensorID = storeDigit.getSensorID();
188 double hitEnergy = storeDigit.getCharge() * ADUToEnergy;
194 m_buffer[ts][sensorID].m_expo += hitEnergy;
199 m_buffer[ts][sensorID].m_regionDoseMap[regionID] += (hitEnergy /
Unit::J);
200 m_buffer[ts][sensorID].m_regionExpoMap[regionID] += hitEnergy;
204 auto& sensorID = pair.first;
205 auto& bgdata = pair.second;
206 bgdata.m_run = eventMetaDataPtr->getRun();
208 if (occupancyMap.find(sensorID) != occupancyMap.end()) {
209 bgdata.m_nEvents += 1;
210 bgdata.m_meanOccupancy += occupancyMap[sensorID];
211 if (occupancyMap[sensorID] > bgdata.m_maxOccupancy) {
212 bgdata.m_maxOccupancy = occupancyMap[sensorID];
214 if (occupancyMap[sensorID] < bgdata.m_minOccupancy) {
215 bgdata.m_minOccupancy = occupancyMap[sensorID];
220 for (
const PXDCluster& cluster : storeClusters) {
222 VxdID sensorID = cluster.getSensorID();
225 auto cluster_uID = info.getUCellID(cluster.getU());
226 auto cluster_vID = info.getVCellID(cluster.getV());
231 double clusterEnergy = cluster.getCharge() * ADUToEnergy;
233 if (cluster.getSize() == 1 && clusterEnergy < 10000 * Unit::eV && clusterEnergy > 6000 *
Unit::eV) {
234 m_buffer[ts][sensorID].m_softPhotonFlux += 1.0;
235 m_buffer[ts][sensorID].m_regionSoftPhotonFluxMap[regionID] += 1.0;
236 }
else if (cluster.getSize() == 1 && clusterEnergy > 10000 *
Unit::eV) {
237 m_buffer[ts][sensorID].m_hardPhotonFlux += 1.0;
238 m_buffer[ts][sensorID].m_regionHardPhotonFluxMap[regionID] += 1.0;
239 }
else if (cluster.getSize() > 1 && clusterEnergy > 10000 *
Unit::eV) {
240 m_buffer[ts][sensorID].m_chargedParticleFlux += 1.0;
241 m_buffer[ts][sensorID].m_regionChargedParticleFluxMap[regionID] += 1.0;
251 TTree* treeBEAST =
new TTree(
"tout",
"BEAST data tree");
254 treeBEAST->Branch(
"ts", &(ts));
257 auto& sensorID = pair.first;
258 auto& bgdata = pair.second;
259 string sensorDescr = sensorID;
260 treeBEAST->Branch(str(format(
"pxd_%1%_run") % sensorDescr).c_str(), &(bgdata.m_run));
261 treeBEAST->Branch(str(format(
"pxd_%1%_nEvents") % sensorDescr).c_str(), &(bgdata.m_nEvents));
262 treeBEAST->Branch(str(format(
"pxd_%1%_minOccupancy") % sensorDescr).c_str(), &(bgdata.m_minOccupancy));
263 treeBEAST->Branch(str(format(
"pxd_%1%_maxOccupancy") % sensorDescr).c_str(), &(bgdata.m_maxOccupancy));
264 treeBEAST->Branch(str(format(
"pxd_%1%_meanOccupancy") % sensorDescr).c_str(), &(bgdata.m_meanOccupancy));
265 treeBEAST->Branch(str(format(
"pxd_%1%_exposition") % sensorDescr).c_str(), &(bgdata.m_expo));
266 treeBEAST->Branch(str(format(
"pxd_%1%_dose") % sensorDescr).c_str(), &(bgdata.m_dose));
267 treeBEAST->Branch(str(format(
"pxd_%1%_softPhotonFlux") % sensorDescr).c_str(), &(bgdata.m_softPhotonFlux));
268 treeBEAST->Branch(str(format(
"pxd_%1%_hardPhotonFlux") % sensorDescr).c_str(), &(bgdata.m_hardPhotonFlux));
269 treeBEAST->Branch(str(format(
"pxd_%1%_chargedParticleFlux") % sensorDescr).c_str(),
270 &(bgdata.m_chargedParticleFlux));
272 for (
int uBin = 0; uBin <
m_nBinsU; ++uBin) {
273 for (
int vBin = 0; vBin <
m_nBinsV; ++vBin) {
275 treeBEAST->Branch(str(format(
"pxd_%1%_region_%2%_%3%_exposition") % sensorDescr % uBin % vBin).c_str(),
276 &(bgdata.m_regionExpoMap[regionID]));
277 treeBEAST->Branch(str(format(
"pxd_%1%_region_%2%_%3%_dose") % sensorDescr % uBin % vBin).c_str(),
278 &(bgdata.m_regionDoseMap[regionID]));
279 treeBEAST->Branch(str(format(
"pxd_%1%_region_%2%_%3%_softPhotonFlux") % sensorDescr % uBin % vBin).c_str(),
280 &(bgdata.m_regionSoftPhotonFluxMap[regionID]));
281 treeBEAST->Branch(str(format(
"pxd_%1%_region_%2%_%3%_hardPhotonFlux") % sensorDescr % uBin % vBin).c_str(),
282 &(bgdata.m_regionHardPhotonFluxMap[regionID]));
283 treeBEAST->Branch(str(format(
"pxd_%1%_region_%2%_%3%_chargedParticleFlux") % sensorDescr % uBin % vBin).c_str(),
284 &(bgdata.m_regionChargedParticleFluxMap[regionID]));
290 for (
auto const& pair1 :
m_buffer) {
291 auto const& timestamp = pair1.first;
292 auto const& sensors = pair1.second;
296 for (
auto const& pair2 : sensors) {
297 auto const& sensorID = pair2.first;
298 auto const& bgdata = pair2.second;
305 m_sensorData[sensorID].m_meanOccupancy = bgdata.m_meanOccupancy / bgdata.m_nEvents;
307 if (currentSensorArea > 0) {
308 m_sensorData[sensorID].m_dose *= (1.0 / (currentComponentTime /
Unit::s)) * (1000 / currentSensorMass);
309 m_sensorData[sensorID].m_expo *= (1.0 / currentSensorArea) * (1.0 / (currentComponentTime /
Unit::s));
310 m_sensorData[sensorID].m_softPhotonFlux *= (1.0 / currentSensorArea) * (1.0 / (currentComponentTime /
Unit::s));
311 m_sensorData[sensorID].m_hardPhotonFlux *= (1.0 / currentSensorArea) * (1.0 / (currentComponentTime /
Unit::s));
312 m_sensorData[sensorID].m_chargedParticleFlux *= (1.0 / currentSensorArea) * (1.0 / (currentComponentTime /
Unit::s));
315 std::pair<VxdID, int> key(sensorID, regionID);
318 if (currentRegionArea > 0) {
319 m_sensorData[sensorID].m_regionDoseMap[regionID] *= (1.0 / currentComponentTime) * (1000 / currentRegionMass);
320 m_sensorData[sensorID].m_regionExpoMap[regionID] *= (1.0 / currentRegionArea) * (1.0 / (currentComponentTime /
Unit::s));
321 m_sensorData[sensorID].m_regionSoftPhotonFluxMap[regionID] *= (1.0 / currentRegionArea) * (1.0 / (currentComponentTime /
Unit::s));
322 m_sensorData[sensorID].m_regionHardPhotonFluxMap[regionID] *= (1.0 / currentRegionArea) * (1.0 / (currentComponentTime /
Unit::s));
323 m_sensorData[sensorID].m_regionChargedParticleFluxMap[regionID] *= (1.0 / currentRegionArea) * (1.0 /
324 (currentComponentTime /
Unit::s));
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...
std::map< std::pair< VxdID, int >, int > m_regionSensitivePixelMap
Struct to hold region-wise number of sensitive pixels.
double m_timePeriod
Period for background time series.
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::map< unsigned long long int, std::map< VxdID, SensorData > > m_buffer
Struct to hold sensor-wise background data.
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.
bool m_hasPXDData
Flag to indicate there was at least one PXDDigit in the run.
void beginRun() override final
Start-of-run initializations.
PXDBgTupleProducerModule()
Constructor.
std::string m_outputFileName
output tuple file name
int m_nPXDSensors
Total number of PXD sensors.
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.
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.
bool isRequired(const std::string &name="")
Ensure this array/object has been registered previously.
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.