ATLAS Offline Software
Loading...
Searching...
No Matches
ITkStripDataRateMonTool.cxx
Go to the documentation of this file.
1
2/*
3Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
4*/
5
6/*
7* Description: Athena tool wrapper around the ITkStrip encoder to study data rate as a function of chip's position in detector
8*/
9
11#include <stdexcept>
12
13ITkStripDataRateMonTool::ITkStripDataRateMonTool(const std::string& type, const std::string& name, const IInterface* parent)
14 : AthAlgTool(type, name, parent)
15{
16}
17
18
20
21 // ----------- Check services presence -----------
22
23 // Checks that the histograming service is up and running
24 ATH_CHECK(m_thistSvc.retrieve());
25
26 // Checks that the strip id help service is up and running
27 ATH_CHECK(detStore()->retrieve(m_stripIdHelper, "SCT_ID"));
28
29 // Checks that the strip manager service is up and running
30 ATH_CHECK(detStore()->retrieve(m_detManager, "ITkStrip"));
31
32 // ----------- Finds the different regions and layers to create histograms for them -----------
33 std::vector<std::vector<float>> barrel_module_z(10); // List of z coordinates for modules in barrel
34 std::vector<std::vector<float>> endcap_module_z(10); //List of z coordinates for modules in endcap
35
36 for (InDetDD::SiDetectorElementCollection::const_iterator iter = m_detManager->getDetectorElementBegin();
37 iter != m_detManager->getDetectorElementEnd(); ++iter) {
38 const InDetDD::SiDetectorElement* element = *iter;
39
40 if (!element) {
41 ATH_MSG_ERROR("Problems with pointer to Detector Element !!!");
42 return StatusCode::FAILURE;
43 }
44
45 // Get the element indices
46 const Identifier identifier = element->identify();
47 const IdentifierHash idHash = m_stripIdHelper->wafer_hash(identifier);
48 const int stripPhiModule = m_stripIdHelper->phi_module(identifier);
49 const int stripBarrelEndcap = m_stripIdHelper->barrel_ec(identifier);
50 const int stripLayerDisk = m_stripIdHelper->layer_disk(identifier);
51 const int stripEtaModule = m_stripIdHelper->eta_module(identifier);
52
53 float module_z = element->center().z();
54
55 // Use one module to save the z location, using phi_module == 0 is an arbitrary choice
56 // also we can skip all the negative z modules since the geometry is symmetric
57 if (stripBarrelEndcap<0 or stripPhiModule > 0 or (stripBarrelEndcap == 0 and stripEtaModule<0))
58 continue;
59
60
61 ATH_MSG_DEBUG("Modules BarrelEndcap LayerDisk Phi Eta z : " << stripBarrelEndcap << " " << stripLayerDisk << " " << stripPhiModule << " " << stripEtaModule << " " << module_z << " " << idHash);
62
63 element->isBarrel() ? barrel_module_z.at(stripLayerDisk).push_back(module_z) : endcap_module_z.at(stripLayerDisk).push_back(module_z);
64
65 }
66
67 // When booking the histograms, you pass as well the module position
68 // it is then stored in the tools and is used to bin the histograms accordingly
69 ATH_CHECK(ITkStripDataRateMonTool::bookHistograms(barrel_module_z, endcap_module_z));
70
71 return StatusCode::SUCCESS;
72}
73
74
75void ITkStripDataRateMonTool::fill(const uint32_t offlineID,
76 const std::vector<unsigned int>& encodedstream,
77 const std::vector<std::bitset<256>>& hitMap) const {
78 // -----------Receives the encoded stream and distributes it to the differents histograms-----------
79
80 // Find the stream length as the number of bits in the stream
81 const float streamLength = encodedstream.size() * s_bitsPerPack;
82 // Find the data rate as the number of bits in the stream multiplied by the chip readout frequency to get it in b/s
83 const float data_rate = streamLength * s_chipReadoutFrequency;
84
85 // -----------Stream length distribution in bits for the whole detector and all the chips-----------
86 m_encoded_streamLength->Fill(streamLength);
87
88 // Finds module properties
89 const Identifier waferID = m_stripIdHelper->wafer_id(offlineID);
90
91 const int stripBarrelEndcap = m_stripIdHelper->barrel_ec(waferID);
92
93 const int stripLayerDisk = m_stripIdHelper->layer_disk(waferID);
94
95 const int stripEtaModule = m_stripIdHelper->eta_module(waferID);
96
97 const Region region = (stripBarrelEndcap==0) ? REGION_BARREL : REGION_ENDCAP;
98
99 const Side side = (stripEtaModule < 0 || stripBarrelEndcap < 0) ? SIDE_NEGATIVE : SIDE_POSITIVE;
100
101 const IdentifierHash idHash = m_stripIdHelper->wafer_hash(waferID);
102 if(!idHash.is_valid()) ATH_MSG_ERROR("Invalid WaferID found");
103
104 const float z = std::abs(m_detManager->getDetectorElement(waferID)->center().z());
105
106 // -----------Stream length distribution in bits-----------
107 m_p_streamLength[stripLayerDisk][region][side]->Fill(z, streamLength);
108 m_h2_streamLength[stripLayerDisk][region][side]->Fill(z, streamLength);
109
110 // -----------Data rate distribution in bits per second-----------
111 m_p_dataRate[stripLayerDisk][region][side]->Fill(z, data_rate);
112 m_h2_dataRate[stripLayerDisk][region][side]->Fill(z, data_rate);
113
114 int nHits=0;
115
116 for (size_t i = 0; i < hitMap.size(); ++i) {
117 std::bitset<256> hits = hitMap[i];
118 nHits+=hits.count();
119 }
120
121 // -----------Hits per chip-----------
122 m_p_hits[stripLayerDisk][region][side]->Fill(z, nHits);
123 m_h2_hits[stripLayerDisk][region][side]->Fill(z, nHits);
124
125}
126
127StatusCode ITkStripDataRateMonTool::bookHistograms(const std::vector<std::vector<float >>& barrel_z,
128 const std::vector<std::vector<float >>& endcap_z) {
129
130 // -----------Stream length distribution in bits for the whole detector and all the chips-----------
131 m_encoded_streamLength = new TH1F("m_encoded_streamLength", "Encoded Stream Length in bits", 2000, 0., 2000.);
132 if ((m_thistSvc->regHist(m_path + m_encoded_streamLength->GetName(), m_encoded_streamLength)).isFailure())
133 return StatusCode::FAILURE;
134
135 ATH_MSG_DEBUG("Histogram " << m_encoded_streamLength->GetName() << " successfully registered.");
136
137 // -----------Stream length distribution in bits for different regions and layers-----------
138
139 std::array<std::vector<std::vector<double>>, N_REGIONS> bins;
140 for (auto& r : bins) r.resize(N_LAYERS);
141
142 // New identifier scheme
143 for (unsigned int layer = 0; layer<N_LAYERS ; layer++) {
144 if (not barrel_z[layer].empty()) {
145 for (unsigned int z_bin = 0; z_bin<(barrel_z[layer].size()-1); z_bin++) {
146 // evaluate middle point between consecutive modules
147 float interModulePoint = 0.5 * ( barrel_z[layer].at(z_bin) + barrel_z[layer].at(z_bin+1) );
148 if (z_bin==0)
149 bins[REGION_BARREL][layer].push_back(0.);
150 bins[REGION_BARREL][layer].push_back( interModulePoint );
151 }
152 //Creates the end of region covered by the module
153 double last_value = 2.*barrel_z[layer].back() - barrel_z[layer].at( barrel_z[layer].size() - 2 );
154 if(last_value!=barrel_z[layer].back()) bins[REGION_BARREL][layer].push_back(last_value);
155 }
156
157 if (not endcap_z[layer].empty()) {
158 for (unsigned int z_bin = 0; z_bin<(endcap_z[layer].size()-1); z_bin++) {
159 // evaluate middle point between consecutive module
160 float interModulePoint = 0.5 * ( endcap_z[layer].at(z_bin) + endcap_z[layer].at(z_bin+1) );
161 if (z_bin==0) {
162 float initialValue = 2.*endcap_z[layer].at(z_bin)-interModulePoint;
163 bins[REGION_ENDCAP][layer].push_back((initialValue));
164 }
165 if(interModulePoint!=bins[REGION_ENDCAP][layer].back())
166 bins[REGION_ENDCAP][layer].push_back( interModulePoint );
167 }
168 //Creates the end of region covered by the module
169 double last_value = 2.*endcap_z[layer].back() - endcap_z[layer].at( endcap_z[layer].size() - 2);
170 if(last_value!=endcap_z[layer].back()) bins[REGION_ENDCAP][layer].push_back(last_value);
171 }
172 }
173
174 for (unsigned int region=0; region<N_REGIONS; region++) {
175 for (unsigned int layer=0; layer<N_LAYERS; layer++) {
176
177
178 if (bins[region][layer].empty())
179 continue;
180
181 for (int side=0; side<N_SIDES; side++) {
182 // Create names and title of histograms for full z coverage
183 const std::string name_base = m_regionLabels[region] + "_" + std::to_string(layer) + "_" + m_sideLabels[side];
184 const std::string title_base = m_regionLabels[region] + " - Layer " + std::to_string(layer) + " - Side " + m_sideLabels[side];
185
186 // -----------Stream length distribution in bits for different regions and layers-----------
187 m_p_streamLength[layer][region][side] = new TProfile(("m_p_streamLength_" + name_base).c_str(),
188 (title_base + " Stream Length; z[mm]; <stream length> [bits]").c_str(),
189 int(bins[region][layer].size()-1), &bins[region][layer][0]);
190 if ((m_thistSvc->regHist(m_path + m_p_streamLength[layer][region][side]->GetName(), m_p_streamLength[layer][region][side])).isFailure())
191 return StatusCode::FAILURE;
192 ATH_MSG_DEBUG("Histogram " << m_p_streamLength[layer][region][side]->GetName() << " successfully registered.");
193
194 m_h2_streamLength[layer][region][side] = new TH2F(("m_h2_streamLength_" + name_base).c_str(),
195 (title_base + " Stream Length; z[mm]; <stream length> [bits]").c_str(),
196 int(bins[region][layer].size()-1), &bins[region][layer][0],
197 1000, 0., 10000.);
198 if ((m_thistSvc->regHist(m_path + m_h2_streamLength[layer][region][side]->GetName(), m_h2_streamLength[layer][region][side])).isFailure())
199 return StatusCode::FAILURE;
200 ATH_MSG_DEBUG("Histogram " << m_h2_streamLength[layer][region][side]->GetName() << " successfully registered.");
201
202
203 // -----------Data rate in b/s for different regions and layers-----------
204
205 m_p_dataRate[layer][region][side] = new TProfile(("m_p_dataRate_" + name_base).c_str(),
206 (title_base + " Data rate per chip; z[mm]; <data rate per chip> [b/s]").c_str(),
207 int(bins[region][layer].size()-1), &bins[region][layer][0]);
208 if ((m_thistSvc->regHist(m_path + m_p_dataRate[layer][region][side]->GetName(), m_p_dataRate[layer][region][side])).isFailure())
209 return StatusCode::FAILURE;
210 ATH_MSG_DEBUG("Histogram " << m_p_dataRate[layer][region][side]->GetName() << " successfully registered.");
211
212 m_h2_dataRate[layer][region][side] = new TH2F(("m_h2_dataRate_" + name_base).c_str(),
213 (title_base + " Data rate per chip; z[mm]; <data rate per chip> [b/s]").c_str(),
214 int(bins[region][layer].size()-1), &bins[region][layer][0],
215 1000, 0., 10000.);
216 if ((m_thistSvc->regHist(m_path + m_h2_dataRate[layer][region][side]->GetName(), m_h2_dataRate[layer][region][side])).isFailure())
217 return StatusCode::FAILURE;
218 ATH_MSG_DEBUG("Histogram " << m_h2_dataRate[layer][region][side]->GetName() << " successfully registered.");
219
220 // -----------Hits per chip for different regions and layers-----------
221 m_p_hits[layer][region][side] = new TProfile(("m_p_hits_" + name_base).c_str(),
222 (title_base + " Hits per chip; z[mm]; <hits/chip>").c_str(),
223 int(bins[region][layer].size()-1), &bins[region][layer][0]);
224 if ((m_thistSvc->regHist(m_path + m_p_hits[layer][region][side]->GetName(), m_p_hits[layer][region][side])).isFailure())
225 return StatusCode::FAILURE;
226 ATH_MSG_DEBUG("Histogram " << m_p_hits[layer][region][side]->GetName() << " successfully registered.");
227
228 m_h2_hits[layer][region][side] = new TH2F(("m_h2_hits_" + name_base).c_str(),
229 (title_base + " Hits per chip; z[mm]; <hits/chip>").c_str(),
230 int(bins[region][layer].size()-1), &bins[region][layer][0],
231 1000, 0., 10000.);
232 if ((m_thistSvc->regHist(m_path + m_h2_hits[layer][region][side]->GetName(), m_h2_hits[layer][region][side])).isFailure())
233 return StatusCode::FAILURE;
234 ATH_MSG_DEBUG("Histogram " << m_h2_hits[layer][region][side]->GetName() << " successfully registered.");
235 }
236 }
237 }
238
239 return StatusCode::SUCCESS;
240
241}
#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
static const uint32_t nHits
size_t size() const
Number of registered mappings.
#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
const InDetDD::SCT_DetectorManager * m_detManager
void fill(const uint32_t offlineID, const std::vector< unsigned int > &encodedstream, const std::vector< std::bitset< 256 > > &hitMap) const
ServiceHandle< ITHistSvc > m_thistSvc
std::map< int, std::string > m_regionLabels
Gaudi::Property< std::string > m_path
std::map< int, std::string > m_sideLabels
StatusCode bookHistograms(const std::vector< std::vector< float > > &barrel_z, const std::vector< std::vector< float > > &endcap_z)
virtual StatusCode initialize() override
ITkStripDataRateMonTool(const std::string &type, const std::string &name, const IInterface *parent)
static const int s_chipReadoutFrequency
This is a "hash" representation of an Identifier.
constexpr bool is_valid() const
Class to hold geometrical description of a silicon detector element.
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