ATLAS Offline Software
Loading...
Searching...
No Matches
EMBHVManager.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
6#include "LArHV/EMBHVModule.h"
8#include "GeoModelKernel/CellBinning.h"
9#include <cmath>
10#include <vector>
11#include "EMBHVPayload.h"
12
14#include "GaudiKernel/ISvcLocator.h"
15#include "GaudiKernel/IToolSvc.h"
16#include "GaudiKernel/Bootstrap.h"
17#include "GaudiKernel/ServiceHandle.h"
18
21
25
26#ifndef SIMULATIONBASE
27#ifndef GENERATIONBASE
29#endif
30#endif
31
33#include <mutex>
34#include <atomic>
35
36
37namespace {
38
39
40struct SimIdFunc
41{
42 SimIdFunc();
43 std::vector<HWIdentifier> operator()(HWIdentifier id) const
44 {
45 return m_cablingTool->getLArElectrodeIDvec (id);
46 }
47 LArHVCablingSimTool* m_cablingTool;
48};
49
50
51SimIdFunc::SimIdFunc()
52{
53 ToolHandle<LArHVCablingSimTool> tool ("LArHVCablingSimTool");
54 if (!tool.retrieve().isSuccess()) {
55 std::abort();
56 }
57 m_cablingTool = tool.get();
58}
59
60
61} // Anonymous namespace
62
63
65public:
66 explicit Clockwork(const EMBHVManager* manager) {
67 for(int iSide=0; iSide<2; ++iSide) {
68 for(int iEta=0; iEta<8; ++iEta) {
69 for(int iPhi=0; iPhi<16; ++iPhi) {
70 for(int iSector=0; iSector<2; ++iSector) {
71 moduleArray[iSide][iEta][iPhi][iSector] = std::make_unique<EMBHVModule>(manager,iSide,iEta,iPhi,iSector);
72 }
73 }
74 }
75 }
76
77 ServiceHandle<StoreGateSvc> detStore ("DetectorStore", "HECHVManager");
78 if (StatusCode::SUCCESS!=detStore->retrieve(elecId, "LArElectrodeID")) {
79 throw std::runtime_error("EMBHVManager failed to retrieve LArElectrodeID");
80 }
81
82 if (StatusCode::SUCCESS!=detStore->retrieve(hvId,"LArHVLineID")) {
83 throw std::runtime_error("EMBHVManager failed to retrieve LArHVLineID");
84 }
85 }
86 Clockwork(const Clockwork&) = delete;
87 ~Clockwork() = default;
88 EMBHVDescriptor descriptor{CellBinning(0.0, 1.4, 7, 1),CellBinning(0.0, 2*M_PI, 16)};
89 std::unique_ptr<const EMBHVModule> moduleArray[2][8][16][2];
90 const LArElectrodeID* elecId = nullptr;
91 const LArHVLineID* hvId = nullptr;
92};
93
94
96{
97public:
98 std::vector<EMBHVPayload> m_payloadArray;
99};
100
101
103
104
105EMBHVManager::EMBHVData::EMBHVData (std::unique_ptr<Payload> payload)
106 : m_payload (std::move (payload))
107{
108}
109
110
113 if (this != &other) {
114 m_payload = std::move (other.m_payload);
115 }
116 return *this;
117}
118
119
121= default;
122
123
124bool EMBHVManager::EMBHVData::hvOn (const EMBHVElectrode& electrode, const int& iGap) const
125{
126 return voltage (electrode, iGap) > INVALID;
127}
128
129
130double EMBHVManager::EMBHVData::voltage (const EMBHVElectrode& electrode, const int& iGap) const
131{
132 return m_payload->m_payloadArray[index(electrode)].voltage[iGap];
133}
134
135
136double EMBHVManager::EMBHVData::current (const EMBHVElectrode& electrode, const int& iGap) const
137{
138 return m_payload->m_payloadArray[index(electrode)].current[iGap];
139}
140
141
142int EMBHVManager::EMBHVData::hvLineNo (const EMBHVElectrode& electrode, const int& iGap) const
143{
144 return m_payload->m_payloadArray[index(electrode)].hvLineNo[iGap];
145}
146
147
149{
150 unsigned int electrodeIndex = electrode.getElectrodeIndex();
151 const EMBHVModule& module = electrode.getModule();
152 unsigned int etaIndex = module.getEtaIndex();
153 unsigned int phiIndex = module.getPhiIndex();
154 unsigned int sectorIndex = module.getSectorIndex();
155 unsigned int sideIndex = module.getSideIndex();
156 unsigned int index = 8192*sideIndex+1024*etaIndex+64*phiIndex+32*sectorIndex+electrodeIndex;
157 return index;
158}
159
160
162 : m_c (std::make_unique<Clockwork> (this))
163{
164}
165
167= default;
168
170{
171 return m_c->descriptor;
172}
173
174unsigned int EMBHVManager::beginPhiIndex() const
175{
176 return m_c->descriptor.getPhiBinning().getFirstDivisionNumber();
177}
178
179unsigned int EMBHVManager::endPhiIndex() const
180{
181 return m_c->descriptor.getPhiBinning().getFirstDivisionNumber() + m_c->descriptor.getPhiBinning().getNumDivisions();
182}
183
184unsigned int EMBHVManager::beginEtaIndex() const
185{
186 return m_c->descriptor.getEtaBinning().getFirstDivisionNumber();
187}
188
189unsigned int EMBHVManager::endEtaIndex() const
190{
191 return m_c->descriptor.getEtaBinning().getFirstDivisionNumber() + m_c->descriptor.getEtaBinning().getNumDivisions();
192}
193
194const EMBHVModule& EMBHVManager::getHVModule(unsigned int iSide, unsigned int iEta,unsigned int iPhi, unsigned int iSector) const
195{
196 return *(m_c->moduleArray[iSide][iEta][iPhi][iSector]);
197}
198
200{
201 return 0;
202}
203
205{
206 return 2;
207}
208
210{
211 return 0;
212}
213
215{
216 return 2;
217}
218
221 const std::vector<const CondAttrListCollection*>& attrLists) const
222{
223 auto payload = std::make_unique<EMBHVData::Payload>();
224 payload->m_payloadArray.reserve(2*8*16*2*32);
225
226 for (int i=0;i<16384;i++) {
227 payload->m_payloadArray[i].voltage[0] = EMBHVData::INVALID;
228 payload->m_payloadArray[i].voltage[1] = EMBHVData::INVALID;
229 }
230
231 for (const CondAttrListCollection* atrlistcol : attrLists) {
232
233 for (CondAttrListCollection::const_iterator citr=atrlistcol->begin(); citr!=atrlistcol->end();++citr) {
234
235 // Construct HWIdentifier
236 // 1. decode COOL Channel ID
237 unsigned int chanID = (*citr).first;
238 int cannode = chanID/1000;
239 int line = chanID%1000;
240
241 // 2. Construct the identifier
242 HWIdentifier id = m_c->hvId->HVLineId(1,1,cannode,line);
243
244 const std::vector<HWIdentifier>& electrodeIdVec = idfunc(id);
245
246 for(size_t i=0;i<electrodeIdVec.size();i++)
247 {
248 HWIdentifier elecHWID = electrodeIdVec[i];
249 int detector = m_c->elecId->detector(elecHWID);
250 if (detector==0) {
251
252// side in standard offline 0 for z<0 (C) 1 for z>0 (A)
253// in electrode numbering, this is the opposite (0 for A and 1 for C)
254 unsigned int sideIndex=1-m_c->elecId->zside(elecHWID);
255// eta index, no trouble
256 unsigned int etaIndex=m_c->elecId->hv_eta(elecHWID);
257// phi index
258// offline 0 to 2pi in 2pi/16 bins
259// this is module in the electrode numbering: on the A side 0 to 15, 0 is halfway around phi=0 (FT-1 (hv_phi=1 is a lower phi)
260// offline phi 0 pi 2pi
261// Module M0 M1 M1 M15 M0
262// FT 0 -1 0 0 -1
263// hv_phi 0 1 0 0 1
264// phiIndex 0 0 1 15 15
265// sector Index 0 1 0 0 1
266 unsigned int phiIndex;
267 unsigned int sectorIndex;
268 if (sideIndex==1) {
269 phiIndex=m_c->elecId->module(elecHWID);
270 sectorIndex=m_c->elecId->hv_phi(elecHWID);
271 }
272// module numbering on the C side 0 around phi=pi, running backwards
273// offline phi 0 pi 2pi
274// Module P8 P7 P7 P0 P0 P9 P8
275// FT -1 0 -1 0 -1 -1 0
276// hv_phi 1 0 1 0 1 1 0
277// phiIndex 0 0 1 7 8 15 15
278// sectorIndex 0 1 0 1 0 0 1
279 else {
280 int imodule=m_c->elecId->module(elecHWID);
281 if (imodule<9) phiIndex = 8 - imodule;
282 else phiIndex = 24 - imodule;
283 sectorIndex = 1-m_c->elecId->hv_phi(elecHWID);
284 }
285
286 if (sectorIndex==1) {
287 if (phiIndex>0) phiIndex = phiIndex - 1;
288 else phiIndex=15;
289 }
290
291 unsigned int electrodeIndex=m_c->elecId->electrode(elecHWID);
292 if (sideIndex==0) {
293 if (m_c->elecId->hv_phi(elecHWID)==1) electrodeIndex=31-electrodeIndex; // FT-1 change 0->31 to 31->0
294 else electrodeIndex=63-electrodeIndex; // FT 0 change 32->63 to 31-0
295 }
296 else {
297 if (m_c->elecId->hv_phi(elecHWID)==0) electrodeIndex=electrodeIndex-32; // FT 0 change 31-63 to 0-31
298 }
299
300 unsigned int index = 8192*sideIndex+1024*etaIndex+64*phiIndex+32*sectorIndex+electrodeIndex;
301
302 unsigned int gapIndex=m_c->elecId->gap(elecHWID);
303 if (sideIndex==0) gapIndex=1-gapIndex;
304
305 float voltage = EMBHVData::INVALID;
306 if (!((*citr).second)["R_VMEAS"].isNull()) voltage = ((*citr).second)["R_VMEAS"].data<float>();
307 float current = 0.;
308 if (!((*citr).second)["R_IMEAS"].isNull()) current = ((*citr).second)["R_IMEAS"].data<float>();
309
310
311 payload->m_payloadArray[index].voltage[gapIndex]=voltage;
312 payload->m_payloadArray[index].current[gapIndex]=current;
313 payload->m_payloadArray[index].hvLineNo[gapIndex]=chanID;
314 }
315 }
316 }
317 }
318
319 return {std::move (payload)};
320}
321
322
325{
326 std::vector<const CondAttrListCollection*> attrLists;
327 ServiceHandle<StoreGateSvc> detStore ("DetectorStore", "EMBHVManager");
328 const CondAttrListCollection* atrlistcol = nullptr;
329 // Not a typo --- this folder has a lower-case l in the database...
330 if (detStore->retrieve(atrlistcol, "/LAR/DCS/HV/BARREl/I16").isSuccess()) {
331 attrLists.push_back (atrlistcol);
332 }
333 if (detStore->retrieve(atrlistcol, "/LAR/DCS/HV/BARREL/I8").isSuccess()) {
334 attrLists.push_back (atrlistcol);
335 }
336 return getData (SimIdFunc(), attrLists);
337}
338
339
340#ifndef SIMULATIONBASE
341#ifndef GENERATIONBASE
344 const std::vector<const CondAttrListCollection*>& attrLists) const
345{
346 auto idfunc = [&] (HWIdentifier id) -> const std::vector<HWIdentifier>
347 { return hvIdMapping.getLArElectrodeIDvec(id); };
348 return getData (idfunc, attrLists);
349}
350
351
353 , int gap
354 , const LArHVIdMapping* hvIdMapping
355 , HWIdentifier *hvlId) const
356{
357 const EMBHVModule& module = electrode.getModule();
358 int etaIndex = module.getEtaIndex();
359 int phiIndex = module.getPhiIndex();
360 int sectorIndex = module.getSectorIndex();
361 int sideIndex = module.getSideIndex();
362 int electrodeIndex = electrode.getElectrodeIndex();
363
364 // ________________________ Construct ElectrodeID ________________________________
365 int id_detector = 0;
366 int id_zside = 1 - sideIndex;
367 int id_hv_phi = (sideIndex==1 ? sectorIndex : 1-sectorIndex);
368 int id_hv_eta = etaIndex;
369 int id_gap = (sideIndex==0 ? 1-gap : gap);
370 int tmpPhi = phiIndex;
371 if(sectorIndex==1) {
372 if(tmpPhi==15) {
373 tmpPhi=0;
374 }
375 else {
376 tmpPhi += 1;
377 }
378 }
379
380 int id_module;
381 if(sideIndex==1) {
382 id_module = tmpPhi;
383 }
384 else {
385 if(tmpPhi<9) {
386 id_module = 8-tmpPhi;
387 }
388 else {
389 id_module = 24-tmpPhi;
390 }
391 }
392
393 int id_electrode;
394 if(sideIndex==0) {
395 if(id_hv_phi==1) {
396 id_electrode = 31-electrodeIndex;
397 }
398 else {
399 id_electrode = 63-electrodeIndex;
400 }
401 }
402 else {
403 if(id_hv_phi==0) {
404 id_electrode = electrodeIndex+32;
405 }
406 else {
407 id_electrode = electrodeIndex;
408 }
409 }
410
411 HWIdentifier elecHWID = m_c->elecId->ElectrodeId(id_detector
412 , id_zside
413 , id_module
414 , id_hv_phi
415 , id_hv_eta
416 , id_gap
417 , id_electrode);
418 // ________________________ ________________________________
419
420 // Get LArHVLineID corresponding to a given LArElectrodeId
421 HWIdentifier id = hvIdMapping->getLArHVLineID(elecHWID);
422
423 if(hvlId) *hvlId=id;
424
425 // Extract HV Line No
426 return m_c->hvId->can_node(id)*1000 + m_c->hvId->hv_line(id);
427}
428#endif
429#endif
430
431
#define M_PI
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
const EMBHVModule & getModule() const
unsigned int getElectrodeIndex() const
Clockwork(const EMBHVManager *manager)
const LArElectrodeID * elecId
Clockwork(const Clockwork &)=delete
EMBHVDescriptor descriptor
const LArHVLineID * hvId
std::unique_ptr< const EMBHVModule > moduleArray[2][8][16][2]
std::vector< EMBHVPayload > m_payloadArray
static int index(const EMBHVElectrode &electrode)
static constexpr double INVALID
int hvLineNo(const EMBHVElectrode &electrode, const int &iGap) const
bool hvOn(const EMBHVElectrode &electrode, const int &iGap) const
std::unique_ptr< Payload > m_payload
double voltage(const EMBHVElectrode &electrode, const int &iGap) const
EMBHVData & operator=(EMBHVData &&other) noexcept
double current(const EMBHVElectrode &electrode, const int &iGap) const
unsigned int beginPhiIndex() const
unsigned int endEtaIndex() const
static unsigned int endSectorIndex()
unsigned int beginEtaIndex() const
const EMBHVDescriptor & getDescriptor() const
std::function< std::vector< HWIdentifier >(HWIdentifier)> idfunc_t
static unsigned int beginSectorIndex()
const EMBHVModule & getHVModule(unsigned int iSide, unsigned int iEta, unsigned int iPhi, unsigned int iSector) const
int hvLineNo(const EMBHVElectrode &electrode, int gap, const LArHVIdMapping *hvIdMapping, HWIdentifier *hvlId=nullptr) const
EMBHVData getData(const LArHVIdMapping &hvIdMapping, const std::vector< const CondAttrListCollection * > &attrLists) const
EMBHVData getDataSim() const
unsigned int endPhiIndex() const
static unsigned int beginSideIndex()
std::unique_ptr< const Clockwork > m_c
static unsigned int endSideIndex()
Describes one HV Module within the EMB.
Definition EMBHVModule.h:20
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
Definition index.py:1
STL namespace.