ATLAS Offline Software
Loading...
Searching...
No Matches
EMECHVManager.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
8#include <cmath>
9#include <iostream>
10
11#include "EMECHVPayload.h"
12
15#include "GaudiKernel/ISvcLocator.h"
16#include "GaudiKernel/IToolSvc.h"
17#include "GaudiKernel/Bootstrap.h"
18#include "GaudiKernel/ServiceHandle.h"
19
22
26
27#ifndef SIMULATIONBASE
28#ifndef GENERATIONBASE
30#endif
31#endif
32
34
35#include <atomic>
36
37
38namespace {
39
40
41struct SimIdFunc
42{
43 SimIdFunc();
44 std::vector<HWIdentifier> operator()(HWIdentifier id) const
45 {
46 return m_cablingTool->getLArElectrodeIDvec (id);
47 }
48 LArHVCablingSimTool* m_cablingTool;
49};
50
51
52SimIdFunc::SimIdFunc()
53{
54 ToolHandle<LArHVCablingSimTool> tool ("LArHVCablingSimTool");
55 if (!tool.retrieve().isSuccess()) {
56 std::abort();
57 }
58 m_cablingTool = tool.get();
59}
60
61
62} // Anonymous namespace
63
64
66public:
67 Clockwork(const EMECHVManager* manager, IOType wheel,
68 std::unique_ptr<EMECHVDescriptor> the_descriptor)
69 : descriptor(std::move(the_descriptor)),
70 iWheel(wheel)
71 {
72 for(int iSide=0; iSide<2; ++iSide) {
73 for(int iEta=0; iEta<8; ++iEta) {
74 for(int iPhi=0; iPhi<8; ++iPhi) {
75 for(int iSector=0; iSector<8; ++iSector) {
76 moduleArray[iSide][iEta][iPhi][iSector] = std::make_unique<EMECHVModule>(manager,wheel,iSide,iEta,iPhi,iSector);
77 }
78 }
79 }
80 }
81
82 ServiceHandle<StoreGateSvc> detStore ("DetectorStore", "HECHVManager");
83 if (StatusCode::SUCCESS!=detStore->retrieve(elecId, "LArElectrodeID")) {
84 throw std::runtime_error("EMECHVManager failed to retrieve LArElectrodeID");
85 }
86
87 if (StatusCode::SUCCESS!=detStore->retrieve(hvId,"LArHVLineID")) {
88 throw std::runtime_error("EMECHVManager failed to retrieve LArHVLineID");
89 }
90 }
91 ~Clockwork() = default;
92 std::unique_ptr<EMECHVDescriptor> descriptor;
94 std::unique_ptr<const EMECHVModule> moduleArray[2][8][8][8]; // not dense
95 const LArElectrodeID* elecId = nullptr;
96 const LArHVLineID* hvId = nullptr;
97};
98
99
101{
102public:
103 std::vector<EMECHVPayload> m_payloadArray;
104};
105
106
108= default;
109
110
111EMECHVManager::EMECHVData::EMECHVData (std::unique_ptr<Payload> payload)
112 : m_payload (std::move (payload))
113{
114}
115
116
119 noexcept {
120 if (this != &other) {
121 m_payload = std::move (other.m_payload);
122 }
123 return *this;
124}
125
126
128= default;
129
130
131bool EMECHVManager::EMECHVData::hvOn (const EMECHVElectrode& electrode, const int& iGap) const
132{
133 return voltage (electrode, iGap) > INVALID;
134}
135
136
137double EMECHVManager::EMECHVData::voltage (const EMECHVElectrode& electrode, const int& iGap) const
138{
139 return m_payload->m_payloadArray[index(electrode)].voltage[iGap];
140}
141
142
143double EMECHVManager::EMECHVData::current (const EMECHVElectrode& electrode, const int& iGap) const
144{
145 return m_payload->m_payloadArray[index(electrode)].current[iGap];
146}
147
148
149int EMECHVManager::EMECHVData::hvLineNo (const EMECHVElectrode& electrode, const int& iGap) const
150{
151 return m_payload->m_payloadArray[index(electrode)].hvLineNo[iGap];
152}
153
154
156{
157 unsigned int electrodeIndex = electrode.getElectrodeIndex();
158 const EMECHVModule& module = electrode.getModule();
159 unsigned int etaIndex = module.getEtaIndex();
160 unsigned int phiIndex = module.getPhiIndex();
161 unsigned int sectorIndex = module.getSectorIndex();
162 unsigned int sideIndex = module.getSideIndex();
163
164 unsigned int index=0;
165 if (module.getWheelIndex()==EMECHVModule::OUTER) index= 5376*sideIndex+768*etaIndex+96*phiIndex+24*sectorIndex+electrodeIndex;
166 else if (module.getWheelIndex()==EMECHVModule::INNER) index= 512*sideIndex+256*etaIndex+32*phiIndex+4*sectorIndex+electrodeIndex;
167
168 return index;
169}
170
171
173{
174 std::unique_ptr<EMECHVDescriptor> descriptor;
175 if (wheel==EMECHVModule::OUTER) {
176 CellPartitioning etaBinning;
177 etaBinning.addValue(1.375);
178 etaBinning.addValue(1.50);
179 etaBinning.addValue(1.6);
180 etaBinning.addValue(1.8);
181 etaBinning.addValue(2.0);
182 etaBinning.addValue(2.1);
183 etaBinning.addValue(2.3);
184 etaBinning.addValue(2.5);
185 descriptor = std::make_unique<EMECHVDescriptor>(etaBinning,CellBinning(0.0, 2*M_PI, 8),CellBinning(0,M_PI/4.0,4));
186 }
187 else {
188 CellPartitioning etaBinning;
189 etaBinning.addValue(2.5);
190 etaBinning.addValue(2.8);
191 etaBinning.addValue(3.2);
192 descriptor = std::make_unique<EMECHVDescriptor>(etaBinning,CellBinning(0.0, 2*M_PI, 8),CellBinning(0,M_PI/4.0,8));
193 }
194 m_c = std::make_unique<Clockwork> (this, wheel, std::move(descriptor));
195}
196
198{
199 return *(m_c->descriptor);
200}
201
203{
204 return m_c->descriptor->getPhiBinning().getFirstDivisionNumber();
205}
206
207unsigned int EMECHVManager::endPhiIndex() const
208{
209 return m_c->descriptor->getPhiBinning().getFirstDivisionNumber() + m_c->descriptor->getPhiBinning().getNumDivisions();
210}
211
213{
214 return m_c->descriptor->getEtaBinning().getFirstDivisionNumber();
215}
216
217unsigned int EMECHVManager::endEtaIndex() const
218{
219 return m_c->descriptor->getEtaBinning().getFirstDivisionNumber() + m_c->descriptor->getEtaBinning().getNumDivisions();
220}
221
222const EMECHVModule& EMECHVManager::getHVModule(unsigned int iSide, unsigned int iEta, unsigned int iPhi, unsigned int iSector) const
223{
224 return *(m_c->moduleArray[iSide][iEta][iPhi][iSector]);
225}
226
228= default;
229
231{
232 return 0;
233}
234
236{
237 return 2;
238}
239
241{
242 return m_c->descriptor->getSectorBinning().getFirstDivisionNumber();
243}
244
246{
247 return m_c->descriptor->getSectorBinning().getFirstDivisionNumber() + m_c->descriptor->getSectorBinning().getNumDivisions();
248}
249
251{
252 return m_c->iWheel;
253}
254
257 const std::vector<const CondAttrListCollection*>& attrLists) const
258{
259 auto payload = std::make_unique<EMECHVData::Payload>();
260
261 if (m_c->iWheel==EMECHVModule::OUTER) {
262 payload->m_payloadArray.reserve(2*7*8*4*24);
263 for (unsigned int i=0;i<10752;i++) {
264 payload->m_payloadArray[i].voltage[0] = EMECHVData::INVALID;
265 payload->m_payloadArray[i].voltage[1] = EMECHVData::INVALID;
266 }
267 }
268 else if (m_c->iWheel==EMECHVModule::INNER) {
269 payload->m_payloadArray.reserve(2*2*8*8*4);
270 for (unsigned int i=0;i<1024;i++) {
271 payload->m_payloadArray[i].voltage[0] = EMECHVData::INVALID;
272 payload->m_payloadArray[i].voltage[1] = EMECHVData::INVALID;
273 }
274 }
275
276 for (const CondAttrListCollection* atrlistcol : attrLists) {
277
278 for (CondAttrListCollection::const_iterator citr=atrlistcol->begin(); citr!=atrlistcol->end();++citr) {
279 // Construct HWIdentifier
280 // 1. decode COOL Channel ID
281 unsigned int chanID = (*citr).first;
282 int cannode = chanID/1000;
283 int line = chanID%1000;
284
285 // 2. Construct the identifier
286 HWIdentifier id = m_c->hvId->HVLineId(1,1,cannode,line);
287
288
289 const std::vector<HWIdentifier>& electrodeIdVec = idfunc(id);
290
291 for(size_t i=0;i<electrodeIdVec.size();i++) {
292 HWIdentifier elecHWID = electrodeIdVec[i];
293
294 int detector = m_c->elecId->detector(elecHWID);
295 // check we are in EMEC
296 if (detector==2) {
297
298
299 unsigned int etaIndex=m_c->elecId->hv_eta(elecHWID);
300
301 if ( (etaIndex>6 && m_c->iWheel==EMECHVModule::INNER) || (etaIndex<7 && m_c->iWheel==EMECHVModule::OUTER) ) {
302
303 unsigned int sideIndex=1-m_c->elecId->zside(elecHWID);
304 unsigned int phiIndex=m_c->elecId->module(elecHWID); // 0 to 7
305// rotation for C side
306 if (sideIndex==0) {
307 if (phiIndex<4) phiIndex=3-phiIndex;
308 else phiIndex=11-phiIndex;
309 }
310 unsigned int sectorIndex=m_c->elecId->hv_phi(elecHWID)-1; // 0 to 3 in Outer, 0 to 7 in Inner
311// rotation for C side
312 if (sideIndex==0) {
313 if (m_c->iWheel==EMECHVModule::OUTER) sectorIndex=3-sectorIndex;
314 else sectorIndex=7-sectorIndex;
315 }
316 unsigned int electrodeIndex = m_c->iWheel==EMECHVModule::OUTER ?
317 m_c->elecId->electrode(elecHWID)%24:
318 m_c->elecId->electrode(elecHWID)%4;
319// rotation for C side
320 if (sideIndex==0) {
321 if (m_c->iWheel==EMECHVModule::OUTER) electrodeIndex=23-electrodeIndex;
322 else electrodeIndex=3-electrodeIndex;
323 }
324
325 unsigned int index = m_c->iWheel==EMECHVModule::OUTER ?
326 5376*sideIndex+768*etaIndex+96*phiIndex+24*sectorIndex+electrodeIndex:
327 512*sideIndex+256*(etaIndex-7)+32*phiIndex+4*sectorIndex+electrodeIndex;
328
329 if (m_c->iWheel==EMECHVModule::OUTER && index>10752) {
330 MsgStream msg (Athena::getMessageSvc(), "EMECHVManager");
331 msg << MSG::ERROR << "invalid index outer " << index << " side,eta,phi,sector,electrode " << sideIndex << " " << etaIndex << " " << phiIndex <<
332 " " << sectorIndex << " " << electrodeIndex << endmsg;
333 continue;
334 }
335 if (m_c->iWheel==EMECHVModule::INNER && index>1024) {
336 MsgStream msg (Athena::getMessageSvc(), "EMECHVManager");
337 msg << MSG::ERROR << "invalid index inner " << index << " side,eta,phi,sector,electrode " << sideIndex << " " << etaIndex << " " << phiIndex <<
338 " " << sectorIndex << " " << electrodeIndex << endmsg;
339 continue;
340 }
341
342 unsigned int gapIndex=m_c->elecId->gap(elecHWID);
343 if (gapIndex>1) {
344 MsgStream msg (Athena::getMessageSvc(), "EMECHVManager");
345 msg << MSG::ERROR << "invalid gapIndex " << gapIndex << endmsg;
346 continue;
347 }
348 if (sideIndex==0) gapIndex=1-gapIndex;
349
350 float voltage = EMECHVData::INVALID;;
351 if (!((*citr).second)["R_VMEAS"].isNull()) voltage = ((*citr).second)["R_VMEAS"].data<float>();
352 float current = 0.;
353 if (!((*citr).second)["R_IMEAS"].isNull()) current = ((*citr).second)["R_IMEAS"].data<float>();
354
355
356 payload->m_payloadArray[index].voltage[gapIndex]=voltage;
357 payload->m_payloadArray[index].current[gapIndex]=current;
358 payload->m_payloadArray[index].hvLineNo[gapIndex]=chanID;
359 } // if etaIndex...
360 } // for (electrodeIdVec)
361 } // is EMEC
362 } // for (atrlistcol)
363 }
364
365 return {std::move (payload)};
366}
367
368
371{
372 std::vector<const CondAttrListCollection*> attrLists;
373 ServiceHandle<StoreGateSvc> detStore ("DetectorStore", "EMBHVManager");
374 const CondAttrListCollection* atrlistcol = nullptr;
375 // Not a typo --- this folder has a lower-case l in the database...
376 if (detStore->retrieve(atrlistcol, "/LAR/DCS/HV/BARREl/I16").isSuccess()) {
377 attrLists.push_back (atrlistcol);
378 }
379 if (detStore->retrieve(atrlistcol, "/LAR/DCS/HV/BARREL/I8").isSuccess()) {
380 attrLists.push_back (atrlistcol);
381 }
382 return getData (SimIdFunc(), attrLists);
383}
384
385
386#if !(defined(SIMULATIONBASE) || defined(GENERATIONBASE))
389 const std::vector<const CondAttrListCollection*>& attrLists) const
390{
391 auto idfunc = [&] (HWIdentifier id) -> const std::vector<HWIdentifier>
392 { return hvIdMapping.getLArElectrodeIDvec(id); };
393 return getData (idfunc, attrLists);
394}
395
396
398 , int gap
399 , const LArHVIdMapping* hvIdMapping
400 , HWIdentifier *hvlId) const
401{
402 const EMECHVModule& module = electrode.getModule();
403 int etaIndex = module.getEtaIndex();
404 int phiIndex = module.getPhiIndex();
405 int sectorIndex = module.getSectorIndex();
406 int sideIndex = module.getSideIndex();
407 int electrodeIndex = electrode.getElectrodeIndex();
408
409 // ________________________ Construct ElectrodeID ________________________________
410 int id_detector = 2;
411 int id_zside = 1-sideIndex;
412 int id_hv_eta = m_c->iWheel==EMECHVModule::OUTER ? etaIndex : etaIndex+7;
413
414 int id_module{0};
415 if(sideIndex==0) {
416 if(phiIndex<4) {
417 id_module=3-phiIndex;
418 }
419 else {
420 id_module=11-phiIndex;
421 }
422 }
423 else {
424 id_module = phiIndex;
425 }
426
427 int id_hv_phi{0};
428 if(sideIndex==0) {
429 if (m_c->iWheel==EMECHVModule::OUTER) {
430 id_hv_phi=4-sectorIndex;
431 }
432 else {
433 id_hv_phi=8-sectorIndex;
434 }
435 }
436 else {
437 id_hv_phi=sectorIndex+1;
438 }
439
440 int tmpElec{0};
441 if(sideIndex==0) {
442 if (m_c->iWheel==EMECHVModule::OUTER) {
443 tmpElec = 23-electrodeIndex;
444 }
445 else {
446 tmpElec = 3 - electrodeIndex;
447 }
448 }
449 else {
450 tmpElec = electrodeIndex;
451 }
452 int id_electrode = m_c->iWheel==EMECHVModule::OUTER
453 ? (id_hv_phi-1)*24 + tmpElec
454 : (id_hv_phi-1)*4 + tmpElec;
455
456 int id_gap = sideIndex==0 ? 1-gap : gap;
457
458 HWIdentifier elecHWID = m_c->elecId->ElectrodeId(id_detector
459 , id_zside
460 , id_module
461 , id_hv_phi
462 , id_hv_eta
463 , id_gap
464 , id_electrode);
465 // ________________________ Construct ElectrodeID ________________________________
466
467 // Get LArHVLineID corresponding to a given LArElectrodeId
468 HWIdentifier id = hvIdMapping->getLArHVLineID(elecHWID);
469
470 if(hvlId) *hvlId=id;
471
472 // Extract HV Line No
473 return m_c->hvId->can_node(id)*1000 + m_c->hvId->hv_line(id);
474}
475#endif
#define M_PI
#define endmsg
This file defines the class for a collection of AttributeLists where each one is associated with a ch...
char data[hepevt_bytes_allocation_ATLAS]
Definition HepEvt.cxx:11
This class is a collection of AttributeLists where each one is associated with a channel number.
ChanAttrListMap::const_iterator const_iterator
unsigned int getElectrodeIndex() const
const EMECHVModule & getModule() const
const LArElectrodeID * elecId
Clockwork(const EMECHVManager *manager, IOType wheel, std::unique_ptr< EMECHVDescriptor > the_descriptor)
std::unique_ptr< EMECHVDescriptor > descriptor
const LArHVLineID * hvId
std::unique_ptr< const EMECHVModule > moduleArray[2][8][8][8]
std::vector< EMECHVPayload > m_payloadArray
std::unique_ptr< Payload > m_payload
static constexpr double INVALID
EMECHVData & operator=(EMECHVData &&other) noexcept
static int index(const EMECHVElectrode &electrode)
double current(const EMECHVElectrode &electrode, const int &iGap) const
bool hvOn(const EMECHVElectrode &electrode, const int &iGap) const
double voltage(const EMECHVElectrode &electrode, const int &iGap) const
int hvLineNo(const EMECHVElectrode &electrode, const int &iGap) const
unsigned int beginEtaIndex() const
const EMECHVDescriptor & getDescriptor() const
int hvLineNo(const EMECHVElectrode &electrode, int gap, const LArHVIdMapping *hvIdMapping, HWIdentifier *hvlId=nullptr) const
const EMECHVModule & getHVModule(unsigned int iSide, unsigned int iEta, unsigned int iPhi, unsigned int iSector) const
unsigned int beginSectorIndex() const
unsigned int endPhiIndex() const
static unsigned int beginSideIndex()
std::function< std::vector< HWIdentifier >(HWIdentifier)> idfunc_t
std::unique_ptr< const Clockwork > m_c
static unsigned int endSideIndex()
unsigned int endEtaIndex() const
EMECHVManager::IOType getWheelIndex() const
EMECHVModule::IOType IOType
unsigned int endSectorIndex() const
unsigned int beginPhiIndex() const
EMECHVData getData(const LArHVIdMapping &hvIdMapping, const std::vector< const CondAttrListCollection * > &attrLists) const
EMECHVData getDataSim() const
EMECHVManager(IOType wheel)
Helper for the Liquid Argon Calorimeter cell at the electrode level.
const std::vector< HWIdentifier > & getLArElectrodeIDvec(HWIdentifier &hvlineId) const
Return a vector of LArElectrodeID corresponding to a given LArHVLineID.
const HWIdentifier getLArHVLineID(HWIdentifier &electrodeId) const
Return the LArHVLineID corresponding to a given LArElectrodeId.
Helper for the Liquid Argon Calorimeter High-Voltage identifiers.
Definition LArHVLineID.h:43
singleton-like access to IMessageSvc via open function and helper
IMessageSvc * getMessageSvc(bool quiet=false)
Definition index.py:1
STL namespace.
MsgStream & msg
Definition testRead.cxx:32