12 #include <background/modules/BeamBkgHitRateMonitor/PXDHitRateCounter.h>
13 #include <pxd/reconstruction/PXDGainCalibrator.h>
14 #include <pxd/reconstruction/PXDPixelMasker.h>
18 #include <framework/logging/Logger.h>
27 namespace Background {
29 void PXDHitRateCounter::initialize(TTree* tree)
32 auto gTools = VXD::GeoCache::getInstance().getGeoTools();
33 if (gTools->getNumberOfPXDLayers() == 0) {
34 B2FATAL(
"Missing geometry for PXD.");
37 m_nPXDSensors = gTools->getNumberOfPXDSensors();
40 m_digits.isOptional();
43 m_clusters.isOptional();
46 "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";
49 tree->Branch(
"pxd", &m_rates, leaflist.c_str());
52 if (m_integrationTime <= 0) B2FATAL(
"invalid integration time window for PXD: " << m_integrationTime);
58 void PXDHitRateCounter::clear()
63 void PXDHitRateCounter::accumulate(
unsigned timeStamp)
66 if ((not m_digits.isValid()) or (not m_clusters.isValid()))
return;
69 auto& rates = m_buffer[timeStamp];
75 rates.averageRate += m_digits.getEntries();
78 auto gTools = VXD::GeoCache::getInstance().getGeoTools();
81 float occupancies[40] = {0};
82 for (
const PXDDigit& storeDigit : m_digits) {
83 VxdID sensorID = storeDigit.getSensorID();
84 int index = gTools->getPXDSensorIndex(storeDigit.getSensorID());
85 int vBin = PXD::PXDGainCalibrator::getInstance().getBinV(sensorID, storeDigit.getVCellID(), 6);
86 double ADUToEnergy = PXD::PXDGainCalibrator::getInstance().getADUToEnergy(sensorID, storeDigit.getUCellID(),
87 storeDigit.getVCellID());
88 double hitEnergy = storeDigit.getCharge() * ADUToEnergy;
89 rates.doseRates[index] += (hitEnergy / Unit::J);
90 occupancies[index] += 1.0;
91 rates.segmentDoseRates[vBin + index * 6] += (hitEnergy / Unit::J);
94 for (
int index = 0; index < m_nPXDSensors; index++) {
95 if (m_activePixels[index] > 0) {
96 occupancies[index] /= m_activePixels[index];
98 rates.meanOccupancies[index] += occupancies[index];
99 if (rates.maxOccupancies[index] < occupancies[index]) {
100 rates.maxOccupancies[index] = occupancies[index];
105 for (
const PXDCluster& cluster : m_clusters) {
107 VxdID sensorID = cluster.getSensorID();
108 int index = gTools->getPXDSensorIndex(sensorID);
109 auto info = getInfo(sensorID);
111 auto cluster_uID = info.getUCellID(cluster.getU());
112 auto cluster_vID = info.getVCellID(cluster.getV());
113 int vBin = PXD::PXDGainCalibrator::getInstance().getBinV(sensorID, cluster_vID, 6);
114 double ADUToEnergy = PXD::PXDGainCalibrator::getInstance().getADUToEnergy(sensorID, cluster_uID, cluster_vID);
115 double clusterEnergy = cluster.getCharge() * ADUToEnergy;
117 if (cluster.getSize() == 1 && clusterEnergy < 10000 * Unit::eV && clusterEnergy > 6000 * Unit::eV) {
118 rates.softPhotonFluxes[index] += 1.0;
119 rates.segmentSoftPhotonFluxes[vBin + index * 6] += 1.0;
120 }
else if (cluster.getSize() == 1 && clusterEnergy > 10000 * Unit::eV) {
121 rates.hardPhotonFluxes[index] += 1.0;
122 rates.segmentHardPhotonFluxes[vBin + index * 6] += 1.0;
123 }
else if (cluster.getSize() > 1 && clusterEnergy > 10000 * Unit::eV) {
124 rates.chargedFluxes[index] += 1.0;
125 rates.segmentChargedFluxes[vBin + index * 6] += 1.0;
133 void PXDHitRateCounter::normalize(
unsigned timeStamp)
136 m_rates = m_buffer[timeStamp];
138 if (not m_rates.valid)
return;
140 if (m_rates.numEvents == 0)
return;
143 m_rates.averageRate /= m_rates.numEvents;
146 double currentComponentTime = m_rates.numEvents * m_integrationTime;
149 auto gTools = VXD::GeoCache::getInstance().getGeoTools();
152 for (
int index = 0; index < m_nPXDSensors; index++) {
153 VxdID sensorID = gTools->getSensorIDFromPXDIndex(index);
154 auto info = getInfo(sensorID);
155 double currentSensorMass = m_activeAreas[index] * info.getThickness() * c_densitySi;
156 double currentSensorArea = m_activeAreas[index];
158 m_rates.meanOccupancies[index] /= m_rates.numEvents;
159 if (currentSensorArea > 0) {
160 m_rates.doseRates[index] *= (1.0 / (currentComponentTime / Unit::s)) * (1000 / currentSensorMass);
161 m_rates.softPhotonFluxes[index] *= (1.0 / currentSensorArea) * (1.0 / (currentComponentTime / Unit::s));
162 m_rates.hardPhotonFluxes[index] *= (1.0 / currentSensorArea) * (1.0 / (currentComponentTime / Unit::s));
163 m_rates.chargedFluxes[index] *= (1.0 / currentSensorArea) * (1.0 / (currentComponentTime / Unit::s));
166 for (
int vBin = 0; vBin < 6; ++vBin) {
167 double currentSegmentMass = m_segmentActiveAreas[vBin + index * 6] * info.getThickness() * c_densitySi;
168 double currentSegmentArea = m_segmentActiveAreas[vBin + index * 6];
169 if (currentSegmentArea > 0) {
170 m_rates.segmentDoseRates[vBin + index * 6] *= (1.0 / (currentComponentTime / Unit::s)) * (1000 / currentSegmentMass);
171 m_rates.segmentSoftPhotonFluxes[vBin + index * 6] *= (1.0 / currentSegmentArea) * (1.0 / (currentComponentTime / Unit::s));
172 m_rates.segmentHardPhotonFluxes[vBin + index * 6] *= (1.0 / currentSegmentArea) * (1.0 / (currentComponentTime / Unit::s));
173 m_rates.segmentChargedFluxes[vBin + index * 6] *= (1.0 / currentSegmentArea) * (1.0 /
174 (currentComponentTime / Unit::s));
181 void PXDHitRateCounter::setActivePixels()
184 auto gTools = VXD::GeoCache::getInstance().getGeoTools();
187 for (
int index = 0; index < m_nPXDSensors; index++) {
188 VxdID sensorID = gTools->getSensorIDFromPXDIndex(index);
189 auto info = getInfo(sensorID);
192 m_activePixels[index] = info.getUCells() * info.getVCells();
194 m_activeAreas[index] = info.getWidth() * info.getLength();
197 for (
int vBin = 0; vBin < 6; ++vBin) {
200 m_segmentActivePixels[vBin + index * 6] = info.getUCells() * info.getVCells() / 6;
202 double v = info.getVCellPosition(vBin * info.getVCells() / 6);
204 m_segmentActiveAreas[vBin + index * 6] = info.getWidth() * info.getVPitch(v) * info.getVCells() / 6;
207 if (m_maskDeadPixels) {
208 for (
int ui = 0; ui < info.getUCells(); ++ui) {
209 for (
int vi = 0; vi < info.getVCells(); ++vi) {
210 if (PXD::PXDPixelMasker::getInstance().pixelDead(sensorID, ui, vi)
211 || !PXD::PXDPixelMasker::getInstance().pixelOK(sensorID, ui, vi)) {
212 m_activePixels[index] -= 1;
213 m_activeAreas[index] -= info.getVPitch(info.getVCellPosition(vi)) * info.getUPitch();
214 int vBin = PXD::PXDGainCalibrator::getInstance().getBinV(sensorID, vi, 6);
215 m_segmentActivePixels[vBin + index * 6] -= 1;
216 m_segmentActiveAreas[vBin + index * 6] -= info.getVPitch(info.getVCellPosition(vi)) * info.getUPitch();