ATLAS Offline Software
Loading...
Searching...
No Matches
TileTMDBMonitorAlgorithm.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
3*/
4
7
8
11
13
14 ATH_MSG_DEBUG("in initialize()");
15
16 // initialize superclass
18
19 ATH_CHECK( detStore()->retrieve(m_tileHWID) );
20
21 ATH_CHECK( m_cablingSvc.retrieve() );
22 m_cabling = m_cablingSvc->cablingService();
23
24 ATH_CHECK( m_rawChannelContainerKey.initialize() );
27 ATH_CHECK( m_tileCondToolTMDB.retrieve() );
28
29 if (m_pulseEnergyRange.size() != 2) {
30 ATH_MSG_FATAL( "Size of PulseEnergyRange should be 2 (from,to), but is " << m_pulseEnergyRange.size() );
31 return StatusCode::FAILURE;
32 }
33
34 if (m_energyRange.size() != 2) {
35 ATH_MSG_FATAL( "Size of EnergyRange should be 2 (from,to), but is " << m_energyRange.size() );
36 return StatusCode::FAILURE;
37 }
38
39 using namespace Monitored;
40
41 m_peakGroups = buildToolMap<int>(m_tools, "TMDB_PeakPosition", Tile::MAX_ROS - 1);
43
44 std::vector<std::string> partitionName = {"LBA", "LBC", "EBA", "EBC"}; // ROS - 1 to partition name map
45 int nChannels[] = {8, 8, 4, 4};
46 for (unsigned int partition = 0; partition < Tile::MAX_ROS - 1; ++partition) {
47
48 m_pulseGroups.push_back(buildToolMap<std::vector<int>>(m_tools,
49 "TMDB_MeanPulse_" + partitionName[partition],
50 Tile::MAX_DRAWER, nChannels[partition]));
51
52 m_chanEnergyGroups.push_back(buildToolMap<std::vector<int>>(m_tools,
53 "TMDB_Energy_" + partitionName[partition],
54 Tile::MAX_DRAWER, nChannels[partition]));
55
56 m_calibErrorGroups.push_back(buildToolMap<std::vector<int>>(m_tools,
57 "TMDB_CalibrationError_" + partitionName[partition],
58 Tile::MAX_DRAWER, nChannels[partition]));
59
60 m_chanChannelNoiseGroups.push_back(buildToolMap<std::vector<std::vector<int>>>(m_tools,
61 "TMDB_ChanNoise_" + partitionName[partition],
62 Tile::MAX_DRAWER, nChannels[partition], nChannels[partition]));
63
64 m_chanPeakPosGroups.push_back(buildToolMap<std::vector<int>>(m_tools,
65 "TMDB_Peak_" + partitionName[partition],
66 Tile::MAX_DRAWER, nChannels[partition]));
67
68 }
69
70 return StatusCode::SUCCESS;
71}
72
73
74void TileTMDBMonitorAlgorithm::fillNoiseHistograms(const TileDigitsCollection* muRcvDigitsCollection, const int drawer, const int partition) const {
75
76 for (unsigned int i = 0; i < muRcvDigitsCollection->size(); i++){
77 const std::vector<float> &samplesX = muRcvDigitsCollection->at(i)->samples();
78 float pedestalX = samplesX[0];
79 auto monPedestalX = Monitored::Scalar<float>("channX", pedestalX);
80 for (unsigned int j = 0; j < muRcvDigitsCollection->size(); j++){
81 const std::vector<float> &samplesY = muRcvDigitsCollection->at(j)->samples();
82 float pedestalY = samplesY[0];
83 auto monPedestalY = Monitored::Scalar<float>("channY", pedestalY);
84
85 fill(m_tools[m_chanChannelNoiseGroups[partition][drawer][i][j]], monPedestalX, monPedestalY);
86 }
87 }
88}
89
90StatusCode TileTMDBMonitorAlgorithm::fillHistograms( const EventContext& ctx ) const {
91
92 // using Tile = TileCalibUtils;
93
94 // In case you want to measure the execution time
95 auto timer = Monitored::Timer("TIME_execute");
96
97 float referenceEnergies[Tile::MAX_ROS - 1][Tile::MAX_DRAWER][8] = {{{0}}};
98
100 ATH_CHECK( rawChannelContainer.isValid() );
101
102 for (const TileRawChannelCollection* rawChannelCollection : *rawChannelContainer) {
103 if (rawChannelCollection->empty() ) continue;
104
105 int fragId = rawChannelCollection->identify();
106 int drawer = fragId & 0x3F;
107 int ros = fragId >> 8;
108 int partition = ros - 1;
109
110 for (const TileRawChannel* rawChannel : *rawChannelCollection) {
111
112 HWIdentifier adc_id = rawChannel->adc_HWID();
113 int channel = m_tileHWID->channel(adc_id);
114 float energy = rawChannel->amplitude();
115
116 std::map<int, int>::const_iterator it = m_cellTMDB[partition].get().find(channel);
117 if (it != m_cellTMDB[partition].get().end()) {
118 int channelTMDB = (*it).second;
119 if ((ros < 3) && (drawer % 2 == 0)) {
120 ++channelTMDB; // In LB TMDB channels in even drawers are shifted by one
121 }
122 referenceEnergies[partition][drawer][channelTMDB] = energy;
123 }
124
125 }
126 }
127
128 std::vector<float> energies[Tile::MAX_ROS - 1];
129 std::vector<int> energyDrawers[Tile::MAX_ROS - 1];
130 std::vector<int> energyChannels[Tile::MAX_ROS - 1];
131
133 ATH_CHECK( muRcvRawChannelContainer.isValid() );
134
135 // Collecting energy information
136 for (const TileRawChannelCollection* muRcvRawChannelCollection : *muRcvRawChannelContainer) {
137 if (muRcvRawChannelCollection->empty() ) continue;
138
139 int fragId = muRcvRawChannelCollection->identify();
140 int drawer = fragId & 0x3F;
141 int ros = fragId >> 8;
142 unsigned int drawerIdx = TileCalibUtils::getDrawerIdx(ros, drawer);
143 int partition = ros - 1;
144
145 for (const TileRawChannel* muRcvRawChannel : *muRcvRawChannelCollection) {
146 HWIdentifier adc_id = muRcvRawChannel->adc_HWID();
147 int channel = m_tileHWID->channel(adc_id);
148 float amplitude = muRcvRawChannel->amplitude();
149 float energy = m_tileCondToolTMDB->channelCalib(drawerIdx, channel, amplitude);
150
151 energyDrawers[partition].push_back(drawer);
152 energyChannels[partition].push_back(channel);
153 energies[partition].push_back(energy);
154
155 auto monEnergy = Monitored::Scalar<float>("energy", energy);
156 fill(m_tools[m_chanEnergyGroups[partition][drawer][channel]], monEnergy);
157
158 auto monCalibError = Monitored::Scalar<float>("error", referenceEnergies[partition][drawer][channel] - energy);
159 fill(m_tools[m_calibErrorGroups[partition][drawer][channel]], monCalibError);
160
162 << " TMDB channel " << channel
163 << ": energy [MeV] = " << energy);
164 }
165 }
166
167 //Collecting channel noise information
168
169
170 std::vector<float> peakPositions[Tile::MAX_ROS - 1];
171 std::vector<int> peakPositionDrawers[Tile::MAX_ROS - 1];
172 std::vector<int> peakPositionChannels[Tile::MAX_ROS - 1];
173
175 ATH_CHECK( muRcvDigitsContainer.isValid() );
176
177 // Collecting peak and samples information
178 for (const TileDigitsCollection* muRcvDigitsCollection : *muRcvDigitsContainer) {
179 if (muRcvDigitsCollection->empty() ) continue;
180
181 int fragId = muRcvDigitsCollection->identify();
182 int drawer = fragId & 0x3F;
183 int ros = fragId >> 8;
184 int partition = ros - 1;
185
186 fillNoiseHistograms(muRcvDigitsCollection, drawer, partition);
187 for (const TileDigits* muRcvDigits : *muRcvDigitsCollection) {
188 HWIdentifier adc_id = muRcvDigits->adc_HWID();
189 int channel = m_tileHWID->channel(adc_id);
190
191 float energy = referenceEnergies[partition][drawer][channel];
192 if ((energy > m_pulseEnergyRange[0]) && (energy < m_pulseEnergyRange[1])) {
193 peakPositionDrawers[partition].push_back(drawer);
194 peakPositionChannels[partition].push_back(channel);
195
196 std::vector<float> samples = muRcvDigits->samples();
197 unsigned int nSamples = samples.size();
198 std::vector<int> sampleNumbers(nSamples, 0);
199 std::iota(sampleNumbers.begin(), sampleNumbers.end(), 0);
200
201 auto monSample = Monitored::Collection("sample", samples);
202 auto monSampleNumber = Monitored::Collection("sampleNumber", sampleNumbers);
203
204 fill(m_tools[m_pulseGroups[partition][drawer][channel]], monSampleNumber, monSample);
205
206 float peakPosition = std::distance(samples.begin(), std::max_element(samples.begin(), samples.end()));
207 peakPositions[partition].push_back(peakPosition);
208
209 auto monPeakPos = Monitored::Scalar<float>("peak", peakPosition);
210 fill(m_tools[m_chanPeakPosGroups[partition][drawer][channel]], monPeakPos);
211
213 << " TMDB channel " << channel
214 << ": peak position = " << peakPosition);
215 }
216 }
217 }
218
219
220
221 for (unsigned int partition = 0; partition < Tile::MAX_ROS - 1; ++partition) {
222 if (!energies[partition].empty()) {
223 auto monModule = Monitored::Collection("module", energyDrawers[partition]);
224 auto monChannel = Monitored::Collection("channel", energyChannels[partition]);
225 auto monEnergy = Monitored::Collection("energy", energies[partition]);
226 fill(m_tools[m_energyGroups[partition]], monModule, monChannel, monEnergy);
227 }
228
229 if (!peakPositions[partition].empty()) {
230 auto monModule = Monitored::Collection("module", peakPositionDrawers[partition]);
231 auto monChannel = Monitored::Collection("channel", peakPositionChannels[partition]);
232 auto monPeakPosition = Monitored::Collection("peakPosition", peakPositions[partition]);
233 fill(m_tools[m_peakGroups[partition]], monModule, monChannel, monPeakPosition);
234 }
235 }
236
237
238 fill("TileTMDBMonExecuteTime", timer);
239
240 return StatusCode::SUCCESS;
241}
242
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_FATAL(x)
#define ATH_MSG_DEBUG(x)
Handle class for reading from StoreGate.
static const Attributes_t empty
const ServiceHandle< StoreGateSvc > & detStore() const
virtual StatusCode initialize() override
initialize
ToolHandleArray< GenericMonitoringTool > m_tools
Array of Generic Monitoring Tools.
const T * at(size_type n) const
Access an element, as an rvalue.
size_type size() const noexcept
Returns the number of elements in the collection.
Declare a monitored scalar variable.
A monitored timer.
virtual bool isValid() override final
Can the handle be successfully dereferenced?
static const unsigned int MAX_ROS
Number of ROSs.
static std::string getDrawerString(unsigned int ros, unsigned int drawer)
Return the drawer name, e.g.
static const unsigned int MAX_DRAWER
Number of drawers in ROS 1-4.
static unsigned int getDrawerIdx(unsigned int ros, unsigned int drawer)
Returns a drawer hash.
SG::ReadHandleKey< TileRawChannelContainer > m_muRcvRawChannelContainerKey
std::vector< std::vector< std::vector< std::vector< int > > > > m_chanChannelNoiseGroups
std::vector< std::vector< std::vector< int > > > m_calibErrorGroups
ToolHandle< ITileCondToolTMDB > m_tileCondToolTMDB
Gaudi::Property< std::vector< float > > m_pulseEnergyRange
std::vector< std::vector< std::vector< int > > > m_chanPeakPosGroups
SG::ReadHandleKey< TileRawChannelContainer > m_rawChannelContainerKey
std::vector< std::vector< std::vector< int > > > m_chanEnergyGroups
std::vector< std::vector< std::vector< int > > > m_pulseGroups
virtual StatusCode fillHistograms(const EventContext &ctx) const override
adds event to the monitoring histograms
const TileCablingService * m_cabling
SG::ReadHandleKey< TileDigitsContainer > m_muRcvDigitsContainerKey
void fillNoiseHistograms(const TileDigitsCollection *muRcvDigitsCollection, const int drawer, const int partition) const
std::reference_wrapper< const std::map< int, int > > m_cellTMDB[Tile::MAX_ROS - 1]
ServiceHandle< TileCablingSvc > m_cablingSvc
Name of Tile cabling service.
virtual StatusCode initialize() override
initialize
Gaudi::Property< std::vector< float > > m_energyRange
T * get(TKey *tobj)
get a TObject* from a TKey* (why can't a TObject be a TKey?)
Definition hcg.cxx:130
Generic monitoring tool for athena components.
std::vector< V > buildToolMap(const ToolHandleArray< GenericMonitoringTool > &tools, const std::string &baseName, int nHist)
Builds an array of indices (base case)
ValuesCollection< T > Collection(std::string name, const T &collection)
Declare a monitored (double-convertible) collection.
void fill(H5::Group &out_file, size_t iterations)