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.