ATLAS Offline Software
Loading...
Searching...
No Matches
ITkPixelDataRateMonTool.cxx
Go to the documentation of this file.
1/*
2Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
5/*
6* Author: Paul Chabrillat, starting from Ondra Kovanda and Noemi Calace work
7* Date: 12/11/2024
8* Description: Athena tool wrapper around the ITkPix encoder to study data rate as a function of chip's position in detector
9*/
10
12#include <stdexcept>
13
14ITkPixelDataRateMonTool::ITkPixelDataRateMonTool(const std::string& type, const std::string& name, const IInterface* parent)
15 : AthAlgTool(type, name, parent)
16{
17}
18
19
21
22 // ----------- Check services presence -----------
23
24 // Checks that the histograming service is up and running
25 ATH_CHECK(m_thistSvc.retrieve());
26
27 // Checks that the pixel readout service is up and running
28 ATH_CHECK(m_pixelReadout.retrieve());
29
30 // Checks that the pixel id help service is up and running
31 ATH_CHECK(detStore()->retrieve(m_pixIdHelper, "PixelID"));
32
33 // Checks that the pixel manager service is up and running
34 ATH_CHECK(detStore()->retrieve(m_detManager, "ITkPixel"));
35
36 // ----------- Finds the different regions and layers to create histograms for them -----------
37 std::vector<std::vector<float>> barrel_module_z(10); // List of z coordinates for modules in barrel
38 std::vector<std::vector<float>> endcap_module_z(10); //List of z coordinates for modules in endcap
39
40 for (InDetDD::SiDetectorElementCollection::const_iterator iter = m_detManager->getDetectorElementBegin();
41 iter != m_detManager->getDetectorElementEnd(); ++iter) {
42 const InDetDD::SiDetectorElement* element = *iter;
43
44 if (!element) {
45 ATH_MSG_ERROR("Problems with pointer to Detector Element !!!");
46 return StatusCode::FAILURE;
47 }
48
49 // Get the element indices
50 const Identifier identifier = element->identify();
51 const int pixelPhiModule = m_pixIdHelper->phi_module(identifier);
52 const int pixelBarrelEndcap = m_pixIdHelper->barrel_ec(identifier);
53 const int pixelLayerDisk = m_pixIdHelper->layer_disk(identifier);
54 const int pixelEtaModule = m_pixIdHelper->eta_module(identifier);
55
56 // Use one module to save the z location, using phi_module == 0 is an arbitrary choice
57 // also we can skip all the negative z modules since the geometry is symmetric
58 if (pixelBarrelEndcap<0 or pixelPhiModule > 0 or (pixelBarrelEndcap == 0 and pixelEtaModule<0))
59 continue;
60
61 if (dynamic_cast <const InDetDD::PixelModuleDesign*>(&(element->design())) == nullptr){
62 throw std::runtime_error("Pointer to PixelModuleDesign object is null");
63 }
64 const InDetDD::PixelModuleDesign *moduleDesign = static_cast<const InDetDD::PixelModuleDesign*>(&(element->design()));
65
66 // Get the number of chips per module
67 int chips = moduleDesign->numberOfCircuits();
68
69 float module_z = element->center().z();
70 ATH_MSG_DEBUG("Modules BarrelEndcap LayerDisk Phi Eta z : " << pixelBarrelEndcap << " " << pixelLayerDisk << " " << pixelPhiModule << " " << pixelEtaModule << " " << module_z << " | nb chips : " << chips << " rows-cols: " << moduleDesign->rowsPerCircuit() << "-" << moduleDesign->columnsPerCircuit() << " thickness:" << moduleDesign->thickness());
71
72 element->isBarrel() ? barrel_module_z.at(pixelLayerDisk).push_back(module_z) : endcap_module_z.at(pixelLayerDisk).push_back(module_z);
73
74 }
75
76 // When booking the histograms, you pass as well the module position
77 // it is then stored in the tools and is used to bin the histograms accordingly
78 ATH_CHECK(ITkPixelDataRateMonTool::bookHistograms(barrel_module_z, endcap_module_z));
79
80 return StatusCode::SUCCESS;
81}
82
83
84void ITkPixelDataRateMonTool::fill(const uint32_t offlineID,
85 const std::vector<unsigned int>& encodedstream,
86 const ITkPixLayout<uint16_t>& hitMap) const {
87 // -----------Receives the encoded stream and distributes it to the differents histograms-----------
88
89 // Find the stream length as the number of bits in the stream
90 const float streamLength = encodedstream.size() * s_bitsPerPack;
91 // Find the data rate as the number of bits in the stream multiplied by the chip readout frequency to get it in b/s
92 const float data_rate = streamLength * s_chipReadoutFrequency;
93
94 // -----------Stream length distribution in bits for the whole detector and all the chips-----------
95 m_encoded_streamLength->Fill(streamLength);
96
97 // Finds module properties
98 const Identifier waferID = Identifier(offlineID);
99 const int pixelBarrelEndcap = m_pixIdHelper->barrel_ec(waferID);
100 const int pixelLayerDisk = m_pixIdHelper->layer_disk(waferID);
101 const int pixelEtaModule = m_pixIdHelper->eta_module(waferID);
102
103 const Region region = (pixelBarrelEndcap==0) ? REGION_BARREL : REGION_ENDCAP;
104 const Side side = (pixelEtaModule < 0 || pixelBarrelEndcap < 0) ? SIDE_NEGATIVE : SIDE_POSITIVE;
105 const float z = std::abs(m_detManager->getDetectorElement(waferID)->center().z());
106
107 // -----------Stream length distribution in bits-----------
108 m_p_streamLength[pixelLayerDisk][region][side]->Fill(z, streamLength);
109 m_h2_streamLength[pixelLayerDisk][region][side]->Fill(z, streamLength);
110
111 // -----------Data rate distribution in bits per second-----------
112 m_p_dataRate[pixelLayerDisk][region][side]->Fill(z, data_rate);
113 m_h2_dataRate[pixelLayerDisk][region][side]->Fill(z, data_rate);
114
115 // -----------Hits per chip-----------
116 m_p_hits[pixelLayerDisk][region][side]->Fill(z, hitMap.nHits());
117 m_h2_hits[pixelLayerDisk][region][side]->Fill(z, hitMap.nHits());
118
119 if (m_doExpertPlots)
120 fillExpertPlots(offlineID, hitMap);
121}
122
123
124void ITkPixelDataRateMonTool::fillExpertPlots(const uint32_t offlineID, const ITkPixLayout<uint16_t>& hitMap) const {
125
126 // -----------Receives the hits and distributes it to the differents histograms-----------
127
128 // Finds module properties
129 const Identifier waferID = Identifier(offlineID);
130 const int pixelBarrelEndcap = m_pixIdHelper->barrel_ec(waferID);
131 const int pixelLayerDisk = m_pixIdHelper->layer_disk(waferID);
132
133 const Region region = (pixelBarrelEndcap==0) ? REGION_BARREL : REGION_ENDCAP;
134
135 // ---Chip hit map---
136
137 for (uint16_t col = 0; col < s_col_chip-1; col++){
138 for (uint16_t row = 0; row < s_row_chip-1; row++){
139
140 if (hitMap(col, row) > 0){
141 m_h2_chip_hitmap[pixelLayerDisk][region]->Fill(row, col, 1);
142 m_h2_chip_totmap[pixelLayerDisk][region]->Fill(row, col, hitMap(col, row));
143 }
144 }
145 }
146
147}
148
149
150StatusCode ITkPixelDataRateMonTool::bookHistograms(const std::vector<std::vector<float >>& barrel_z,
151 const std::vector<std::vector<float >>& endcap_z) {
152
153 // -----------Stream length distribution in bits for the whole detector and all the chips-----------
154 m_encoded_streamLength = new TH1F("m_encoded_streamLength", "Encoded Stream Length in bits", 2000, 0, 2000);
155 if ((m_thistSvc->regHist(m_path + m_encoded_streamLength->GetName(), m_encoded_streamLength)).isFailure())
156 return StatusCode::FAILURE;
157
158 ATH_MSG_DEBUG("Histogram " << m_encoded_streamLength->GetName() << " successfully registered.");
159
160 // -----------Stream length distribution in bits for different regions and layers-----------
161
162 std::array<std::vector<std::vector<double>>, N_REGIONS> bins;
163 for (auto& r : bins) r.resize(N_LAYERS);
164
165 // New identifier scheme
166 for (unsigned int layer = 0; layer<N_LAYERS ; layer++) {
167 if (not barrel_z[layer].empty()) {
168 for (unsigned int z_bin = 0; z_bin<(barrel_z[layer].size()-1); z_bin++) {
169 // evaluate middle point between consecutive modules
170 float interModulePoint = 0.5 * ( barrel_z[layer].at(z_bin) + barrel_z[layer].at(z_bin+1) );
171 if (z_bin==0)
172 bins[REGION_BARREL][layer].push_back(0.);
173 bins[REGION_BARREL][layer].push_back( interModulePoint );
174 }
175 //Creates the end of region covered by the module
176 double last_value = 2.*barrel_z[layer].back() - barrel_z[layer].at( barrel_z[layer].size() - 2 );
177 bins[REGION_BARREL][layer].push_back(last_value);
178 }
179
180 if (not endcap_z[layer].empty()) {
181 for (unsigned int z_bin = 0; z_bin<(endcap_z[layer].size()-1); z_bin++) {
182 // evaluate middle point between consecutive modules
183 float interModulePoint = 0.5 * ( endcap_z[layer].at(z_bin) + endcap_z[layer].at(z_bin+1) );
184 if (z_bin==0) {
185 float initialValue = 2.*endcap_z[layer].at(z_bin)-interModulePoint;
186 bins[REGION_ENDCAP][layer].push_back((initialValue));
187 }
188 bins[REGION_ENDCAP][layer].push_back( interModulePoint );
189 }
190 //Creates the end of region covered by the module
191 double last_value = 2.*endcap_z[layer].back() - endcap_z[layer].at( endcap_z[layer].size() - 2);
192 bins[REGION_ENDCAP][layer].push_back(last_value);
193 }
194 }
195
196 for (unsigned int region=0; region<N_REGIONS; region++) {
197 for (unsigned int layer=0; layer<N_LAYERS; layer++) {
198
199
200 if (bins[region][layer].empty())
201 continue;
202
203 if (m_doExpertPlots) {
204 m_h2_chip_hitmap[layer][region] = new TH2F(("m_h2_chip_hitmap_" + m_regionLabels[region] + "_" + std::to_string(layer)).c_str(),
205 (m_regionLabels[region] + " - Layer " + std::to_string(layer) + " Chip hit map; x [px]; y [px]; #epsilon").c_str(),
206 s_row_chip, -0.5, s_row_chip-0.5, s_col_chip, -0.5, s_col_chip-0.5);
207 if ((m_thistSvc->regHist(m_path + m_h2_chip_hitmap[layer][region]->GetName(), m_h2_chip_hitmap[layer][region])).isFailure())
208 return StatusCode::FAILURE;
209 ATH_MSG_DEBUG("Histogram " << m_h2_chip_hitmap[layer][region]->GetName() << " successfully registered.");
210
211 m_h2_chip_totmap[layer][region] = new TH2F(("m_h2_chip_totmap_" + m_regionLabels[region] + "_" + std::to_string(layer)).c_str(),
212 (m_regionLabels[region] + " - Layer " + std::to_string(layer) + " Chip ToT map; x [px]; y [px]; #epsilon").c_str(),
213 s_row_chip, -0.5, s_row_chip-0.5, s_col_chip, -0.5, s_col_chip-0.5);
214 if ((m_thistSvc->regHist(m_path + m_h2_chip_totmap[layer][region]->GetName(), m_h2_chip_totmap[layer][region])).isFailure())
215 return StatusCode::FAILURE;
216 ATH_MSG_DEBUG("Histogram " << m_h2_chip_totmap[layer][region]->GetName() << " successfully registered.");
217 }
218
219 for (int side=0; side<N_SIDES; side++) {
220 // Create names and title of histograms for full z coverage
221 const std::string name_base = m_regionLabels[region] + "_" + std::to_string(layer) + "_" + m_sideLabels[side];
222 const std::string title_base = m_regionLabels[region] + " - Layer " + std::to_string(layer) + " - Side " + m_sideLabels[side];
223
224 // -----------Stream length distribution in bits for different regions and layers-----------
225 m_p_streamLength[layer][region][side] = new TProfile(("m_p_streamLength_" + name_base).c_str(),
226 (title_base + " Stream Length; z[mm]; <stream length> [bits]").c_str(),
227 int(bins[region][layer].size()-1), &bins[region][layer][0]);
228 if ((m_thistSvc->regHist(m_path + m_p_streamLength[layer][region][side]->GetName(), m_p_streamLength[layer][region][side])).isFailure())
229 return StatusCode::FAILURE;
230 ATH_MSG_DEBUG("Histogram " << m_p_streamLength[layer][region][side]->GetName() << " successfully registered.");
231
232 m_h2_streamLength[layer][region][side] = new TH2F(("m_h2_streamLength_" + name_base).c_str(),
233 (title_base + " Stream Length; z[mm]; <stream length> [bits]").c_str(),
234 int(bins[region][layer].size()-1), &bins[region][layer][0],
235 1000, 0., 10000.);
236 if ((m_thistSvc->regHist(m_path + m_h2_streamLength[layer][region][side]->GetName(), m_h2_streamLength[layer][region][side])).isFailure())
237 return StatusCode::FAILURE;
238 ATH_MSG_DEBUG("Histogram " << m_h2_streamLength[layer][region][side]->GetName() << " successfully registered.");
239
240
241 // -----------Data rate in b/s for different regions and layers-----------
242
243 m_p_dataRate[layer][region][side] = new TProfile(("m_p_dataRate_" + name_base).c_str(),
244 (title_base + " Data rate per chip; z[mm]; <data rate per chip> [b/s]").c_str(),
245 int(bins[region][layer].size()-1), &bins[region][layer][0]);
246 if ((m_thistSvc->regHist(m_path + m_p_dataRate[layer][region][side]->GetName(), m_p_dataRate[layer][region][side])).isFailure())
247 return StatusCode::FAILURE;
248 ATH_MSG_DEBUG("Histogram " << m_p_dataRate[layer][region][side]->GetName() << " successfully registered.");
249
250 m_h2_dataRate[layer][region][side] = new TH2F(("m_h2_dataRate_" + name_base).c_str(),
251 (title_base + " Data rate per chip; z[mm]; <data rate per chip> [b/s]").c_str(),
252 int(bins[region][layer].size()-1), &bins[region][layer][0],
253 1000, 0., 10000.);
254 if ((m_thistSvc->regHist(m_path + m_h2_dataRate[layer][region][side]->GetName(), m_h2_dataRate[layer][region][side])).isFailure())
255 return StatusCode::FAILURE;
256 ATH_MSG_DEBUG("Histogram " << m_h2_dataRate[layer][region][side]->GetName() << " successfully registered.");
257
258 // -----------Hits per chip for different regions and layers-----------
259 m_p_hits[layer][region][side] = new TProfile(("m_p_hits_" + name_base).c_str(),
260 (title_base + " Hits per chip; z[mm]; <hits/chip>").c_str(),
261 int(bins[region][layer].size()-1), &bins[region][layer][0]);
262 if ((m_thistSvc->regHist(m_path + m_p_hits[layer][region][side]->GetName(), m_p_hits[layer][region][side])).isFailure())
263 return StatusCode::FAILURE;
264 ATH_MSG_DEBUG("Histogram " << m_p_hits[layer][region][side]->GetName() << " successfully registered.");
265
266 m_h2_hits[layer][region][side] = new TH2F(("m_h2_hits_" + name_base).c_str(),
267 (title_base + " Hits per chip; z[mm]; <hits/chip>").c_str(),
268 int(bins[region][layer].size()-1), &bins[region][layer][0],
269 1000, 0., 10000.);
270 if ((m_thistSvc->regHist(m_path + m_h2_hits[layer][region][side]->GetName(), m_h2_hits[layer][region][side])).isFailure())
271 return StatusCode::FAILURE;
272 ATH_MSG_DEBUG("Histogram " << m_h2_hits[layer][region][side]->GetName() << " successfully registered.");
273 }
274 }
275 }
276
277 return StatusCode::SUCCESS;
278
279}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_DEBUG(x)
static const std::vector< std::string > bins
#define z
static const Attributes_t empty
AthAlgTool(const std::string &type, const std::string &name, const IInterface *parent)
Constructor with parameters:
const ServiceHandle< StoreGateSvc > & detStore() const
DataModel_detail::const_iterator< DataVector > const_iterator
Definition DataVector.h:838
int nHits() const
std::map< int, std::string > m_regionLabels
const InDetDD::PixelDetectorManager * m_detManager
virtual StatusCode initialize() override
ServiceHandle< InDetDD::IPixelReadoutManager > m_pixelReadout
std::map< int, std::string > m_sideLabels
Gaudi::Property< bool > m_doExpertPlots
static const int s_chipReadoutFrequency
void fill(const uint32_t offlineID, const std::vector< unsigned int > &encodedstream, const ITkPixLayout< uint16_t > &hitMap) const
void fillExpertPlots(const uint32_t offlineID, const ITkPixLayout< uint16_t > &hitMap) const
Gaudi::Property< std::string > m_path
ITkPixelDataRateMonTool(const std::string &type, const std::string &name, const IInterface *parent)
StatusCode bookHistograms(const std::vector< std::vector< float > > &barrel_z, const std::vector< std::vector< float > > &endcap_z)
ServiceHandle< ITHistSvc > m_thistSvc
double thickness() const
Method which returns thickness of the silicon wafer.
Class used to describe the design of a module (diode segmentation and readout scheme)
int rowsPerCircuit() const
Number of cell rows per circuit:
int numberOfCircuits() const
Total number of circuits:
int columnsPerCircuit() const
Number of cell columns per circuit:
Class to hold geometrical description of a silicon detector element.
virtual const SiDetectorDesign & design() const override final
access to the local description (inline):
virtual const Amg::Vector3D & center() const override final
Center in global coordinates.
virtual Identifier identify() const override final
identifier of this detector element (inline)
int r
Definition globals.cxx:22