10 #include <background/modules/BeamBkgHitRateMonitor/PXDHitRateCounter.h>
11 #include <pxd/reconstruction/PXDGainCalibrator.h>
12 #include <pxd/reconstruction/PXDPixelMasker.h>
16 #include <framework/logging/Logger.h>
25 namespace Background {
27 void PXDHitRateCounter::initialize(TTree* tree)
30 auto gTools = VXD::GeoCache::getInstance().getGeoTools();
31 if (gTools->getNumberOfPXDLayers() == 0) {
32 B2FATAL(
"Missing geometry for PXD.");
35 m_nPXDSensors = gTools->getNumberOfPXDSensors();
38 m_digits.isOptional();
41 m_clusters.isOptional();
44 "meanOccupancies[40]/F:maxOccupancies[40]/F:doseRates[40]/F:softPhotonFluxes[40]/F:hardPhotonFluxes[40]/F:chargedFluxes[40]/F:segmentDoseRates[240]/F:segmentSoftPhotonFluxes[240]/F:segmentHardPhotonFluxes[240]/F:segmentChargedFluxes[240]/F:averageRate/F:numEvents/I:valid/O";
47 tree->Branch(
"pxd", &m_rates, leaflist.c_str());
50 if (m_integrationTime <= 0) B2FATAL(
"invalid integration time window for PXD: " << m_integrationTime);
56 void PXDHitRateCounter::clear()
61 void PXDHitRateCounter::accumulate(
unsigned timeStamp)
64 if ((not m_digits.isValid()) or (not m_clusters.isValid()))
return;
67 auto& rates = m_buffer[timeStamp];
73 rates.averageRate += m_digits.getEntries();
76 auto gTools = VXD::GeoCache::getInstance().getGeoTools();
79 float occupancies[40] = {0};
80 for (
const PXDDigit& storeDigit : m_digits) {
81 VxdID sensorID = storeDigit.getSensorID();
82 int index = gTools->getPXDSensorIndex(storeDigit.getSensorID());
83 int vBin = PXD::PXDGainCalibrator::getInstance().getBinV(sensorID, storeDigit.getVCellID(), 6);
84 double ADUToEnergy = PXD::PXDGainCalibrator::getInstance().getADUToEnergy(sensorID, storeDigit.getUCellID(),
85 storeDigit.getVCellID());
86 double hitEnergy = storeDigit.getCharge() * ADUToEnergy;
87 rates.doseRates[index] += (hitEnergy / Unit::J);
88 occupancies[index] += 1.0;
89 rates.segmentDoseRates[vBin + index * 6] += (hitEnergy / Unit::J);
92 for (
int index = 0; index < m_nPXDSensors; index++) {
93 if (m_activePixels[index] > 0) {
94 occupancies[index] /= m_activePixels[index];
96 rates.meanOccupancies[index] += occupancies[index];
97 if (rates.maxOccupancies[index] < occupancies[index]) {
98 rates.maxOccupancies[index] = occupancies[index];
103 for (
const PXDCluster& cluster : m_clusters) {
105 VxdID sensorID = cluster.getSensorID();
106 int index = gTools->getPXDSensorIndex(sensorID);
107 auto info = getInfo(sensorID);
109 auto cluster_uID = info.getUCellID(cluster.getU());
110 auto cluster_vID = info.getVCellID(cluster.getV());
111 int vBin = PXD::PXDGainCalibrator::getInstance().getBinV(sensorID, cluster_vID, 6);
112 double ADUToEnergy = PXD::PXDGainCalibrator::getInstance().getADUToEnergy(sensorID, cluster_uID, cluster_vID);
113 double clusterEnergy = cluster.getCharge() * ADUToEnergy;
115 if (cluster.getSize() == 1 && clusterEnergy < 10000 * Unit::eV && clusterEnergy > 6000 * Unit::eV) {
116 rates.softPhotonFluxes[index] += 1.0;
117 rates.segmentSoftPhotonFluxes[vBin + index * 6] += 1.0;
118 }
else if (cluster.getSize() == 1 && clusterEnergy > 10000 * Unit::eV) {
119 rates.hardPhotonFluxes[index] += 1.0;
120 rates.segmentHardPhotonFluxes[vBin + index * 6] += 1.0;
121 }
else if (cluster.getSize() > 1 && clusterEnergy > 10000 * Unit::eV) {
122 rates.chargedFluxes[index] += 1.0;
123 rates.segmentChargedFluxes[vBin + index * 6] += 1.0;
131 void PXDHitRateCounter::normalize(
unsigned timeStamp)
134 m_rates = m_buffer[timeStamp];
136 if (not m_rates.valid)
return;
138 if (m_rates.numEvents == 0)
return;
141 m_rates.averageRate /= m_rates.numEvents;
144 double currentComponentTime = m_rates.numEvents * m_integrationTime;
147 auto gTools = VXD::GeoCache::getInstance().getGeoTools();
150 for (
int index = 0; index < m_nPXDSensors; index++) {
151 VxdID sensorID = gTools->getSensorIDFromPXDIndex(index);
152 auto info = getInfo(sensorID);
153 double currentSensorMass = m_activeAreas[index] * info.getThickness() * c_densitySi;
154 double currentSensorArea = m_activeAreas[index];
156 m_rates.meanOccupancies[index] /= m_rates.numEvents;
157 if (currentSensorArea > 0) {
158 m_rates.doseRates[index] *= (1.0 / (currentComponentTime / Unit::s)) * (1000 / currentSensorMass);
159 m_rates.softPhotonFluxes[index] *= (1.0 / currentSensorArea) * (1.0 / (currentComponentTime / Unit::s));
160 m_rates.hardPhotonFluxes[index] *= (1.0 / currentSensorArea) * (1.0 / (currentComponentTime / Unit::s));
161 m_rates.chargedFluxes[index] *= (1.0 / currentSensorArea) * (1.0 / (currentComponentTime / Unit::s));
164 for (
int vBin = 0; vBin < 6; ++vBin) {
165 double currentSegmentMass = m_segmentActiveAreas[vBin + index * 6] * info.getThickness() * c_densitySi;
166 double currentSegmentArea = m_segmentActiveAreas[vBin + index * 6];
167 if (currentSegmentArea > 0) {
168 m_rates.segmentDoseRates[vBin + index * 6] *= (1.0 / (currentComponentTime / Unit::s)) * (1000 / currentSegmentMass);
169 m_rates.segmentSoftPhotonFluxes[vBin + index * 6] *= (1.0 / currentSegmentArea) * (1.0 / (currentComponentTime / Unit::s));
170 m_rates.segmentHardPhotonFluxes[vBin + index * 6] *= (1.0 / currentSegmentArea) * (1.0 / (currentComponentTime / Unit::s));
171 m_rates.segmentChargedFluxes[vBin + index * 6] *= (1.0 / currentSegmentArea) * (1.0 /
172 (currentComponentTime / Unit::s));
179 void PXDHitRateCounter::setActivePixels()
182 auto gTools = VXD::GeoCache::getInstance().getGeoTools();
185 for (
int index = 0; index < m_nPXDSensors; index++) {
186 VxdID sensorID = gTools->getSensorIDFromPXDIndex(index);
187 auto info = getInfo(sensorID);
190 m_activePixels[index] = info.getUCells() * info.getVCells();
192 m_activeAreas[index] = info.getWidth() * info.getLength();
195 for (
int vBin = 0; vBin < 6; ++vBin) {
198 m_segmentActivePixels[vBin + index * 6] = info.getUCells() * info.getVCells() / 6;
200 double v = info.getVCellPosition(vBin * info.getVCells() / 6);
202 m_segmentActiveAreas[vBin + index * 6] = info.getWidth() * info.getVPitch(v) * info.getVCells() / 6;
205 if (m_maskDeadPixels) {
206 for (
int ui = 0; ui < info.getUCells(); ++ui) {
207 for (
int vi = 0; vi < info.getVCells(); ++vi) {
208 if (PXD::PXDPixelMasker::getInstance().pixelDead(sensorID, ui, vi)
209 || !PXD::PXDPixelMasker::getInstance().pixelOK(sensorID, ui, vi)) {
210 m_activePixels[index] -= 1;
211 m_activeAreas[index] -= info.getVPitch(info.getVCellPosition(vi)) * info.getUPitch();
212 int vBin = PXD::PXDGainCalibrator::getInstance().getBinV(sensorID, vi, 6);
213 m_segmentActivePixels[vBin + index * 6] -= 1;
214 m_segmentActiveAreas[vBin + index * 6] -= info.getVPitch(info.getVCellPosition(vi)) * info.getUPitch();
The PXD Cluster class This class stores all information about reconstructed PXD clusters The position...
Class to uniquely identify a any structure of the PXD and SVD.
Abstract base class for different kinds of events.