ATLAS Offline Software
Loading...
Searching...
No Matches
LArHVCondAlg.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
5#include "./LArHVCondAlg.h"
12#include "LArHV/LArHVManager.h"
13#include "LArHV/EMBHVManager.h"
14#include "LArHV/EMECHVModule.h"
19#include "LArHV/EMECHVManager.h"
23#include "LArHV/HECHVManager.h"
24#include "LArHV/HECHVSubgap.h"
26#include "LArHV/FCALHVManager.h"
27#include "LArHV/FCALHVLine.h"
28
32
36
37#include "CoralBase/Blob.h"
38
39#include <cmath>
40#include <cstdlib>
41#include <set>
42#include <sstream>
43
44#define HV_NON_NOMINAL_TOLERANCE 10 // tolerance : 1V for HV
45#define DEAD_HV_THRESHOLD 10 // HV <10 V="dead"
46#define MAX_LAR_CELLS 182468
47
48//initialize
50 ATH_CHECK( detStore()->retrieve (m_calocellID, "CaloCell_ID") );
51
52 m_larem_id = m_calocellID->em_idHelper();
53 m_larhec_id = m_calocellID->hec_idHelper();
54 m_larfcal_id = m_calocellID->fcal_idHelper();
55
56 ATH_CHECK(detStore()->retrieve(m_electrodeID));
57 ATH_CHECK(detStore()->retrieve(m_hvLineID));
58 ATH_CHECK(detStore()->retrieve(m_onlineID));
59
61
62 if (m_doR) {
63 ATH_MSG_INFO("Will use currents to correct voltage-drop at HV-resistors");
64 }
65 else {
66 ATH_MSG_INFO("Will NOT correct voltage-drop at HV-resistors");
67 }
68
69 // Read Handles
70 ATH_CHECK(m_cablingKey.initialize());
73 ATH_CHECK(m_cablingKey.initialize());
74 ATH_CHECK(m_BFKey.initialize() );
76 ATH_CHECK(m_hvRKey.initialize(m_doR && (m_doHV || m_doAffectedHV)));
78 ATH_CHECK(m_caloMgrKey.initialize());
79 // Write Handles
80
83 ATH_CHECK(m_affectedKey.initialize());
84
85 m_scaleTool=std::make_unique<LArHVScaleCorrTool>(m_calocellID,msg(),m_fixHVCorrStrings);
86
88
89 ATH_MSG_DEBUG("Configured with doHV " << m_doHV << " doAffected " << m_doAffected
90 << " doAffectedHV " << m_doAffectedHV);
91
92 return StatusCode::SUCCESS;
93}
94
95
96StatusCode LArHVCondAlg::execute(const EventContext& ctx) const
97{
98 ATH_MSG_DEBUG("executing");
99 // Allow sharing this between the two calls.
100 voltagePerLine_t voltagePerLine;
101 if (m_doHV || m_doAffectedHV) {
102 ATH_CHECK( makeHVScaleCorr (ctx, voltagePerLine) );
103 }
104 if (m_doAffected) {
105 ATH_CHECK( makeAffectedRegionInfo (ctx, voltagePerLine) );
106 }
107
108 return StatusCode::SUCCESS;
109}
110
111
113{
114
115 std::set<unsigned> changes;
116 const auto items = {std::make_pair(&m_fixHVStrings, &m_fixVoltagePerLine),
117 std::make_pair(&m_fixCurrentStrings, &m_fixCurrentPerLine)};
118 for (auto [prop, store]: items) {
119 store->clear();
120 for (auto& p: prop->value()) {
121 std::stringstream ss(p);
122 unsigned hvline;
123 float value;
124 ss >> hvline >> value >> std::skipws;
125 if (ss && ss.eof()) {
126 changes.insert(hvline);
127 if (auto empl = store->emplace(hvline, value); !empl.second) {
128 ATH_MSG_WARNING("Setting multiple times HV and/or current for line " << hvline
129 << ", this will replace the previous value(s).");
130 empl.first->second = value;
131 }
132 continue;
133 }
134 ATH_MSG_ERROR("Couldn't interpret HV or current setting: \"" << p << "\"");
135 return StatusCode::FAILURE;
136 }
137 }
138 if (changes.size() > 0) {
139 ATH_MSG_INFO("Fixed values of voltage and/or current to be used instead of DCS readings are provided for "
140 << changes.size() << " HV line(s)");
141 }
142 return StatusCode::SUCCESS;
143}
144
145
146StatusCode LArHVCondAlg::makeHVScaleCorr (const EventContext& ctx,
147 voltagePerLine_t& voltagePerLine) const
148{
149 constexpr int RESIDUAL = 0, FULL = 1;
150 std::map<int, SG::WriteCondHandle<LArHVCorr>> writeHandle;
151 for (int ct: {RESIDUAL, FULL}) {
153 if (key.empty()) continue;
154 auto itr = writeHandle.try_emplace(ct, key, ctx).first;
155 if (itr->second.isValid()) {
156 ATH_MSG_DEBUG("Found valid write handle for LArHVCorr, key " << key.key());
157 writeHandle.erase(itr);
158 }
159 }
160 if (writeHandle.empty()) return StatusCode::SUCCESS;
161 const bool doFull = writeHandle.count(FULL), doResid = writeHandle.count(RESIDUAL);
162 auto addDep = [&](auto& dep, const char* debugDescr=nullptr) {
163 for (auto&[ct, wh]: writeHandle) {
164 wh.addDependency(dep);
165 if (!debugDescr) return;
166 std::string dr;
167 if constexpr(requires{dep.getRange();}) {
168 dr = dep.getRange();
169 } else {
170 dr = dep;
171 }
172 ATH_MSG_DEBUG("Range of " << debugDescr << " " << dr
173 << ", intersection (corr. type " << ct << "): " << wh.getRange());
174 }
175 };
176
177 //Start with infinite range and narrow it down
178 {
180 addDep(iov);
181 }
182
184 const LArOnOffIdMapping* cabling=*larCablingHdl;
185 addDep(larCablingHdl, "cabling");
186
188 const CaloDetDescrManager* calodetdescrmgr = *caloMgrHandle;
189 addDep(caloMgrHandle);
190
191 const ILArHVScaleCorr *onlHVCorr{nullptr};
192 if(writeHandle.count(RESIDUAL)) {
194 onlHVCorr = *onlHVCorrHdl;
195 writeHandle.at(RESIDUAL).addDependency(onlHVCorrHdl);
196 ATH_MSG_DEBUG("Range of online HV correction " << onlHVCorrHdl.getRange() << ", intersection: " << writeHandle.at(RESIDUAL).getRange());
197 }
198
200 const LArHVIdMapping* hvCabling = *mappingHdl;
201 addDep(mappingHdl);
202
203 pathVec hasPathologyEM;
204 pathVec hasPathologyHEC;
205 pathVec hasPathologyFCAL;
206 hasPathologyEM.resize(m_larem_id->channel_hash_max());
207 hasPathologyHEC.resize(m_larhec_id->channel_hash_max());
208 hasPathologyFCAL.resize(m_larfcal_id->channel_hash_max());
209
210 bool doPathology=true;
212 const LArHVPathology* pathologyContainer = *pHdl;
213 if(!pathologyContainer) {
214 ATH_MSG_WARNING("Why do not have HV pathology object " << m_pathologiesKey.fullKey() << " ? Work without pathologies !!!");
215 doPathology=false;
216 }
217
218 if(doPathology) {
219 addDep(pHdl, "HV-Pathology");
220 const std::vector<LArHVPathologiesDb::LArHVElectPathologyDb> &pathCont = pathologyContainer->getPathology();
221 const size_t nPathologies=pathCont.size();
222 if (m_nPathologies != nPathologies) {
223 ATH_MSG_INFO( "Number of HV pathologies found " << nPathologies);
224 m_nPathologies=nPathologies;
225 }
226 for(unsigned i=0; i<nPathologies; ++i) {
227 LArHVPathologiesDb::LArHVElectPathologyDb electPath = pathCont[i];
228 Identifier id(electPath.cellID);
229 if (m_larem_id->is_lar_em(id)) {
230 IdentifierHash idHash = m_larem_id->channel_hash(id);
231 unsigned int index = (unsigned int)(idHash);
232 if (index<hasPathologyEM.size()) {
233 if(!hasPathologyEM[index].empty()) {
234 if(hasPathologyEM[index].size()<static_cast<size_t>(abs(electPath.electInd+1)))
235 hasPathologyEM[index].resize(electPath.electInd+1);
236 hasPathologyEM[index][electPath.electInd]=electPath.pathologyType;
237 } else {
238 std::vector<unsigned short> svec;
239 svec.resize(electPath.electInd+1);
240 svec[electPath.electInd]=electPath.pathologyType;
241 hasPathologyEM[index]=svec;
242 }
243 }
244 }
245 if (m_larhec_id->is_lar_hec(id)) {
246 IdentifierHash idHash = m_larhec_id->channel_hash(id);
247 unsigned int index = (unsigned int)(idHash);
248 if (index<hasPathologyHEC.size()) {
249 if(!hasPathologyHEC[index].empty()) {
250 if(hasPathologyHEC[index].size()<static_cast<size_t>(abs(electPath.electInd+1)))
251 hasPathologyHEC[index].resize(electPath.electInd+1);
252 hasPathologyHEC[index][electPath.electInd]=electPath.pathologyType;
253 } else {
254 std::vector<unsigned short> svec;
255 svec.resize(electPath.electInd+1);
256 svec[electPath.electInd]=electPath.pathologyType;
257 hasPathologyHEC[index]=svec;
258 }
259 }
260 }
261 if (m_larfcal_id->is_lar_fcal(id)) {
262 IdentifierHash idHash = m_larfcal_id->channel_hash(id);
263 unsigned int index = (unsigned int)(idHash);
264 if (index<hasPathologyFCAL.size()) {
265 if(!hasPathologyFCAL[index].empty()) {
266 if(hasPathologyFCAL[index].size()<static_cast<size_t>(abs(electPath.electInd+1)))
267 hasPathologyFCAL[index].resize(electPath.electInd+1);
268 hasPathologyFCAL[index][electPath.electInd]=electPath.pathologyType;
269 } else {
270 std::vector<unsigned short> svec;
271 svec.resize(electPath.electInd+1);
272 svec[electPath.electInd]=electPath.pathologyType;
273 hasPathologyFCAL[index]=svec;
274 }
275
276 }
277 }
278 } // Pathology containers
279 }//doPathology
280
281 const float* rValues{nullptr};
282 if(m_doR) {
284 const AthenaAttributeList* attr = *readAttrHandle;
285 addDep(readAttrHandle);
286 // store the conditions blob
287 const coral::Blob& rBlob = (*attr)["ElectrodeRvalues"].data<coral::Blob>();
288 if(rBlob.size()/sizeof(float) != m_electrodeID->electrodeHashMax()) {
289 ATH_MSG_ERROR("Expected " << m_electrodeID->electrodeHashMax() << " R values, but got " << rBlob.size()/sizeof(float) << " aborting");
290 return StatusCode::FAILURE;
291 }
292 rValues = static_cast<const float*>(rBlob.startingAddress());
293 }
294
295 ATH_CHECK( getVoltagePerLine (ctx, voltagePerLine, addDep) );
296
298 ATH_CHECK(fillPathAndCellHV(calodetdescrmgr,voltageVec, hvCabling, voltagePerLine,
299 pathologyContainer, hasPathologyEM, hasPathologyHEC, hasPathologyFCAL, rValues));
300
301 auto clampCorr = [&](float value, const HWIdentifier hwid) {
302 if (value < 0.9f) {
303 if (value < 0.01f) {
304 ATH_MSG_WARNING("Ignoring suspiciously small correction factor of " << value
305 << " for channel " << m_onlineID->channel_name(hwid));
306 value = 1.f;
307 } else if (value < 0.4f) {
308 ATH_MSG_WARNING("HV corr for channel " << m_onlineID->channel_name(hwid)
309 << " = " << value);
310 } else {
311 ATH_MSG_DEBUG("HV corr for channel " << m_onlineID->channel_name(hwid)
312 << " = " << value);
313 }
314 }
315 return value;
316 };
317 std::vector<float> vScale[2];
318 if (doResid) vScale[RESIDUAL].resize(MAX_LAR_CELLS, 1.f);
319 if (doFull) vScale[FULL].resize(MAX_LAR_CELLS, 1.f);
320 for (unsigned i=0;i<MAX_LAR_CELLS;++i) {
321 IdentifierHash hash(i);
322 const CaloDetDescrElement* dde = calodetdescrmgr->get_element(hash);
323 const HWIdentifier hwid=cabling->createSignalChannelIDFromHash(hash);
324 float scale=m_scaleTool->getHVScale(dde,voltageVec[i],msg());
325 if (doResid) { // factor out the online correction
326 float onlineCorr = onlHVCorr->HVScaleCorr(hwid);
327 if (onlineCorr<=0.f || onlineCorr>=100.f) onlineCorr = 1.f;
328 vScale[RESIDUAL][i] = clampCorr(scale/onlineCorr, hwid);
329 }
330 if (doFull) vScale[FULL][i] = clampCorr(scale, hwid);
331 } //end loop over all cells
332 for (auto& [ct, wh]: writeHandle) {
333 auto hvCorr = std::make_unique<LArHVCorr>(std::move(vScale[ct]), cabling, m_calocellID);
334 if (wh.record(std::move(hvCorr)).isFailure()) {
335 ATH_MSG_ERROR("Could not record LArHVCorr object with " << wh.key()
336 << " with EventRange " << wh.getRange() << " into Conditions Store");
337 return StatusCode::FAILURE;
338 }
339 ATH_MSG_INFO("recorded new " << wh.key() << " with range " << wh.getRange() << " into Conditions Store");
340 }
341 return StatusCode::SUCCESS;
342}
343
344
345StatusCode LArHVCondAlg::makeAffectedRegionInfo (const EventContext& ctx,
346 voltagePerLine_t& voltagePerLine) const
347{
349 if (writeAffectedHandle.isValid()) {
350 ATH_MSG_DEBUG("Found valid write LArAffectedRegions handle");
351 return StatusCode::SUCCESS;
352 }
353
355 const LArOnOffIdMapping* cabling=*larCablingHdl;
356 ATH_MSG_DEBUG("Range of cabling" << larCablingHdl.getRange() << ", intersection: " << writeAffectedHandle.getRange());
357 writeAffectedHandle.addDependency(larCablingHdl);
358
360 const LArBadFebCont* bfCont = *readBFHandle;
361 writeAffectedHandle.addDependency(readBFHandle);
362 ATH_MSG_DEBUG("Range of BadFeb " << readBFHandle.getRange() << ", intersection: " << writeAffectedHandle.getRange());
363
364 auto vAffected = std::make_unique<CaloAffectedRegionInfoVec>();
365 if (m_doAffectedHV) {
366 auto addDep = [&] (SG::ReadCondHandle<CondAttrListCollection>& h, const char* debugDescr) {
367 writeAffectedHandle.addDependency (h);
368 if (debugDescr) ATH_MSG_DEBUG("Range of " << debugDescr << " " << h.getRange()
369 << ", intersection: " << writeAffectedHandle.getRange());
370 };
371 ATH_CHECK( getVoltagePerLine (ctx, voltagePerLine, addDep) );
372
374 const LArHVIdMapping* hvCabling = *mappingHdl;
375 writeAffectedHandle.addDependency(mappingHdl);
376
377 ATH_CHECK(searchNonNominalHV_EMB(vAffected.get(), hvCabling, voltagePerLine));
378 ATH_CHECK(searchNonNominalHV_EMEC_OUTER(vAffected.get(), hvCabling, voltagePerLine));
379 ATH_CHECK(searchNonNominalHV_EMEC_INNER(vAffected.get(), hvCabling, voltagePerLine));
380 ATH_CHECK(searchNonNominalHV_HEC(vAffected.get(), hvCabling, voltagePerLine));
381 ATH_CHECK(searchNonNominalHV_FCAL(vAffected.get(), hvCabling, voltagePerLine));
382 }
383
384 ATH_CHECK(updateMethod(ctx, vAffected.get(), bfCont, cabling));
385 ATH_CHECK(writeAffectedHandle.record(std::move(vAffected)));
386 ATH_MSG_INFO("recorded new " << writeAffectedHandle.key() << " with range "
387 << writeAffectedHandle.getRange()<< " into Conditions Store");
388
389 return StatusCode::SUCCESS;
390}
391
392
393StatusCode LArHVCondAlg::getVoltagePerLine (const EventContext& ctx,
394 voltagePerLine_t& voltagePerLine,
395 const addDepFcn_t& addDep) const
396{
397 // Do this bit unconditionally, so that dependencies are propagated correctly.
398 std::vector<const CondAttrListCollection*> attrvec;
399 // get handles to DCS Database folders
400 for (const auto& fldkey: m_DCSFolderKeys ) {
402 const CondAttrListCollection* cattr = *dcsHdl;
403 if(cattr) {
404 ATH_MSG_DEBUG("Folder: "<<dcsHdl.key()<<" has size: "<<std::distance(cattr->begin(),cattr->end()));
405 attrvec.push_back(cattr);
406 addDep (dcsHdl, dcsHdl.key().c_str());
407 } else {
408 ATH_MSG_WARNING("Why do not have DCS folder " << fldkey.fullKey());
409 }
410 } // over DCS folders
411
412 // But we can skip this if we've already done it.
413 if (voltagePerLine.empty()) {
414 ATH_CHECK(dcs2LineVoltage(voltagePerLine, attrvec));
415 }
416
417 return StatusCode::SUCCESS;
418}
419
420
422 , voltagePerCell_t& hvdata
423 , const LArHVIdMapping* hvCabling
424 , const voltagePerLine_t& voltage
425 , const LArHVPathology& pathologies
426 , pathVec& hasPathologyEM
427 , pathVec& hasPathologyHEC
428 , pathVec& hasPathologyFCAL
429 , const float* rValues) const
430{
431
432 std::vector<unsigned int> listElec;
433
434 const float uAkOhm = 1.e-3; // current is uA, rValues kOhm, result should be V
435
436
437 // loop over all EM Identifiers
438 for (auto id: m_larem_id->channel_ids()) {
439 const IdentifierHash hash=m_calocellID->calo_cell_hash(id);
440 voltageCell_t& v=hvdata[hash];
441 if (abs(m_larem_id->barrel_ec(id))==1 && m_larem_id->sampling(id) > 0) { // LAr EMB
442 unsigned int index = (unsigned int)(m_larem_id->channel_hash(id));
443 bool hasPathology=false;
444 if (index<hasPathologyEM.size()) {
445 if (!hasPathologyEM[index].empty()) {
446 hasPathology=true;
447 listElec = getElecList(id,pathologies);
448 }
449 }
450 const EMBDetectorElement* embElement = dynamic_cast<const EMBDetectorElement*>(calodetdescrmgr->get_element(hash));
451 if (!embElement) std::abort();
452 const EMBCellConstLink cell = embElement->getEMBCell();
453 unsigned int nelec = cell->getNumElectrodes();
454 unsigned int ngap = 2*nelec;
455 float wt = 1./ngap;
456 for (unsigned int i=0;i<nelec;i++) {
457 const EMBHVElectrode& electrode = cell->getElectrode(i);
458 // " " << electrode->getModule()->getEtaIndex() << " " << electrode->getModule()->getPhiIndex() <<
459 // " " << electrode->getModule()->getSectorIndex() << " " << electrode->getElectrodeIndex() << std::endl;
460 for (unsigned int igap=0;igap<2;igap++) {
461 float hv=0;
462 float curr=0;
463 unsigned int hvline = electrode.hvLineNo(igap,hvCabling);
464 auto hvIt=voltage.find(hvline);
465 if(hvIt != voltage.end()) { //Found HV line
466 hv=hvIt->second.hv;
467 if(rValues && m_useCurrentEMB) { // modify the current record
468 curr=hvIt->second.curr;
469 const EMBHVModule &hvmod = electrode.getModule();
470 unsigned ridx = m_electrodeID->electrodeHash(m_electrodeID->ElectrodeId(0,
471 hvmod.getSideIndex(),
472 hvCabling->getCellModule(id),
473 hvmod.getPhiIndex(),
474 hvmod.getEtaIndex(),
475 igap,
476 electrode.getElectrodeIndex() ));
477 if(curr > 0.) curr *= uAkOhm * rValues[ridx]; else curr = 0.;
478 ATH_MSG_VERBOSE("channel. "<<std::hex<<id.get_identifier32()<<std::dec <<" hvline: "<<hvline<<" curr. " << curr << " R: "<<rValues[ridx]);
479 }//end if rValues
480 if (hasPathology) {
481 ATH_MSG_VERBOSE( "Has pathology for id: "<< m_larem_id->print_to_string(id)<<" "<<hasPathologyEM[index]);
482 msg(MSG::VERBOSE) << "Original hv: "<<hv<<" ";
483 for (unsigned int ii=0;ii<listElec.size();ii++) {
484 if (listElec[ii]==(2*i+igap) && listElec[ii]<hasPathologyEM[index].size() && hasPathologyEM[index][listElec[ii]]) {
485 if(hasPathologyEM[index][listElec[ii]]&LArHVPathologyBits::MaskHV) {
486 hv=0.;
487 curr = 0.;
488 } else if(hasPathologyEM[index][listElec[ii]]&LArHVPathologyBits::MaskCurr) {
489 curr = 0.;
490 } else {
491 hv=((hasPathologyEM[index][listElec[ii]]&LArHVPathologyBits::SetHVMask)>>4);
492 curr=0.;
493 }
494 }
495 }
496 msg(MSG::VERBOSE) << "set hv: "<<hv<<endmsg;
497 }//end if has patology
498
499 }//end got hv
500 else {
501 ATH_MSG_WARNING("Do not have hvline: "<<hvline<<" in LArHVData mapping ! Set voltage to 0 !");
502 }
503 addHV(v,hv-curr,wt);
504 }//end loop over gaps
505 }//end loop over electrodes
506 } else if (abs(m_larem_id->barrel_ec(id))==1 && m_larem_id->sampling(id) == 0) { // EMBPS
507
508 const EMBDetectorElement* embElement = dynamic_cast<const EMBDetectorElement*>(calodetdescrmgr->get_element(hash));
509 if (!embElement) std::abort();
510 const EMBCellConstLink cell = embElement->getEMBCell();
511 const EMBPresamplerHVModule& hvmodule = cell->getPresamplerHVModule ();
512
513 float wt = 0.5;
514 for (unsigned int igap=0;igap<2;igap++) {
515 float hv=0;
516 float curr=0;
517 unsigned hvline = hvmodule.hvLineNo(igap,hvCabling);
518 auto hvIt=voltage.find(hvline);
519 if(hvIt != voltage.end()) { //Found HV line
520 hv=hvIt->second.hv;
521 if(rValues && m_useCurrentOthers) { // modify the current record
522 curr=hvIt->second.curr;
523 unsigned ridx = m_electrodeID->electrodeHash(m_electrodeID->ElectrodeId(1,
524 hvmodule.getSideIndex(),
525 hvCabling->getCellModule(id),
526 0, // not used in EMBPS
527 hvmodule.getEtaIndex(),
528 igap,
529 0 // not used in EMBPS
530 ));
531 if(curr > 0.) curr *= uAkOhm * rValues[ridx]; else curr = 0;
532 ATH_MSG_VERBOSE("channel. "<<std::hex<<id.get_identifier32()<<std::dec <<" hvline: "<<hvline<<" curr. " << curr << " R: "<<rValues[ridx]);
533 }//end have rValue
534 }//end have voltage
535 else {
536 ATH_MSG_WARNING("Do not have hvline: "<<hvline<<" in LArHVData mapping ! Set voltage to 0 !");
537 }
538 addHV(v,hv-curr,wt);
539 }//end loop over gaps
540 } else if (abs(m_larem_id->barrel_ec(id))>1 && m_larem_id->sampling(id) > 0){ // LAr EMEC
541 unsigned int index = (unsigned int)(m_larem_id->channel_hash(id));
542 bool hasPathology=false;
543 if (index<hasPathologyEM.size()) {
544 if (!hasPathologyEM[index].empty()) {
545 hasPathology=true;
546 listElec = getElecList(id, pathologies);
547 }
548 }
549
550 const EMECDetectorElement* emecElement = dynamic_cast<const EMECDetectorElement*>(calodetdescrmgr->get_element(hash));
551 if (!emecElement) std::abort();
552 const EMECCellConstLink cell = emecElement->getEMECCell();
553 unsigned int nelec = cell->getNumElectrodes();
554 unsigned int ngap = 2*nelec;
555 float wt = 1./ngap;
556 for (unsigned int i=0;i<nelec;i++) {
557 const EMECHVElectrode& electrode = cell->getElectrode(i);
558 for (unsigned int igap=0;igap<2;igap++) {
559 float hv=0;
560 float curr=0;
561 unsigned hvline = electrode.hvLineNo(igap,hvCabling);
562 auto hvIt=voltage.find(hvline);
563 if(hvIt != voltage.end()) { //Found HV line
564 hv=hvIt->second.hv;
565 if(rValues && m_useCurrentOthers) { // modify the current record
566 curr=hvIt->second.curr;
567 const EMECHVModule &hvmod = electrode.getModule();
568 unsigned ridx = m_electrodeID->electrodeHash(m_electrodeID->ElectrodeId(2,
569 hvmod.getSideIndex(),
570 hvCabling->getCellModule(id),
571 hvmod.getPhiIndex(),
572 hvmod.getEtaIndex(),
573 hvmod.getSectorIndex(),
574 electrode.getElectrodeIndex() ));
575 if(curr > 0.) curr *= uAkOhm * rValues[ridx]; else curr = 0.;
576 ATH_MSG_VERBOSE("channel. "<<std::hex<<id.get_identifier32()<<std::dec <<" hvline: "<<hvline<<" curr. " << curr << " R: "<<rValues[ridx]);
577 }
578 if (hasPathology) {
579 msg(MSG::VERBOSE) << "Has pathology for id: "<< m_larem_id->print_to_string(id)<<" "<<hasPathologyEM[index]<<endmsg;
580 for (unsigned int ii=0;ii<listElec.size();ii++) {
581 if (listElec[ii]==(2*i+igap) && listElec[ii]<hasPathologyEM[index].size() && hasPathologyEM[index][listElec[ii]]) {
582 if(hasPathologyEM[index][listElec[ii]]&LArHVPathologyBits::MaskHV) {
583 hv=0.;
584 curr = 0.;
585 } else if(hasPathologyEM[index][listElec[ii]]&LArHVPathologyBits::MaskCurr) {
586 curr = 0.;
587 } else {
588 hv=((hasPathologyEM[index][listElec[ii]]&0xFFF0)>>4);
589 curr=0.;
590 }
591 }
592 }
593 }//end hasPatology
594 }//end have voltage
595 else {
596 ATH_MSG_WARNING("Do not have hvline: "<<hvline<<" in LArHVData mapping ! Set voltage to 0 !");
597 }
598 addHV(v,hv-curr,wt);
599 }//end loop over gaps
600 }//end loop over electrodes
601
602 } else if (abs(m_larem_id->barrel_ec(id))>1 && m_larem_id->sampling(id)==0) { // EMECPS
603
604 const EMECDetectorElement* emecElement = dynamic_cast<const EMECDetectorElement*>(calodetdescrmgr->get_element(hash));
605 if (!emecElement) std::abort();
606 const EMECCellConstLink cell = emecElement->getEMECCell();
607 const EMECPresamplerHVModule& hvmodule = cell->getPresamplerHVModule ();
608
609 double wt = 0.5;
610 for (unsigned int igap=0;igap<2;igap++) {
611 float hv=0;
612 float curr=0;
613 unsigned int hvline = hvmodule.hvLineNo(igap,hvCabling);
614 auto hvIt=voltage.find(hvline);
615 if(hvIt != voltage.end()) { //Found HV line
616 hv=hvIt->second.hv;
617 if(rValues && m_useCurrentOthers) { // modify the current record
618 curr=hvIt->second.curr;
619 unsigned ridx = m_electrodeID->electrodeHash(m_electrodeID->ElectrodeId(3,
620 hvmodule.getSideIndex(),
621 hvCabling->getCellModule(id),
622 0, // not used in EMECPS
623 0,
624 igap,
625 0 // not used in EMECPS
626 ));
627 if(curr >0.) curr *= uAkOhm * rValues[ridx]; else curr=0.;
628 ATH_MSG_VERBOSE("channel. "<<std::hex<<id.get_identifier32()<<std::dec <<" hvline: "<<hvline<<" curr. " << curr << " R: "<<rValues[ridx]);
629 }//end if rValues
630
631 }//end have hv-value
632 else {
633 ATH_MSG_WARNING("Do not have hvline: "<<hvline<<" in LArHVData mapping ! Set voltage to 0 !");
634 }
635 addHV(v,hv-curr,wt);
636 }//end loop over gaps
637 } else { // something wrong
638 ATH_MSG_ERROR("This could not be, what happened with EM identifiers ?");
639 return StatusCode::FAILURE;
640 }
641 } // end loop over EM-identifiers
642
643
644 // LAr HEC
645 for( auto id: m_larhec_id->channel_ids()) {
646 const IdentifierHash hash=m_calocellID->calo_cell_hash(id);
647 unsigned int index = (unsigned int)(m_larhec_id->channel_hash(id));
648 bool hasPathology=false;
649 if (index<hasPathologyHEC.size()) {
650 if (!hasPathologyHEC[index].empty()) {
651 hasPathology=true;
652 listElec = getElecList(id, pathologies);
653 }
654 }
655 const HECDetectorElement* hecElement = dynamic_cast<const HECDetectorElement*>(calodetdescrmgr->get_element(hash));
656 if (!hecElement) std::abort();
657 const HECCellConstLink cell = hecElement->getHECCell();
658 unsigned int nsubgaps = cell->getNumSubgaps();
659 float wt = 1./nsubgaps;
660 voltageCell_t& v=hvdata[hash];
661 for (unsigned int i=0;i<nsubgaps;i++) {
662 float hv=0;
663 float curr=0;
664 const HECHVSubgap& subgap = cell->getSubgap(i);
665 unsigned int hvline = subgap.hvLineNo(hvCabling);
666 auto hvIt=voltage.find(hvline);
667 if(hvIt != voltage.end()) { //Found HV line
668 hv=hvIt->second.hv;
669 if(rValues && m_useCurrentOthers) { // modify the current record
670 curr=hvIt->second.curr;
671 const HECHVModule &hvmod = subgap.getModule();
672 unsigned ridx = m_electrodeID->electrodeHash(m_electrodeID->ElectrodeId(4,
673 hvmod.getSideIndex(),
674 hvCabling->getCellModule(id),
675 0, // not used in HEC
676 hvmod.getSamplingIndex(),
677 subgap.getSubgapIndex(),
678 0 // not used in HEC
679 ));
680 if(curr > 0.) curr *= uAkOhm * rValues[ridx]; else curr = 0.;
681 ATH_MSG_VERBOSE("channel. "<<std::hex<<id.get_identifier32()<<std::dec <<" hvline: "<<hvline<<" cur. " << curr << " R: "<<rValues[ridx]);
682 }
683 if (hasPathology) {
684 msg(MSG::VERBOSE) << "Has pathology for id: "<< m_larhec_id->print_to_string(id)<<" "<<hasPathologyHEC[index]<<endmsg;
685 for (unsigned int ii=0;ii<listElec.size();ii++) {
686 if (listElec[ii]==i && listElec[ii]<hasPathologyHEC[index].size() && hasPathologyHEC[index][listElec[ii]]) {
687 if(hasPathologyHEC[index][listElec[ii]]&LArHVPathologyBits::MaskHV) {
688 hv=0.;
689 curr = 0.;
690 } else if(hasPathologyHEC[index][listElec[ii]]&LArHVPathologyBits::MaskCurr){
691 curr = 0.;
692 } else {
693 hv=((hasPathologyHEC[index][listElec[ii]]&LArHVPathologyBits::SetHVMask)>>4);
694 curr=0.;
695 }
696 }
697 }
698 }//end have pathology
699 } //end have voltage
700 else {
701 ATH_MSG_WARNING("Do not have hvline: "<<hvline<<" in LArHVData mapping ! Set voltage to 0 !");
702 }
703 addHV(v,hv-curr,wt);
704 }//end loop over subgaps
705 }//end loop over HEC-IDs
706
707
708 for(auto id: m_larfcal_id->channel_ids()) { // LAr FCAL
709 unsigned int index = (unsigned int)(m_larfcal_id->channel_hash(id));
710 const IdentifierHash hash=m_calocellID->calo_cell_hash(id);
711 bool hasPathology=false;
712 if (index<hasPathologyFCAL.size()) {
713 if (!hasPathologyFCAL[index].empty()) {
714 hasPathology=true;
715 listElec = getElecList(id, pathologies);
716 }
717 }
718
719 const FCALDetectorElement* fcalElement = dynamic_cast<const FCALDetectorElement*>(calodetdescrmgr->get_element(hash));
720 if (!fcalElement) std::abort();
721 const FCALTile* tile = fcalElement->getFCALTile();
722 unsigned int nlines = tile->getNumHVLines();
723 unsigned int nlines_found=0;
724 for (unsigned int i=0;i<nlines;i++) {
725 const FCALHVLine* line = tile->getHVLine(i);
726 if (line) nlines_found++;
727 }
728 if (nlines_found>0) {
729 float wt = 1./nlines_found;
730 voltageCell_t& v=hvdata[hash];
731 for (unsigned int i=0;i<nlines;i++) {
732 const FCALHVLine* line = tile->getHVLine(i);
733 if (!line) continue;
734 unsigned int hvline = line->hvLineNo(hvCabling);
735 float hv=0;
736 float curr=0;
737 auto hvIt=voltage.find(hvline);
738 if(hvIt != voltage.end()) { //Found HV line
739 hv=hvIt->second.hv;
740 bool useCurrent= (m_larfcal_id->module(id)==1 && m_useCurrentFCAL1) || (m_larfcal_id->module(id)!=1 && m_useCurrentOthers);
741 if(rValues && useCurrent) { // modify the current record
742 curr=hvIt->second.curr;
743 const FCALHVModule& hvmod = line->getModule();
744 unsigned ridx = m_electrodeID->electrodeHash(m_electrodeID->ElectrodeId(5,
745 hvmod.getSideIndex(),
746 hvCabling->getCellModule(id),
747 0, // not used in FCAL
748 hvmod.getSamplingIndex(),
749 hvmod.getSectorIndex(),
750 line->getLineIndex()
751 ));
752 if(curr > 0.) curr *= uAkOhm * rValues[ridx]; else curr = 0.;
753 ATH_MSG_VERBOSE("channel. "<<std::hex<<id.get_identifier32()<<std::dec <<" hvline: "<<hvline<<" curr." << curr << " R: "<<rValues[ridx]);
754 }
755 if (hasPathology) {
756 msg(MSG::VERBOSE) << "Has pathology for id: "<< m_larfcal_id->print_to_string(id)<<" "<<hasPathologyFCAL[index]<<endmsg;
757 for (unsigned int ii=0;ii<listElec.size();ii++) {
758 if (listElec[ii]==i && listElec[ii]<hasPathologyFCAL[index].size() && hasPathologyFCAL[index][listElec[ii]]) {
759 if(hasPathologyFCAL[index][listElec[ii]]&LArHVPathologyBits::MaskHV){
760 hv=0.;
761 curr = 0.;
762 } else if(hasPathologyFCAL[index][listElec[ii]]&LArHVPathologyBits::MaskCurr){
763 curr = 0.;
764 } else {
765 hv=((hasPathologyFCAL[index][listElec[ii]]&0xFFF0)>>4);
766 curr=0.;
767 }
768 }
769 }
770 }//end if have pathology
771 }//end got voltage
772 else {
773 ATH_MSG_WARNING("Do not have hvline: "<<hvline<<" in LArHVData mapping ! Set voltage to 0 !");
774 }
775 addHV(v,hv-curr,wt);
776
777 }//end loop over lines
778 }//end if found line
779 }// end loop over fcal ids
780
781 return StatusCode::SUCCESS;
782}
783
784void LArHVCondAlg::addHV(voltageCell_t& v , float hv, float wt) const {
785 bool found=false;
786 for (unsigned int i=0;i<v.size();i++) {
787 if (std::fabs(hv-v[i].hv) <0.1) {
788 found=true;
789 v[i].weight += wt;
790 break;
791 }
792 }
793 if (!found) {
794 v.emplace_back(hv,wt);
795 } // not already in the list
796}
797
798
799std::vector<unsigned int> LArHVCondAlg::getElecList(const Identifier& id, const LArHVPathology& pathologyContainer) const
800{
801 std::vector<unsigned int> myList;
802 myList.clear();
803 for(unsigned i=0; i<pathologyContainer.getPathology().size(); ++i) {
804 LArHVPathologiesDb::LArHVElectPathologyDb electPath = pathologyContainer.getPathology()[i];
805 if (electPath.cellID == (unsigned int)(id.get_identifier32().get_compact())) {
806 myList.push_back(electPath.electInd);
807 }
808 }
809 return myList;
810
811}
812
813
814
815StatusCode LArHVCondAlg::dcs2LineVoltage(voltagePerLine_t& result, const std::vector<const CondAttrListCollection* >& fldvec) const {
816
817
818 result.clear();
819
820 ATH_MSG_DEBUG("Got "<<fldvec.size()<<" DCS HV folders");
821 for(const auto *attrlist : fldvec) { // loop over all DCS folders
822 CondAttrListCollection::const_iterator citr=attrlist->begin();
823 CondAttrListCollection::const_iterator citr_e=attrlist->end();
824 ATH_MSG_DEBUG("Length: "<<std::distance(citr,citr_e));
825 for(;citr!=citr_e;++citr) {
826 const unsigned chan=citr->first;
827 ATH_MSG_VERBOSE("Got HV cool chan: "<< chan);
828 const coral::Attribute& attr=((citr)->second)["R_VMEAS"];
829 float voltage=-999;
830 if (!attr.isNull()) voltage=attr.data<float>(); //Ignore NULL values
831 const coral::Attribute& attrc=((citr)->second)["R_IMEAS"];
832 float current=0.;
833 if (!attrc.isNull()) current=attrc.data<float>(); //Ignore NULL values
834 ATH_MSG_VERBOSE("read voltage: "<<voltage<<" and current: "<<current );
835 auto empl=result.emplace(chan,DCS_t{voltage,current});
836 if (!empl.second) {
837 ATH_MSG_WARNING("DCS channel " << chan << " encountered twice!");
838 }
839 }//end loop over attributeListCollection
840 }
841 for (auto [chan, desired]: m_fixVoltagePerLine) {
842 if (auto empl = result.emplace(chan, DCS_t{desired, 0.f}); !empl.second) {
843 DCS_t& dcs = empl.first->second;
844 ATH_MSG_DEBUG("Changing voltage for " << chan << " from " << dcs.hv << " to " << desired);
845 dcs.hv = desired;
846 } else {
847 ATH_MSG_WARNING("voltage set for channel " << chan << " unknown to DCS.");
848 }
849 }
850 for (auto [chan, desired]: m_fixCurrentPerLine) {
851 if (auto empl = result.emplace(chan, DCS_t{0.f, desired}); !empl.second) {
852 DCS_t& dcs = empl.first->second;
853 ATH_MSG_DEBUG("Changing current for " << chan << " from " << dcs.curr << " to " << desired);
854 dcs.curr = desired;
855 } else {
856 ATH_MSG_WARNING("current set for channel " << chan << " unknown to DCS and voltage remains 0?!");
857 }
858 }
859 return StatusCode::SUCCESS;
860}
861
862
863//=========================================================================================
865 , const LArHVIdMapping* hvCabling
866 , const voltagePerLine_t& voltage) const { // deals with LAr HV, EMBarrel
867
868 ATH_MSG_DEBUG(" start HV_EMB ");
869 const LArHVManager *manager = nullptr;
870
871 if (detStore()->retrieve(manager)==StatusCode::SUCCESS) {
872
873 // accordion calorimeter
874 float HVnominal = HV_nominal("EMB",0.);
875 const EMBHVManager& hvManager_EMB=manager->getEMBHVManager();
876
877 for (unsigned int iSide=hvManager_EMB.beginSideIndex();iSide<hvManager_EMB.endSideIndex();iSide++) { // loop over HV modules
878 for (unsigned int iPhi=hvManager_EMB.beginPhiIndex();iPhi<hvManager_EMB.endPhiIndex();iPhi++) {
879 for (unsigned int iSector=hvManager_EMB.beginSectorIndex();iSector<hvManager_EMB.endSectorIndex();iSector++) {
880 for (unsigned int iEta=hvManager_EMB.beginEtaIndex();iEta<hvManager_EMB.endEtaIndex();iEta++) { //0 to 7
881 const EMBHVModule& hvMod = hvManager_EMB.getHVModule(iSide,iEta,iPhi,iSector);
882
883 float eta_min=hvMod.getEtaMin();
884 float eta_max=hvMod.getEtaMax();
885
886 ATH_MSG_VERBOSE("iSide,iPhi,iSector,iEta " << iSide << " " << iPhi << " " << iSector << " " << iEta);
887 float phi_min=+30.,phi_max=-30.;
888
889 bool are_previous_HV_affected=false;
890 bool are_previous_HV_dead=false;
891 for (unsigned int ielec=0;ielec<32;ielec++) { //use hvMod->getNumElectrodes when bug is corrected
892 const EMBHVElectrode& electrode = hvMod.getElectrode(ielec);
893
894 double hv[2]={0.,0.};
895 for (unsigned int iGap=0;iGap<2;iGap++) { // EMB : 2, TRY TO FIND AUTOMATICALLY NB OF GAPS
896 unsigned int hvline = electrode.hvLineNo(iGap,hvCabling);
897 auto hvIt=voltage.find(hvline);
898 if(hvIt == voltage.end()) {
899 ATH_MSG_WARNING("Do not have hvline: "<<hvline<<" in LArHVData ! Assuming missing DCS data");
900 continue;
901 }
902 hv[iGap]=hvIt->second.hv;
903 } //end for iGap
904
905 ATH_MSG_VERBOSE(" electrode HV " << ielec << " " << electrode.getPhi() << " "<< hv[0] << " " << hv[1] );
906
907 //take decisions according to all the gaps HV :
908 bool isDead=false;
909 if (fabs(hv[0])<DEAD_HV_THRESHOLD && fabs(hv[1])<DEAD_HV_THRESHOLD) isDead=true;
910 bool isAffected=false;
911 if ( !isDead && ((fabs(hv[0]-HVnominal)>HV_NON_NOMINAL_TOLERANCE) || (fabs(hv[1]-HVnominal)>HV_NON_NOMINAL_TOLERANCE))) isAffected=true;
912 ATH_MSG_VERBOSE(" dead/affected " << isDead << " " << isAffected);
913
914 // end previous dead region
915 if (are_previous_HV_dead && !isDead) {
916 are_previous_HV_dead=false;
917 ATH_MSG_VERBOSE(" -- end dead region " << eta_min << " " << eta_max << " " <<phi_min << " " << phi_max);
918 CaloAffectedRegionInfo current_CaloAffectedRegionInfo(eta_min,eta_max,phi_min,phi_max,1,3,CaloAffectedRegionInfo::HVdead);
919 vAffected->push_back(current_CaloAffectedRegionInfo);
920 }
921
922 // end previous affected region
923 if (are_previous_HV_affected && !isAffected) {
924 are_previous_HV_affected=false;
925 ATH_MSG_VERBOSE(" -- end affected region " << eta_min << " " << eta_max << " " <<phi_min << " " << phi_max);
926 CaloAffectedRegionInfo current_CaloAffectedRegionInfo(eta_min,eta_max,phi_min,phi_max,1,3,CaloAffectedRegionInfo::HVaffected);
927 vAffected->push_back(current_CaloAffectedRegionInfo);
928 }
929
930 if (isDead) {
931 if (!are_previous_HV_dead) {
932 phi_min=CaloPhiRange::fix(electrode.getPhi()-1e-4);
933 phi_max=CaloPhiRange::fix(electrode.getPhi()+1e-4);
934 ATH_MSG_VERBOSE(" -- start dead region " << eta_min << " " << eta_max << " " << phi_min << " " <<phi_max);
935 are_previous_HV_dead = true;
936 }
937 else {
938 extendPhiRegion(electrode.getPhi(),phi_min,phi_max);
939 ATH_MSG_VERBOSE(" extend dead region " << phi_min << " " << phi_max);
940 }
941 }
942
943 if (isAffected) {
944 if (!are_previous_HV_affected) {
945 phi_min=CaloPhiRange::fix(electrode.getPhi()-1e-4);
946 phi_max=CaloPhiRange::fix(electrode.getPhi()+1e-4);
947 ATH_MSG_VERBOSE(" -- start affected region " << eta_min << " " << eta_max << " " << phi_min << " " <<phi_max);
948 are_previous_HV_affected = true;
949 }
950 else {
951 extendPhiRegion(electrode.getPhi(),phi_min,phi_max);
952 ATH_MSG_VERBOSE(" extend affected region " << phi_min << " " << phi_max);
953 }
954 }
955
956 } // end for ielec
957
958 if (are_previous_HV_affected) { //in case a non nominal exists, stores it if we finish the 32 electrodes (because else the are_previous_HV_affected will be reinitialized for the next 32 electrodes serie )
959 ATH_MSG_VERBOSE(" -- finish affected region after electrode loop " << eta_min << " " << eta_max << " " << phi_min << " " <<phi_max);
960 CaloAffectedRegionInfo current_CaloAffectedRegionInfo(eta_min,eta_max,phi_min,phi_max,1,3,CaloAffectedRegionInfo::HVaffected);
961 vAffected->push_back(current_CaloAffectedRegionInfo);
962 }
963 if (are_previous_HV_dead) {
964 ATH_MSG_VERBOSE(" -- finish dead region after electrode loop " << eta_min << " " << eta_max << " " << phi_min << " " <<phi_max);
965 CaloAffectedRegionInfo current_CaloAffectedRegionInfo(eta_min,eta_max,phi_min,phi_max,1,3,CaloAffectedRegionInfo::HVdead);
966 vAffected->push_back(current_CaloAffectedRegionInfo);
967 }
968 } // end for iEta
969 } // end for iSector
970 } // end for iPhi
971 } //end for iSide
972
973 // barrel presampler
974 const EMBPresamplerHVManager& hvManager_EMBPS=manager->getEMBPresamplerHVManager();
975 HVnominal = HV_nominal("EMBPS",0.);
976 for (unsigned int iSide=hvManager_EMBPS.beginSideIndex();iSide<hvManager_EMBPS.endSideIndex();iSide++) { // loop over HV modules
977 for (unsigned int iPhi=hvManager_EMBPS.beginPhiIndex();iPhi<hvManager_EMBPS.endPhiIndex();iPhi++) {
978 for (unsigned int iEta=hvManager_EMBPS.beginEtaIndex();iEta<hvManager_EMBPS.endEtaIndex();iEta++) { //0 to 7
979 const EMBPresamplerHVModule& hvMod = hvManager_EMBPS.getHVModule(iSide,iEta,iPhi);
980 ATH_MSG_VERBOSE("iSide,iPhi,iEta " << iSide << " " << iPhi << " " << iEta);
981 double hv[2];
982 for (int iGap=0;iGap<2;iGap++) {
983 unsigned int hvline = hvMod.hvLineNo(iGap,hvCabling);
984 auto hvIt=voltage.find(hvline);
985 if(hvIt == voltage.end()) {
986 ATH_MSG_WARNING("Do not have hvline: "<<hvline<<" in LArHVData ! Assuming missing DCS data");
987 continue;
988 }
989 hv[iGap]=hvIt->second.hv;
990 }
991 float eta_min=hvMod.getEtaMin();
992 float eta_max=hvMod.getEtaMax();
993 float phi_min=CaloPhiRange::fix(hvMod.getPhiMin());
994 float phi_max=CaloPhiRange::fix(hvMod.getPhiMax());
995 ATH_MSG_VERBOSE(" HV " << hv[0] << " " << hv[1] << " " << " etamin,etamax,phimin,phimax " << eta_min << " " << eta_max << " " << phi_min << " " << phi_max);
996
997 //take decisions according to all the gaps HV :
998 bool isDead=false;
999 if (fabs(hv[0])<DEAD_HV_THRESHOLD && fabs(hv[1])<DEAD_HV_THRESHOLD) isDead=true;
1000 bool isAffected=false;
1001 if ( !isDead && ((fabs(hv[0]-HVnominal)>HV_NON_NOMINAL_TOLERANCE) || (fabs(hv[1]-HVnominal)>HV_NON_NOMINAL_TOLERANCE))) isAffected=true;
1002 ATH_MSG_VERBOSE(" dead/affected " << isDead << " " << isAffected );
1003
1004 if (isDead) {
1005 CaloAffectedRegionInfo current_CaloAffectedRegionInfo(eta_min,eta_max,phi_min,phi_max,0,0,CaloAffectedRegionInfo::HVdead);
1006 vAffected->push_back(current_CaloAffectedRegionInfo);
1007 }
1008 if (isAffected) {
1009 CaloAffectedRegionInfo current_CaloAffectedRegionInfo(eta_min,eta_max,phi_min,phi_max,0,0,CaloAffectedRegionInfo::HVaffected);
1010 vAffected->push_back(current_CaloAffectedRegionInfo);
1011 }
1012 } // loop over iEta EMBPS
1013 } // loop over iphi EMBPS
1014 } // lop over EMBPS side
1015 } else {
1016 ATH_MSG_ERROR("Do not have EMB HV Manager !!! ");
1017 return StatusCode::FAILURE;
1018 }
1019 return StatusCode::SUCCESS;
1020}
1021//=========================================================================================
1023 , const LArHVIdMapping* hvCabling
1024 , const voltagePerLine_t& voltage) const { // deals with LAr HV, EM EndCap OUTER
1025
1026 const LArHVManager *manager = nullptr;
1027
1028 ATH_MSG_DEBUG(" start HV_EMEC_OUTER ");
1029
1030 if (detStore()->retrieve(manager)==StatusCode::SUCCESS) {
1031
1032 const EMECHVManager& hvManager_EMEC_OUT=manager->getEMECHVManager(EMECHVModule::OUTER);
1033
1034 for (unsigned int iSide=hvManager_EMEC_OUT.beginSideIndex();iSide<hvManager_EMEC_OUT.endSideIndex();iSide++) { // loop over HV modules
1035 for (unsigned int iPhi=hvManager_EMEC_OUT.beginPhiIndex();iPhi<hvManager_EMEC_OUT.endPhiIndex();iPhi++) {
1036 for (unsigned int iSector=hvManager_EMEC_OUT.beginSectorIndex();iSector<hvManager_EMEC_OUT.endSectorIndex();iSector++) {
1037 for (unsigned int iEta=hvManager_EMEC_OUT.beginEtaIndex();iEta<hvManager_EMEC_OUT.endEtaIndex();iEta++) {
1038 const EMECHVModule& hvMod=hvManager_EMEC_OUT.getHVModule(iSide,iEta,iPhi,iSector);
1039
1040 float etaMod = 0.5*(fabs(hvMod.getEtaMin())+fabs(hvMod.getEtaMax()));
1041 float HVnominal = HV_nominal("EMEC",etaMod);
1042
1043 float eta_min=hvMod.getEtaMin();
1044 float eta_max=hvMod.getEtaMax();
1045
1046 ATH_MSG_VERBOSE("iSide,iPhi,iSector,iEta " << iSide << " " << iPhi << " " << iSector << " "
1047 << iEta << " eta_min , eta_max " << eta_min << " " << eta_max );
1048
1049
1050 float phi_min=+30.,phi_max=-30.;
1051
1052 bool are_previous_HV_affected=false;
1053 bool are_previous_HV_dead=false;
1054 for (unsigned int ielec=0;ielec<hvMod.getNumElectrodes();ielec++) { //use hvMod->getNumElectrodes when bug is corrected
1055 const EMECHVElectrode& electrode = hvMod.getElectrode(ielec);
1056
1057 double hv[2];
1058 for (unsigned int iGap=0;iGap<2;iGap++) { //EMEC : 2 gaps, TRY TO FIND AUTOMATICALLY NB OF GAPS
1059 unsigned int hvline = electrode.hvLineNo(iGap,hvCabling);
1060 auto hvIt=voltage.find(hvline);
1061 if(hvIt == voltage.end()) {
1062 ATH_MSG_WARNING("Do not have hvline: "<<hvline<<" in LArHVData ! Assuming missing DCS data");
1063 continue;
1064 }
1065 hv[iGap]=hvIt->second.hv;
1066 } //end for iGap
1067
1068 //------------------
1069 //take decisions according to all the gaps HV :
1070 bool isDead=false;
1071 if (fabs(hv[0])<DEAD_HV_THRESHOLD && fabs(hv[1])<DEAD_HV_THRESHOLD) isDead=true;
1072 bool isAffected=false;
1073 if ( !isDead && ((fabs(hv[0]-HVnominal)>HV_NON_NOMINAL_TOLERANCE) || (fabs(hv[1]-HVnominal)>HV_NON_NOMINAL_TOLERANCE))) isAffected=true;
1074 ATH_MSG_VERBOSE(" electrode HV " << ielec << " " << electrode.getPhi() << " " << hv[0]
1075 << " " << hv[1] << " " << " isDead/isAffected " << isDead << " " << isAffected );
1076
1077 // end previous dead region
1078 if (are_previous_HV_dead && !isDead) {
1079 are_previous_HV_dead=false;
1080 ATH_MSG_VERBOSE(" -- end dead region " << eta_min << " " << eta_max << " " <<phi_min << " " << phi_max);
1081 CaloAffectedRegionInfo current_CaloAffectedRegionInfo(eta_min,eta_max,phi_min,phi_max,5,7,CaloAffectedRegionInfo::HVdead);
1082 vAffected->push_back(current_CaloAffectedRegionInfo);
1083 }
1084
1085 // end previous affected region
1086 if (are_previous_HV_affected && !isAffected) {
1087 are_previous_HV_affected=false;
1088 ATH_MSG_VERBOSE(" -- end affected region " << eta_min << " " << eta_max << " " <<phi_min << " " << phi_max);
1089 CaloAffectedRegionInfo current_CaloAffectedRegionInfo(eta_min,eta_max,phi_min,phi_max,5,7,CaloAffectedRegionInfo::HVaffected);
1090 vAffected->push_back(current_CaloAffectedRegionInfo);
1091 }
1092
1093 if (isDead) {
1094 if (!are_previous_HV_dead) {
1095 phi_min=CaloPhiRange::fix(electrode.getPhi()-1e-4);
1096 phi_max=CaloPhiRange::fix(electrode.getPhi()+1e-4);
1097 are_previous_HV_dead = true;
1098 ATH_MSG_VERBOSE(" -- start dead region " << eta_min << " " << eta_max << " " << phi_min << " " <<phi_max);
1099 }
1100 else {
1101 extendPhiRegion(electrode.getPhi(),phi_min,phi_max);
1102 ATH_MSG_VERBOSE(" extend affected region " << phi_min << " " << phi_max);
1103 }
1104 }
1105
1106 if (isAffected) {
1107 if (!are_previous_HV_affected) {
1108 phi_min=CaloPhiRange::fix(electrode.getPhi()-1e-4);
1109 phi_max=CaloPhiRange::fix(electrode.getPhi()+1e-4);
1110 are_previous_HV_affected = true;
1111 ATH_MSG_VERBOSE(" -- start affected region " << eta_min << " " << eta_max << " " << phi_min << " " <<phi_max);
1112 }
1113 else {
1114 extendPhiRegion(electrode.getPhi(),phi_min,phi_max);
1115 ATH_MSG_VERBOSE(" extend affected region " << phi_min << " " << phi_max);
1116 }
1117 }
1118
1119 } // end for ielec
1120
1121 if (are_previous_HV_affected) {
1122 //in case a non nominal exists, stores it if we finish the 32 electrodes
1123 //(because else the are_previous_HV_affected will be reinitialized
1124 //for the next 32 electrodes serie )
1125 ATH_MSG_VERBOSE(" - finih affected region after electrode loop " << eta_min << " " << eta_max
1126 << " " << phi_max << " " <<phi_max);
1127 CaloAffectedRegionInfo current_CaloAffectedRegionInfo(eta_min,eta_max,phi_min,phi_max,5,7,CaloAffectedRegionInfo::HVaffected);
1128 vAffected->push_back(current_CaloAffectedRegionInfo);
1129 }
1130 if (are_previous_HV_dead) {
1131 ATH_MSG_VERBOSE(" -- finish dead region after electrode loop " << eta_min << " " << eta_max << " " << phi_max << " " <<phi_max);
1132 CaloAffectedRegionInfo current_CaloAffectedRegionInfo(eta_min,eta_max,phi_min,phi_max,5,7,CaloAffectedRegionInfo::HVdead);
1133 vAffected->push_back(current_CaloAffectedRegionInfo);
1134 }
1135 } // end for iEta
1136 } // end for iSector
1137 } // end for iPhi
1138 } //end for iSide
1139
1140 // endcap presampler
1141 const EMECPresamplerHVManager& hvManager_EMECPS=manager->getEMECPresamplerHVManager();
1142 float HVnominal = HV_nominal("EMECPS",0.);
1143 for (unsigned int iSide=hvManager_EMECPS.beginSideIndex();iSide<hvManager_EMECPS.endSideIndex();iSide++) { // loop over HV modules
1144 for (unsigned int iPhi=hvManager_EMECPS.beginPhiIndex();iPhi<hvManager_EMECPS.endPhiIndex();iPhi++) {
1145 const EMECPresamplerHVModule& hvMod = hvManager_EMECPS.getHVModule(iSide,iPhi);
1146 double hv[2];
1147 for (int iGap=0;iGap<2;iGap++) {
1148 unsigned int hvline = hvMod.hvLineNo(iGap,hvCabling);
1149 auto hvIt=voltage.find(hvline);
1150 if(hvIt == voltage.end()) {
1151 ATH_MSG_WARNING("Do not have hvline: "<<hvline<<" in LArHVData ! Assuming missing DCS data");
1152 continue;
1153 }
1154 hv[iGap]=hvIt->second.hv;
1155 }//end loop over gaps
1156 float eta_min=hvMod.getEtaMin();
1157 float eta_max=hvMod.getEtaMax();
1158 float phi_min=CaloPhiRange::fix(hvMod.getPhiMin());
1159 float phi_max=CaloPhiRange::fix(hvMod.getPhiMax());
1160 ATH_MSG_VERBOSE("iSide,iPhi" << iSide << " " << iPhi << " HV " << hv[0] << " " << hv[1] << " "
1161 << " etamin,etamax,phimin,phimax " << eta_min << " " << eta_max << " "
1162 << phi_min << " " << phi_max);
1163
1164 //take decisions according to all the gaps HV :
1165 bool isDead=false;
1166 if (fabs(hv[0])<DEAD_HV_THRESHOLD && fabs(hv[1])<DEAD_HV_THRESHOLD) isDead=true;
1167 bool isAffected=false;
1168 if ( !isDead && ((fabs(hv[0]-HVnominal)>HV_NON_NOMINAL_TOLERANCE) || (fabs(hv[1]-HVnominal)>HV_NON_NOMINAL_TOLERANCE))) isAffected=true;
1169 ATH_MSG_VERBOSE(" dead/affected " << isDead << " " << isAffected);
1170
1171 if (isDead) {
1172 CaloAffectedRegionInfo current_CaloAffectedRegionInfo(eta_min,eta_max,phi_min,phi_max,4,4,CaloAffectedRegionInfo::HVdead);
1173 vAffected->push_back(current_CaloAffectedRegionInfo);
1174 }
1175 if (isAffected) {
1176 CaloAffectedRegionInfo current_CaloAffectedRegionInfo(eta_min,eta_max,phi_min,phi_max,4,4,CaloAffectedRegionInfo::HVaffected);
1177 vAffected->push_back(current_CaloAffectedRegionInfo);
1178 }
1179 } // loop over iphi EMECPS
1180 } // lop over EMECPS side
1181 } else {
1182 ATH_MSG_ERROR("DO not have EMEC HV manager !");
1183 return StatusCode::FAILURE;
1184 }
1185 return StatusCode::SUCCESS;
1186}
1187//=========================================================================================
1189 , const LArHVIdMapping* hvCabling
1190 , const voltagePerLine_t& voltage) const { // deals with LAr HV, EM EndCap INNER
1191 const LArHVManager *manager = nullptr;
1192
1193 ATH_MSG_VERBOSE(" start loop over EMEC_INNER ");
1194 if (detStore()->retrieve(manager)==StatusCode::SUCCESS) {
1195
1196 const EMECHVManager& hvManager_EMEC_IN=manager->getEMECHVManager(EMECHVModule::INNER);
1197
1198 for (unsigned int iSide=hvManager_EMEC_IN.beginSideIndex();iSide<hvManager_EMEC_IN.endSideIndex();iSide++) { // loop over HV modules
1199 for (unsigned int iPhi=hvManager_EMEC_IN.beginPhiIndex();iPhi<hvManager_EMEC_IN.endPhiIndex();iPhi++) {
1200 for (unsigned int iSector=hvManager_EMEC_IN.beginSectorIndex();iSector<hvManager_EMEC_IN.endSectorIndex();iSector++) {
1201 for (unsigned int iEta=hvManager_EMEC_IN.beginEtaIndex();iEta<hvManager_EMEC_IN.endEtaIndex();iEta++) {
1202 const EMECHVModule& hvMod=hvManager_EMEC_IN.getHVModule(iSide,iEta,iPhi,iSector);
1203
1204 float etaMod = 0.5*(fabs(hvMod.getEtaMin())+fabs(hvMod.getEtaMax()));
1205 float HVnominal = HV_nominal("EMEC",etaMod);
1206
1207 float eta_min = hvMod.getEtaMin();
1208 float eta_max = hvMod.getEtaMax();
1209
1210 ATH_MSG_VERBOSE("iSide,iPhi,iSector,iEta " << iSide << " " << iPhi << " " << iSector << " "
1211 << iEta << " eta_min , eta_max " << eta_min << " " << eta_max);
1212
1213 float phi_min=+30.,phi_max=-30.;
1214
1215 bool are_previous_HV_affected=0;
1216 bool are_previous_HV_dead=0;
1217 for (unsigned int ielec=0;ielec<hvMod.getNumElectrodes();ielec++) {
1218 const EMECHVElectrode& electrode = hvMod.getElectrode(ielec);
1219
1220 double hv[2];
1221 for (unsigned int iGap=0;iGap<2;iGap++) {
1222 unsigned int hvline = electrode.hvLineNo(iGap,hvCabling);
1223 auto hvIt=voltage.find(hvline);
1224 if(hvIt == voltage.end()) {
1225 ATH_MSG_WARNING("Do not have hvline: "<<hvline<<" in LArHVData ! Assuming missing DCS data");
1226 continue;
1227 }
1228 hv[iGap]=hvIt->second.hv;
1229 } //end for iGap
1230
1231 //------------------
1232 //take decisions according to all the gaps HV :
1233 bool isDead=false;
1234 if (fabs(hv[0])<DEAD_HV_THRESHOLD && fabs(hv[1])<DEAD_HV_THRESHOLD) isDead=true;
1235 bool isAffected=false;
1236 if ( !isDead && ((fabs(hv[0]-HVnominal)>HV_NON_NOMINAL_TOLERANCE) || (fabs(hv[1]-HVnominal)>HV_NON_NOMINAL_TOLERANCE))) isAffected=true;
1237 ATH_MSG_VERBOSE(" electrode HV " << ielec << " " << electrode.getPhi() << " "
1238 << hv[0] << " " << hv[1] << " " << " isDead, isAffected "
1239 << isDead << " " << isAffected);
1240
1241 // end previous dead region
1242 if (are_previous_HV_dead && !isDead) {
1243 are_previous_HV_dead=false;
1244 ATH_MSG_VERBOSE(" -- end dead region " << eta_min << " " << eta_max << " " <<phi_min << " " << phi_max);
1245 CaloAffectedRegionInfo current_CaloAffectedRegionInfo(eta_min,eta_max,phi_min,phi_max,5,7,CaloAffectedRegionInfo::HVdead);
1246 vAffected->push_back(current_CaloAffectedRegionInfo);
1247 }
1248
1249 // end previous affected region
1250 if (are_previous_HV_affected && !isAffected) {
1251 are_previous_HV_affected=false;
1252 ATH_MSG_VERBOSE(" -- end affected region " << eta_min << " " << eta_max << " " <<phi_min << " " << phi_max);
1253 CaloAffectedRegionInfo current_CaloAffectedRegionInfo(eta_min,eta_max,phi_min,phi_max,5,7,CaloAffectedRegionInfo::HVaffected);
1254 vAffected->push_back(current_CaloAffectedRegionInfo);
1255 }
1256
1257 if (isDead) {
1258 if (!are_previous_HV_dead) {
1259 phi_min=CaloPhiRange::fix(electrode.getPhi()-1e-4);
1260 phi_max=CaloPhiRange::fix(electrode.getPhi()+1e-4);
1261 ATH_MSG_VERBOSE(" -- start dead region " << phi_min << " " << phi_max);
1262 are_previous_HV_dead = true;
1263 }
1264 else {
1265 extendPhiRegion(electrode.getPhi(),phi_min,phi_max);
1266 ATH_MSG_VERBOSE(" extend dead region " << phi_min << " " << phi_max);
1267 }
1268 }
1269
1270 if (isAffected) {
1271 if (!are_previous_HV_affected) {
1272 phi_min=CaloPhiRange::fix(electrode.getPhi()-1e-4);
1273 phi_max=CaloPhiRange::fix(electrode.getPhi()+1e-4);
1274 are_previous_HV_affected = true;
1275 ATH_MSG_VERBOSE(" -- start affected region " << phi_min << " " << phi_max);
1276 }
1277 else {
1278 extendPhiRegion(electrode.getPhi(),phi_min,phi_max);
1279 ATH_MSG_VERBOSE(" extend affected region " << phi_min << " " << phi_max);
1280 }
1281 }
1282
1283 } // end for ielec
1284
1285 if (are_previous_HV_affected) {
1286 //in case a non nominal exists, stores it if we finish the 32 electrodes
1287 //(because else the are_previous_HV_affected will be reinitialized
1288 //for the next 32 electrodes serie )
1289 ATH_MSG_VERBOSE(" - finish affected region after electrode loop " << eta_min << " "
1290 << eta_max << " " << phi_max << " " <<phi_max);
1291 CaloAffectedRegionInfo current_CaloAffectedRegionInfo(eta_min,eta_max,phi_min,phi_max,5,7,CaloAffectedRegionInfo::HVaffected);
1292 vAffected->push_back(current_CaloAffectedRegionInfo);
1293 }
1294 if (are_previous_HV_dead) {
1295 ATH_MSG_VERBOSE(" - end dead region after electrode loop " << eta_min << " " << eta_max << " " << phi_max << " " <<phi_max);
1296 CaloAffectedRegionInfo current_CaloAffectedRegionInfo(eta_min,eta_max,phi_min,phi_max,5,7,CaloAffectedRegionInfo::HVdead);
1297 vAffected->push_back(current_CaloAffectedRegionInfo);
1298 }
1299 } // end for iEta
1300 } // end for iSector
1301 } // end for iPhi
1302 } //end for iSide
1303 } else {
1304 ATH_MSG_ERROR("DO not have EMEC HV manager ");
1305 return StatusCode::FAILURE;
1306 }
1307 return StatusCode::SUCCESS;
1308}
1309//=========================================================================================
1311 , const LArHVIdMapping* hvCabling
1312 , const voltagePerLine_t& voltage) const { // deals with LAr HV, HEC
1313
1314 ATH_MSG_DEBUG(" in HEC ");
1315 const LArHVManager *manager = nullptr;
1316 float etamax_layer[4]={3.3,3.1,3.1,3.3};
1317 float etamin_layer[4]={1.5,1.5,1.6,1.7};
1318
1319 float HVnominal = HV_nominal("HEC",0.);
1320
1321
1322 if (detStore()->retrieve(manager)==StatusCode::SUCCESS) {
1323
1324 const HECHVManager& hvManager_HEC=manager->getHECHVManager();
1325
1326 for (unsigned int iSide=hvManager_HEC.beginSideIndex();iSide<hvManager_HEC.endSideIndex();iSide++) { // loop over HV modules
1327 for (unsigned int iPhi=hvManager_HEC.beginPhiIndex();iPhi<hvManager_HEC.endPhiIndex();iPhi++) {
1328 for (unsigned int iSampling=hvManager_HEC.beginSamplingIndex();iSampling<hvManager_HEC.endSamplingIndex();iSampling++) {
1329 float eta_min,eta_max;
1330 if (iSide==1) {
1331 eta_min = etamin_layer[iSampling];
1332 eta_max = etamax_layer[iSampling];
1333 } else {
1334 eta_min = -1.*etamax_layer[iSampling];
1335 eta_max = -1.*etamin_layer[iSampling];
1336 }
1337
1338 const HECHVModule& hvMod = hvManager_HEC.getHVModule(iSide,iPhi,iSampling);
1339 ATH_MSG_VERBOSE(" iSide,iPhi,iSampling " << iSide << " " << iPhi << " " << iSampling);
1340
1341 double hv[4] = {0}; // 4 subgaps in HEC
1342 for (unsigned int iGap=0;iGap<hvMod.getNumSubgaps();iGap++) {
1343 const HECHVSubgap& subgap=hvMod.getSubgap(iGap);
1344 unsigned int hvline = subgap.hvLineNo(hvCabling);
1345 auto hvIt=voltage.find(hvline);
1346 if(hvIt == voltage.end()) {
1347 ATH_MSG_WARNING("Do not have hvline: "<<hvline<<" in LArHVData ! Assuming missing DCS data");
1348 continue;
1349 }
1350 if(iGap<4) hv[iGap]=hvIt->second.hv;
1351 }// end for iGap
1352
1353 //------------------
1354 //take decisions according to all the gaps HV :
1355 bool isDead=false;
1356 if (fabs(hv[0])<DEAD_HV_THRESHOLD && fabs(hv[1])<DEAD_HV_THRESHOLD && fabs(hv[2])<DEAD_HV_THRESHOLD && fabs(hv[3])<DEAD_HV_THRESHOLD) isDead=true;
1357 bool isAffected=false;
1358 if ( !isDead && ((fabs(hv[0]-HVnominal)>HV_NON_NOMINAL_TOLERANCE) || (fabs(hv[1]-HVnominal)>HV_NON_NOMINAL_TOLERANCE) ||
1359 (fabs(hv[2]-HVnominal)>HV_NON_NOMINAL_TOLERANCE) || (fabs(hv[3]-HVnominal)>HV_NON_NOMINAL_TOLERANCE)) ) isAffected=true;
1360 ATH_MSG_VERBOSE(" HV values " << hv[0] << " " << hv[1] << " " << hv[2] << " " << hv[3] << " "
1361 << " isDead/isAffected " << isDead << " " << isAffected);
1362
1363 float phiMin = CaloPhiRange::fix(hvMod.getPhiMin());
1364 float phiMax = CaloPhiRange::fix(hvMod.getPhiMax());
1365
1366
1367 if (isDead) { //stores it, DEAD means all hvs < threshold
1368 ATH_MSG_VERBOSE(" new dead region " << eta_min << " " << eta_max << " " << phiMin << " " << phiMax << " layer " << 8+iSampling);
1369 CaloAffectedRegionInfo current_CaloAffectedRegionInfo(eta_min,eta_max,phiMin,phiMax,8+iSampling,8+iSampling,CaloAffectedRegionInfo::HVdead);
1370 vAffected->push_back(current_CaloAffectedRegionInfo);
1371 }
1372 if (isAffected) {
1373 ATH_MSG_VERBOSE(" new affected region " << eta_min << " " << eta_max << " " << phiMin << " " << phiMax << " layer " << 8+iSampling);
1374 CaloAffectedRegionInfo current_CaloAffectedRegionInfo(eta_min,eta_max,phiMin,phiMax,8+iSampling,8+iSampling,CaloAffectedRegionInfo::HVaffected);
1375 vAffected->push_back(current_CaloAffectedRegionInfo);
1376 }
1377
1378 } //end for iSampling
1379 }//end for iPhi
1380 }//end for iSide
1381 } else {
1382 ATH_MSG_ERROR("Do not have HEC HV manager ");
1383 return StatusCode::FAILURE;
1384 }
1385 return StatusCode::SUCCESS;
1386}
1387//=========================================================================================
1389 , const LArHVIdMapping* hvCabling
1390 , const voltagePerLine_t& voltage) const { // deals with LAr HV, FCAL
1391
1392 ATH_MSG_DEBUG( " inFCAL ");
1393 const LArHVManager *manager = nullptr;
1394 if (detStore()->retrieve(manager)==StatusCode::SUCCESS) {
1395
1396 const FCALHVManager& hvManager_FCAL=manager->getFCALHVManager();
1397
1398 for (unsigned int iSide=hvManager_FCAL.beginSideIndex();iSide<hvManager_FCAL.endSideIndex();iSide++) { // loop over HV modules
1399 float eta_min=3.1,eta_max=4.9;
1400 if (iSide==0) {
1401 eta_min=-4.9;
1402 eta_max=-3.1;
1403 }
1404 for (unsigned int iSampling=hvManager_FCAL.beginSamplingIndex();iSampling<hvManager_FCAL.endSamplingIndex();iSampling++) {
1405 float HVnominal = HV_nominal("FCAL",(float)(iSampling));
1406 for (unsigned int iSector=hvManager_FCAL.beginSectorIndex(iSampling);iSector<hvManager_FCAL.endSectorIndex(iSampling);iSector++) {
1407
1408 const FCALHVModule& hvMod = hvManager_FCAL.getHVModule(iSide,iSector,iSampling);
1409 ATH_MSG_VERBOSE(" FCAL HVModule side,sampling,sector " << iSide << " " << iSampling << " "
1410 << iSector << " HV nominal " << HVnominal);
1411
1412 float dphi=CaloPhiRange::twopi()/16;
1413 if (iSampling==1) dphi=CaloPhiRange::twopi()/8.;
1414 if (iSampling==2) dphi=CaloPhiRange::twopi()/4.;
1415 float phi_min = ((float)(iSector))*dphi;
1416 phi_min = CaloPhiRange::fix(phi_min);
1417 float phi_max = CaloPhiRange::fix(dphi+phi_min);
1418
1419 ATH_MSG_VERBOSE(" eta_min,eta_max,phi_min,phi_max " << eta_min << " " << eta_max << " " << phi_min
1420 << " " << phi_max << " number of lines " << hvMod.getNumHVLines());
1421 float hv[4] = {0};
1422 for (unsigned int iLine=0;iLine<hvMod.getNumHVLines();iLine++) {
1423 const FCALHVLine& hvline = hvMod.getHVLine(iLine);
1424 unsigned int ihvline = hvline.hvLineNo(hvCabling);
1425 auto hvIt=voltage.find(ihvline);
1426 if(hvIt == voltage.end()) {
1427 ATH_MSG_WARNING("Do not have hvline: "<<ihvline<<" in LArHVData ! Assuming missing DCS data");
1428 continue;
1429 }
1430 if (iLine<4) hv[iLine]=hvIt->second.hv;
1431 }
1432 //------------------
1433 //take decisions according to all the gaps HV :
1434 bool isDead=false;
1435 if (fabs(hv[0]) < DEAD_HV_THRESHOLD && fabs(hv[1]) < DEAD_HV_THRESHOLD && fabs(hv[2]) < DEAD_HV_THRESHOLD && fabs(hv[3]) < DEAD_HV_THRESHOLD) isDead=true;
1436 bool isAffected=false;
1437 if ( !isDead && ((fabs(hv[0]-HVnominal)>HV_NON_NOMINAL_TOLERANCE) || (fabs(hv[1]-HVnominal)>HV_NON_NOMINAL_TOLERANCE) ||
1438 (fabs(hv[2]-HVnominal)>HV_NON_NOMINAL_TOLERANCE) || (fabs(hv[3]-HVnominal)>HV_NON_NOMINAL_TOLERANCE)) ) isAffected=true;
1439 ATH_MSG_VERBOSE(" HV values " << hv[0] << " " << hv[1] << " " << hv[2] << " " << hv[3] << " "
1440 << " isDead/isAffected " << isDead << " " << isAffected);
1441
1442
1443 if (isAffected) {
1444 ATH_MSG_VERBOSE(" -- store affected region ");
1445 CaloAffectedRegionInfo current_CaloAffectedRegionInfo(eta_min,eta_max,phi_min,phi_max,21+iSampling,21+iSampling,CaloAffectedRegionInfo::HVaffected);
1446 vAffected->push_back(current_CaloAffectedRegionInfo);
1447 }
1448 if (isDead) {
1449 ATH_MSG_VERBOSE(" -- store dead region ");
1450 CaloAffectedRegionInfo current_CaloAffectedRegionInfo(eta_min,eta_max,phi_min,phi_max,21+iSampling,21+iSampling,CaloAffectedRegionInfo::HVdead);
1451 vAffected->push_back(current_CaloAffectedRegionInfo);
1452 }
1453 } //end iSector
1454 } //end iSampling
1455 }// end iSide
1456 } else {
1457 ATH_MSG_ERROR("Do not have FCAL HV manager");
1458 return StatusCode::FAILURE;
1459 }
1460 return StatusCode::SUCCESS;
1461}
1462//=========================================================================================
1463StatusCode LArHVCondAlg::updateMethod(const EventContext& ctx,
1464 CaloAffectedRegionInfoVec *vAffected, const LArBadFebCont* bfCont,
1465 const LArOnOffIdMapping* cabling) const { //store informations on the missing Febs w/ range of eta, phi, layer
1466 ATH_MSG_DEBUG ( "updateMethod()" );
1467
1469 const CaloDetDescrManager* calodetdescrmgr = *caloMgrHandle;
1470
1471 for (const HWIdentifier febId : m_onlineID->feb_range()) {
1472 bool IsMissingFeb=(bfCont->status(febId).deadAll() || bfCont->status(febId).deadReadout());
1473
1474 if (IsMissingFeb) { //flag for special treatment for FEB that has non contiguous eta regions, so we have to separate them
1475 bool is_normal=0; //FEB without discontinuity
1476 bool is_additive1=0; //FEB with a discontinuity
1477
1478 int layer_min=+30,layer_max=-30;
1479 float eta_min=+30,eta_max=-30;
1480 float phi_min=+30,phi_max=-30;
1481
1482 int layer_min_additive1=+30,layer_max_additive1=-30;
1483 float eta_min_additive1=+30,eta_max_additive1=-30;
1484 float phi_min_additive1=+30,phi_max_additive1=-30;
1485
1486 int chans_per_feb = m_onlineID->channelInSlotMax(febId);
1487
1488 for (int icha=0;icha<chans_per_feb;icha++) { //loop on each channel of the relevant FEB
1489 HWIdentifier channelId=m_onlineID->channel_Id(febId,icha);
1490
1491 if (cabling->isOnlineConnected(channelId)) {
1492 Identifier offlineId=cabling->cnvToIdentifier(channelId);
1493 const CaloDetDescrElement* caloddElement=calodetdescrmgr->get_element(offlineId);
1494
1495 CaloCell_ID::CaloSample current_layer=caloddElement->getSampling(); // calo layer
1496 float current_eta=caloddElement->eta();
1497 float current_eta_low=caloddElement->eta()-0.5*caloddElement->deta();
1498 float current_eta_high=caloddElement->eta()+0.5*caloddElement->deta();
1499 float current_phi_low=caloddElement->phi()-0.5*caloddElement->dphi();
1500 float current_phi_high=caloddElement->phi()+0.5*caloddElement->dphi();
1501
1502 if (caloddElement->is_lar_em_barrel() && caloddElement->getLayer()==3 && fabs(current_eta)>0.79 && fabs(current_eta)<1.33) { //EMB, back sampling, slot 12 : special treatment : this FEB has non contiguous eta regions, so we have to separate them
1503 is_additive1=1; //in order to add it to the summary only if it happens
1504
1505 if (current_layer<layer_min_additive1)
1506 layer_min_additive1=current_layer;
1507 if (current_layer>layer_max_additive1)
1508 layer_max_additive1=current_layer;
1509
1510 if (current_eta_low<eta_min_additive1)
1511 eta_min_additive1=current_eta_low;
1512 if (current_eta_high>eta_max_additive1)
1513 eta_max_additive1=current_eta_high;
1514
1515 extendPhiRegion(current_phi_low,phi_min_additive1,phi_max_additive1);
1516 extendPhiRegion(current_phi_high,phi_min_additive1,phi_max_additive1);
1517
1518 }
1519 else { //normal case
1520 is_normal=1; // normal case
1521
1522 if (current_layer<layer_min)
1523 layer_min=current_layer;
1524 if (current_layer>layer_max)
1525 layer_max=current_layer;
1526
1527 if (current_eta_low<eta_min)
1528 eta_min=current_eta_low;
1529 if (current_eta_high>eta_max)
1530 eta_max=current_eta_high;
1531
1532 extendPhiRegion(current_phi_low,phi_min,phi_max);
1533 extendPhiRegion(current_phi_high,phi_min,phi_max);
1534
1535 }
1536 } //end of isOnlineConnected()
1537 } // end of loop on channels
1538
1539 if (is_normal) {
1540 CaloAffectedRegionInfo current_CaloAffectedRegionInfo(eta_min,eta_max,phi_min,phi_max,layer_min,layer_max,CaloAffectedRegionInfo::missingReadout);
1541 vAffected->push_back(current_CaloAffectedRegionInfo);
1542 }
1543
1544 if (is_additive1) {
1545 CaloAffectedRegionInfo current_additive1_CaloAffectedRegionInfo(eta_min_additive1,eta_max_additive1,phi_min_additive1,phi_max_additive1,layer_min_additive1,layer_max_additive1,CaloAffectedRegionInfo::missingReadout);
1546 vAffected->push_back(current_additive1_CaloAffectedRegionInfo);
1547 }
1548 } // end of isMissingFeb
1549 } // end of loop on Febs
1550 return StatusCode::SUCCESS;
1551}
1552//====================================================================================
1553float LArHVCondAlg::HV_nominal(const char *identification,const float myparameter) const
1554{
1555 if (strcmp(identification,"EMBPS")==0)
1556 return 1200.;
1557 else if (strcmp(identification,"EMECPS")==0)
1558 return 1600.;
1559 else if (strcmp(identification,"EMB")==0)
1560 return 2000.;
1561 else if (strcmp(identification,"EMEC")==0) {
1562 if ( fabs(myparameter)<1.5 )
1563 return 2500.;
1564 else if (fabs(myparameter)<1.6)
1565 return 2300.;
1566 else if (fabs(myparameter)<1.8 )
1567 return 2100.;
1568 else if ( fabs(myparameter) < 2.0 )
1569 return 1700.;
1570 else if ( fabs(myparameter) < 2.1 )
1571 return 1500.;
1572 else if ( fabs(myparameter) < 2.3 )
1573 return 1250.;
1574 else if ( fabs(myparameter) < 2.5 )
1575 return 1000.;
1576 else if ( fabs(myparameter) < 2.8 )
1577 return 2300.;
1578 else return 1800.;
1579 }
1580 else if (strcmp(identification,"HEC")==0) {
1581 return 1800.;
1582 }
1583 else if (strcmp(identification,"FCAL")==0) {
1584 if (myparameter<0.5)
1585 return 250.;
1586 else if (myparameter<1.5)
1587 return 375.;
1588 else if (myparameter<2.5)
1589 return 500.;
1590 }
1591
1592 return -1;
1593}
1594//=========================================================================================
1595
1596void LArHVCondAlg::extendPhiRegion(float phi, float & phi_min, float & phi_max) const {
1597
1598 static const float epsilon=1e-4;
1599
1601
1602 if (phi_min>10. || phi_max<-10.) {
1603 phi_min = CaloPhiRange::fix(phi-epsilon);
1604 phi_max = CaloPhiRange::fix(phi+epsilon);
1605 return;
1606 }
1607
1608 bool isInRegion=false;
1609 if (phi_min<phi_max) {
1610 if (phi>phi_min && phi<phi_max) isInRegion=true;
1611 }
1612 else {
1613 if (phi>phi_min || phi<phi_max) isInRegion=true;
1614 }
1615 if (isInRegion) return;
1616
1617 float dphi1 = CaloPhiRange::diff(phi,phi_min);
1618 float dphi2 = CaloPhiRange::diff(phi,phi_max);
1619 if (fabs(dphi1)<fabs(dphi2) )
1620 phi_min=phi;
1621 else
1622 phi_max=phi;
1623
1624 return;
1625
1626}
Scalar phi() const
phi method
#define endmsg
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
std::vector< CaloAffectedRegionInfo > CaloAffectedRegionInfoVec
Definition of CaloDetDescrManager.
Calo Subsystem specific Detector Elements + Dummy element for testing.
CaloPhiRange class declaration.
This file defines the class for a collection of AttributeLists where each one is associated with a ch...
LArBadXCont< LArBadFeb > LArBadFebCont
#define DEAD_HV_THRESHOLD
#define MAX_LAR_CELLS
#define HV_NON_NOMINAL_TOLERANCE
static Double_t ss
An AttributeList represents a logical row of attributes in a metadata table.
size_t size() const
Number of registered mappings.
static const Attributes_t empty
const ServiceHandle< StoreGateSvc > & detStore() const
Header file for AthHistogramAlgorithm.
An AttributeList represents a logical row of attributes in a metadata table.
CaloSampling::CaloSample CaloSample
Definition CaloCell_ID.h:53
This class groups all DetDescr information related to a CaloCell.
virtual int getLayer() const
cell layer
CaloCell_ID::CaloSample getSampling() const
cell sampling
bool is_lar_em_barrel() const
cell belongs to EM barrel
const CaloDetDescrElement * get_element(const Identifier &cellId) const
get element by its identifier
This class provides the client interface for accessing the detector description information common to...
static double twopi()
static double fix(double phi)
static double diff(double phi1, double phi2)
simple phi1 - phi2 calculation, but result is fixed to respect range.
This class is a collection of AttributeLists where each one is associated with a channel number.
const_iterator end() const
const_iterator begin() const
Access to Chan/AttributeList pairs via iterators.
ChanAttrListMap::const_iterator const_iterator
LAr EMB Detector Element.
EMBCellConstLink getEMBCell() const
EMB Cell description from LArReadoutGeometry.
const EMBHVModule & getModule() const
int hvLineNo(int iGap, const LArHVIdMapping *hvIdMapping) const
double getPhi() const
unsigned int getElectrodeIndex() const
This class provides direct access to information on the HV electrodes within the barrels.
unsigned int beginPhiIndex() const
unsigned int endEtaIndex() const
static unsigned int endSectorIndex()
unsigned int beginEtaIndex() const
static unsigned int beginSectorIndex()
const EMBHVModule & getHVModule(unsigned int iSide, unsigned int iEta, unsigned int iPhi, unsigned int iSector) const
unsigned int endPhiIndex() const
static unsigned int beginSideIndex()
static unsigned int endSideIndex()
Describes one HV Module within the EMB.
Definition EMBHVModule.h:22
const EMBHVElectrode & getElectrode(unsigned int iElectrode) const
double getEtaMin() const
unsigned int getPhiIndex() const
unsigned int getSideIndex() const
double getEtaMax() const
unsigned int getEtaIndex() const
This class provides direct access to information on the HV electrodes within the barrels.
const EMBPresamplerHVModule & getHVModule(unsigned int iSide, unsigned int iEta, unsigned int iPhi) const
static unsigned int beginSideIndex()
unsigned int beginPhiIndex() const
static unsigned int endSideIndex()
unsigned int beginEtaIndex() const
Describes one HV Module within the EMB Presampler.
unsigned int getSideIndex() const
unsigned int getEtaIndex() const
int hvLineNo(int iGap, const LArHVIdMapping *hvIdMapping) const
LAr EMEC Detector Element.
EMECCellConstLink getEMECCell() const
EMEC Cell description from LArReadoutGeometry.
int hvLineNo(int iGap, const LArHVIdMapping *hvIdMapping) const
double getPhi() const
unsigned int getElectrodeIndex() const
const EMECHVModule & getModule() const
This class provides direct access to information on the HV electrodes within the EMEC.
unsigned int beginEtaIndex() 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()
static unsigned int endSideIndex()
unsigned int endEtaIndex() const
unsigned int endSectorIndex() const
unsigned int beginPhiIndex() const
double getEtaMax() const
const EMECHVElectrode & getElectrode(unsigned int iElectrode) const
unsigned int getNumElectrodes() const
unsigned int getSideIndex() const
unsigned int getSectorIndex() const
double getEtaMin() const
unsigned int getPhiIndex() const
unsigned int getEtaIndex() const
This class provides direct access to information on the HV electrodes within the EMEC.
const EMECPresamplerHVModule & getHVModule(unsigned int iSide, unsigned int iPhi) const
static unsigned int beginSideIndex()
Describes one HV Module within the EMEc Presampler.
unsigned int getSideIndex() const
int hvLineNo(int iGap, const LArHVIdMapping *hvIdMapping) const
LAr FCAL Detector Element.
const FCALTile * getFCALTile() const
FCAL Tile description from LArReadoutGeometry.
This class provides direct access to information on the HV electrodes within the barrels.
static unsigned int beginSideIndex()
static unsigned int endSamplingIndex()
static unsigned int endSideIndex()
static unsigned int beginSectorIndex(unsigned int iSampling)
static unsigned int beginSamplingIndex()
const FCALHVModule & getHVModule(unsigned int iSide, unsigned int iSector, unsigned int iSampling) const
static unsigned int endSectorIndex(unsigned int iSampling)
Describes one HV Module within the FCAL.
const FCALHVLine & getHVLine(unsigned int iLine) const
unsigned int getSamplingIndex() const
unsigned int getSideIndex() const
unsigned int getSectorIndex() const
static unsigned int getNumHVLines()
A tile of the forward calorimeter readout geometry.
Definition FCALTile.h:27
LAr HEC Detector Element.
HECCellConstLink getHECCell() const
HEC Cell description from LArReadoutGeometry.
This class provides direct access to information on the HV electrodes within the barrels.
static unsigned int beginPhiIndex()
static unsigned int endSamplingIndex()
const HECHVModule & getHVModule(unsigned int iSide, unsigned int iPhi, unsigned int iSampling) const
static unsigned int endSideIndex()
static unsigned int beginSideIndex()
static unsigned int beginSamplingIndex()
static unsigned int endPhiIndex()
Describes one HV Module within the HEC.
Definition HECHVModule.h:23
const HECHVSubgap & getSubgap(unsigned int iElectrode) const
unsigned int getSideIndex() const
unsigned int getSamplingIndex() const
double getPhiMin() const
static unsigned int getNumSubgaps()
double getPhiMax() const
const HECHVModule & getModule() const
unsigned int getSubgapIndex() const
int hvLineNo(const LArHVIdMapping *hvIdMapping) const
virtual const float & HVScaleCorr(const HWIdentifier &id) const =0
static EventIDRange infiniteMixed()
Produces an mixed EventIDRange that is infinite in Time and RunLumi.
This is a "hash" representation of an Identifier.
bool deadReadout() const
FEB is not sending readout data, but the L1 trigger path is working.
Definition LArBadFeb.h:33
LArBC_t status(const HWIdentifier channel) const
Query the status of a particular channel or FEB This is the main client access method.
void extendPhiRegion(float phi, float &phi_min, float &phi_max) const
Gaudi::Property< bool > m_doHV
StatusCode execute(const EventContext &ctx) const override
const LArHVLineID * m_hvLineID
SG::ReadCondHandleKey< ILArHVScaleCorr > m_onlineHVScaleCorrKey
const CaloCell_ID * m_calocellID
SG::ReadCondHandleKey< AthenaAttributeList > m_hvRKey
SG::ReadCondHandleKey< CaloDetDescrManager > m_caloMgrKey
SG::ReadCondHandleKey< LArOnOffIdMapping > m_cablingKey
void addHV(voltageCell_t &v, float hv, float weight) const
Add voltage/weight for a sub-gap of a cell.
Gaudi::Property< bool > m_useCurrentFCAL1
Gaudi::Property< bool > m_useCurrentEMB
SG::ReadCondHandleKey< LArHVPathology > m_pathologiesKey
Gaudi::Property< std::vector< std::string > > m_fixHVCorrStrings
StatusCode searchNonNominalHV_EMEC_INNER(CaloAffectedRegionInfoVec *vAffected, const LArHVIdMapping *hvCabling, const voltagePerLine_t &voltage) const
StatusCode fixVoltageAndCurrent()
StatusCode searchNonNominalHV_HEC(CaloAffectedRegionInfoVec *vAffected, const LArHVIdMapping *hvCabling, const voltagePerLine_t &voltage) const
StatusCode searchNonNominalHV_FCAL(CaloAffectedRegionInfoVec *vAffected, const LArHVIdMapping *hvCabling, const voltagePerLine_t &voltage) const
SG::ReadCondHandleKeyArray< CondAttrListCollection > m_DCSFolderKeys
std::unordered_map< unsigned, DCS_t > voltagePerLine_t
SG::WriteCondHandleKey< LArHVCorr > m_outputHVScaleFullCorrKey
std::unordered_map< unsigned, float > m_fixCurrentPerLine
SG::WriteCondHandleKey< CaloAffectedRegionInfoVec > m_affectedKey
std::vector< unsigned int > getElecList(const Identifier &id, const LArHVPathology &pathologies) const
StatusCode updateMethod(const EventContext &ctx, CaloAffectedRegionInfoVec *vAffected, const LArBadFebCont *bfCont, const LArOnOffIdMapping *cabling) const
std::unique_ptr< const LArHVScaleCorrTool > m_scaleTool
StatusCode searchNonNominalHV_EMB(CaloAffectedRegionInfoVec *vAffected, const LArHVIdMapping *hvCabling, const voltagePerLine_t &voltage) const
StatusCode makeAffectedRegionInfo(const EventContext &ctx, voltagePerLine_t &voltagePerLine) const
LArHVScaleCorrTool::voltageCell_t voltageCell_t
const LArElectrodeID * m_electrodeID
StatusCode getVoltagePerLine(const EventContext &ctx, voltagePerLine_t &voltagePerLine, const addDepFcn_t &addDep) const
std::vector< voltageCell_t > voltagePerCell_t
const LArHEC_ID * m_larhec_id
SG::ReadCondHandleKey< LArBadFebCont > m_BFKey
std::unordered_map< unsigned, float > m_fixVoltagePerLine
Gaudi::Property< std::vector< std::string > > m_fixHVStrings
std::atomic< unsigned > m_nPathologies
SG::WriteCondHandleKey< LArHVCorr > m_outputHVScaleResidCorrKey
StatusCode makeHVScaleCorr(const EventContext &ctx, voltagePerLine_t &voltagePerLine) const
virtual StatusCode initialize() override
std::function< void(SG::ReadCondHandle< CondAttrListCollection > &dep, const char *debugDescr)> addDepFcn_t
const LArOnlineID * m_onlineID
Gaudi::Property< bool > m_doRProp
StatusCode fillPathAndCellHV(const CaloDetDescrManager *calodetdescrmgr, voltagePerCell_t &hvdata, const LArHVIdMapping *hvCabling, const voltagePerLine_t &voltage, const LArHVPathology &pathologies, pathVec &hasPathologyEM, pathVec &hasPathologyHEC, pathVec &hasPathologyFCAL, const float *rValues) const
Read the voltage per HV line and store it in structure per readout-cell (resolve the many-HV-lines-to...
Gaudi::Property< bool > m_doAffected
StatusCode searchNonNominalHV_EMEC_OUTER(CaloAffectedRegionInfoVec *vAffected, const LArHVIdMapping *hvCabling, const voltagePerLine_t &voltage) const
const LArEM_ID * m_larem_id
Gaudi::Property< bool > m_doAffectedHV
Gaudi::Property< std::vector< std::string > > m_fixCurrentStrings
StatusCode dcs2LineVoltage(voltagePerLine_t &result, const std::vector< const CondAttrListCollection * > &fldvec) const
Read HV from DCS, store them in internal data structure per HV-line (Step 1).
const LArFCAL_ID * m_larfcal_id
SG::ReadCondHandleKey< LArHVIdMapping > m_hvMappingKey
Gaudi::Property< bool > m_useCurrentOthers
std::vector< std::vector< unsigned short > > pathVec
Internal structure for HV pathologies.
float HV_nominal(const char *identification, const float eta) const
int getCellModule(const Identifier &offId) const
returns the Module of a given offId
This class provides access to the High Voltage throughout the LAr.
static const unsigned short MaskCurr
static const unsigned short SetHVMask
static const unsigned short MaskHV
const std::vector< LArHVPathologiesDb::LArHVElectPathologyDb > & getPathology() const
const std::string & key() const
const EventIDRange & getRange()
const std::string & key() const
void addDependency(const EventIDRange &range)
const EventIDRange & getRange() const
StatusCode record(const EventIDRange &range, T *t)
record handle, with explicit range DEPRECATED
Definition index.py:1