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