ATLAS Offline Software
EMBHVManager.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 #include "LArHV/EMBHVManager.h"
6 #include "LArHV/EMBHVModule.h"
7 #include "LArHV/EMBHVElectrode.h"
8 #include "GeoModelKernel/CellBinning.h"
9 #include <cmath>
10 #include <vector>
11 #include "EMBHVPayload.h"
12 
13 #include "StoreGate/StoreGateSvc.h"
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 
37 namespace {
38 
39 
40 struct 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 
51 SimIdFunc::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 
65 public:
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 {
97 public:
98  std::vector<EMBHVPayload> m_payloadArray;
99 };
100 
101 
103 
104 
105 EMBHVManager::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 
124 bool EMBHVManager::EMBHVData::hvOn (const EMBHVElectrode& electrode, const int& iGap) const
125 {
126  return voltage (electrode, iGap) > INVALID;
127 }
128 
129 
130 double EMBHVManager::EMBHVData::voltage (const EMBHVElectrode& electrode, const int& iGap) const
131 {
132  return m_payload->m_payloadArray[index(electrode)].voltage[iGap];
133 }
134 
135 
136 double EMBHVManager::EMBHVData::current (const EMBHVElectrode& electrode, const int& iGap) const
137 {
138  return m_payload->m_payloadArray[index(electrode)].current[iGap];
139 }
140 
141 
142 int 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 
174 unsigned int EMBHVManager::beginPhiIndex() const
175 {
176  return m_c->descriptor.getPhiBinning().getFirstDivisionNumber();
177 }
178 
179 unsigned int EMBHVManager::endPhiIndex() const
180 {
181  return m_c->descriptor.getPhiBinning().getFirstDivisionNumber() + m_c->descriptor.getPhiBinning().getNumDivisions();
182 }
183 
184 unsigned int EMBHVManager::beginEtaIndex() const
185 {
186  return m_c->descriptor.getEtaBinning().getFirstDivisionNumber();
187 }
188 
189 unsigned int EMBHVManager::endEtaIndex() const
190 {
191  return m_c->descriptor.getEtaBinning().getFirstDivisionNumber() + m_c->descriptor.getEtaBinning().getNumDivisions();
192 }
193 
194 const 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  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) { return hvIdMapping.getLArElectrodeIDvec(id); };
347  return getData (idfunc, attrLists);
348 }
349 
350 
352  , int gap
353  , const LArHVIdMapping* hvIdMapping) const
354 {
355  const EMBHVModule& module = electrode.getModule();
356  int etaIndex = module.getEtaIndex();
357  int phiIndex = module.getPhiIndex();
358  int sectorIndex = module.getSectorIndex();
359  int sideIndex = module.getSideIndex();
360  int electrodeIndex = electrode.getElectrodeIndex();
361 
362  // ________________________ Construct ElectrodeID ________________________________
363  int id_detector = 0;
364  int id_zside = 1 - sideIndex;
365  int id_hv_phi = (sideIndex==1 ? sectorIndex : 1-sectorIndex);
366  int id_hv_eta = etaIndex;
367  int id_gap = (sideIndex==0 ? 1-gap : gap);
368  int tmpPhi = phiIndex;
369  if(sectorIndex==1) {
370  if(tmpPhi==15) {
371  tmpPhi=0;
372  }
373  else {
374  tmpPhi += 1;
375  }
376  }
377 
378  int id_module;
379  if(sideIndex==1) {
380  id_module = tmpPhi;
381  }
382  else {
383  if(tmpPhi<9) {
384  id_module = 8-tmpPhi;
385  }
386  else {
387  id_module = 24-tmpPhi;
388  }
389  }
390 
391  int id_electrode;
392  if(sideIndex==0) {
393  if(id_hv_phi==1) {
394  id_electrode = 31-electrodeIndex;
395  }
396  else {
397  id_electrode = 63-electrodeIndex;
398  }
399  }
400  else {
401  if(id_hv_phi==0) {
402  id_electrode = electrodeIndex+32;
403  }
404  else {
405  id_electrode = electrodeIndex;
406  }
407  }
408 
409  HWIdentifier elecHWID = m_c->elecId->ElectrodeId(id_detector
410  , id_zside
411  , id_module
412  , id_hv_phi
413  , id_hv_eta
414  , id_gap
415  , id_electrode);
416  // ________________________ ________________________________
417 
418  // Get LArHVLineID corresponding to a given LArElectrodeId
419  HWIdentifier id = hvIdMapping->getLArHVLineID(elecHWID);
420 
421  // Extract HV Line No
422  return m_c->hvId->can_node(id)*1000 + m_c->hvId->hv_line(id);
423 }
424 #endif
425 #endif
426 
427 
EMBHVManager::EMBHVData::hvOn
bool hvOn(const EMBHVElectrode &electrode, const int &iGap) const
Definition: EMBHVManager.cxx:124
EMBHVManager::beginEtaIndex
unsigned int beginEtaIndex() const
Definition: EMBHVManager.cxx:184
fillPileUpNoiseLumi.current
current
Definition: fillPileUpNoiseLumi.py:52
EMBHVElectrode
Definition: EMBHVElectrode.h:15
checkFileSG.line
line
Definition: checkFileSG.py:75
CondAttrListCollection.h
This file defines the class for a collection of AttributeLists where each one is associated with a ch...
EMBHVManager::Clockwork::moduleArray
std::unique_ptr< const EMBHVModule > moduleArray[2][8][16][2]
Definition: EMBHVManager.cxx:89
EMBHVManager::endPhiIndex
unsigned int endPhiIndex() const
Definition: EMBHVManager.cxx:179
make_unique
std::unique_ptr< T > make_unique(Args &&... args)
Definition: SkimmingToolEXOT5.cxx:23
LArElectrodeID
Helper for the Liquid Argon Calorimeter cell at the electrode level.
Definition: LArElectrodeID.h:101
index
Definition: index.py:1
EMBHVManager::Clockwork
Definition: EMBHVManager.cxx:64
M_PI
#define M_PI
Definition: ActiveFraction.h:11
EMBHVManager::idfunc_t
std::function< std::vector< HWIdentifier >(HWIdentifier)> idfunc_t
Definition: EMBHVManager.h:95
LArHVIdMapping::getLArHVLineID
const HWIdentifier getLArHVLineID(HWIdentifier &electrodeId) const
Return the LArHVLineID corresponding to a given LArElectrodeId.
Definition: LArHVIdMapping.cxx:22
EMBHVManager::Clockwork::elecId
const LArElectrodeID * elecId
Definition: EMBHVManager.cxx:90
EMBHVManager::beginSectorIndex
static unsigned int beginSectorIndex()
Definition: EMBHVManager.cxx:199
EMBHVManager::EMBHVData::current
double current(const EMBHVElectrode &electrode, const int &iGap) const
Definition: EMBHVManager.cxx:136
LArHVLineID.h
HWIdentifier
Definition: HWIdentifier.h:13
CondAttrListCollection
This class is a collection of AttributeLists where each one is associated with a channel number....
Definition: CondAttrListCollection.h:52
CxxUtils::INVALID
@ INVALID
Definition: CachedValue.h:28
AthenaAttributeList.h
CaloSwCorrections.gap
def gap(flags, cells_name, *args, **kw)
Definition: CaloSwCorrections.py:212
EMBHVManager::EMBHVData::hvLineNo
int hvLineNo(const EMBHVElectrode &electrode, const int &iGap) const
Definition: EMBHVManager.cxx:142
EMBHVManager::beginSideIndex
static unsigned int beginSideIndex()
Definition: EMBHVManager.cxx:209
EMBHVManager::endEtaIndex
unsigned int endEtaIndex() const
Definition: EMBHVManager.cxx:189
EMBHVManager::EMBHVData::Payload
Definition: EMBHVManager.cxx:96
EMBHVElectrode.h
EMBHVManager::Clockwork::Clockwork
Clockwork(const EMBHVManager *manager)
Definition: EMBHVManager.cxx:66
TRT::Hit::detector
@ detector
Definition: HitInfo.h:78
EMBHVManager::getHVModule
const EMBHVModule & getHVModule(unsigned int iSide, unsigned int iEta, unsigned int iPhi, unsigned int iSector) const
Definition: EMBHVManager.cxx:194
EMBHVManager::getDescriptor
const EMBHVDescriptor & getDescriptor() const
Definition: EMBHVManager.cxx:169
python.PyAthena.module
module
Definition: PyAthena.py:134
EMBHVDescriptor
Definition: EMBHVDescriptor.h:11
LArHVCablingSimTool
Mapping from HV lines to electrodes.
Definition: LArHVCablingSimTool.h:29
EMBHVManager::EMBHVData::Payload::m_payloadArray
std::vector< EMBHVPayload > m_payloadArray
Definition: EMBHVManager.cxx:98
lumiFormat.i
int i
Definition: lumiFormat.py:92
EMBHVManager::EMBHVData::voltage
double voltage(const EMBHVElectrode &electrode, const int &iGap) const
Definition: EMBHVManager.cxx:130
EMBHVManager::~EMBHVManager
~EMBHVManager()
EMBHVElectrode::getElectrodeIndex
unsigned int getElectrodeIndex() const
Definition: EMBHVElectrode.cxx:48
EMBHVManager::Clockwork::Clockwork
Clockwork(const Clockwork &)=delete
EMBHVManager::Clockwork::~Clockwork
~Clockwork()=default
LArHVIdMapping.h
EMBHVManager::EMBHVManager
EMBHVManager()
Definition: EMBHVManager.cxx:161
EMBHVManager::EMBHVData::operator=
EMBHVData & operator=(EMBHVData &&other) noexcept
Definition: EMBHVManager.cxx:112
EMBHVManager::getDataSim
EMBHVData getDataSim() const
Definition: EMBHVManager.cxx:324
EMBHVManager::m_c
std::unique_ptr< const Clockwork > m_c
Definition: EMBHVManager.h:103
python.PyKernel.detStore
detStore
Definition: PyKernel.py:41
EMBHVManager::beginPhiIndex
unsigned int beginPhiIndex() const
Definition: EMBHVManager.cxx:174
EMBHVElectrode::getModule
const EMBHVModule & getModule() const
Definition: EMBHVElectrode.cxx:32
EMBHVManager::EMBHVData
Definition: EMBHVManager.h:39
HWIdentifier.h
id
SG::auxid_t id
Definition: Control/AthContainers/Root/debug.cxx:194
EMBHVManager::EMBHVData::INVALID
static constexpr double INVALID
Definition: EMBHVManager.h:41
AtlCoolConsole.tool
tool
Definition: AtlCoolConsole.py:453
EMBHVManager::Clockwork::hvId
const LArHVLineID * hvId
Definition: EMBHVManager.cxx:91
EMBHVManager
This class provides direct access to information on the HV electrodes within the barrels....
Definition: EMBHVManager.h:36
EMBHVManager::hvLineNo
int hvLineNo(const EMBHVElectrode &electrode, int gap, const LArHVIdMapping *hvIdMapping) const
Definition: EMBHVManager.cxx:351
PixelModuleFeMask_create_db.payload
string payload
Definition: PixelModuleFeMask_create_db.py:69
Trk::iPhi
@ iPhi
Definition: ParamDefs.h:53
EMBHVManager::EMBHVData::index
static int index(const EMBHVElectrode &electrode)
Definition: EMBHVManager.cxx:148
eflowRec::phiIndex
unsigned int phiIndex(float phi, float binsize)
calculate phi index for a given phi
Definition: EtaPhiLUT.cxx:23
DeMoScan.index
string index
Definition: DeMoScan.py:362
InDetDD::other
@ other
Definition: InDetDD_Defs.h:16
LArHVIdMapping
Definition: LArHVIdMapping.h:21
CondAttrListCollection::const_iterator
ChanAttrListMap::const_iterator const_iterator
Definition: CondAttrListCollection.h:63
EMBHVPayload.h
LArHVCablingSimTool.h
python.Logging.manager
manager
Definition: PhysicsAnalysis/D3PDTools/AnaAlgorithm/python/Logging.py:92
LArElectrodeID.h
EMBHVManager::getData
EMBHVData getData(const LArHVIdMapping &hvIdMapping, const std::vector< const CondAttrListCollection * > &attrLists) const
Definition: EMBHVManager.cxx:343
EMBHVManager::endSectorIndex
static unsigned int endSectorIndex()
Definition: EMBHVManager.cxx:204
EMBHVManager::EMBHVData::~EMBHVData
~EMBHVData()
EMBHVModule
Describes one HV Module within the EMB.
Definition: EMBHVModule.h:20
EMBHVManager::endSideIndex
static unsigned int endSideIndex()
Definition: EMBHVManager.cxx:214
EMBHVManager::Clockwork::descriptor
EMBHVDescriptor descriptor
Definition: EMBHVManager.cxx:88
xAOD::iEta
setScale setgFexType iEta
Definition: gFexJetRoI_v1.cxx:74
StoreGateSvc.h
EMBHVModule.h
EMBHVManager.h
LArHVIdMapping::getLArElectrodeIDvec
const std::vector< HWIdentifier > & getLArElectrodeIDvec(HWIdentifier &hvlineId) const
Return a vector of LArElectrodeID corresponding to a given LArHVLineID.
Definition: LArHVIdMapping.cxx:83
EMBHVManager::EMBHVData::EMBHVData
EMBHVData()
ServiceHandle< StoreGateSvc >
LArHVLineID
Helper for the Liquid Argon Calorimeter High-Voltage identifiers.
Definition: LArHVLineID.h:48