ATLAS Offline Software
LArCelldeadOTXTool.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 #include "LArCelldeadOTXTool.h"
6 
7 #include "CaloEvent/CaloCell.h"
12 
14 
16  ATH_CHECK(m_MFKey.initialize());
17  ATH_CHECK(m_badSCKey.initialize());
21 
22  ATH_CHECK(detStore()->retrieve(m_onlineID, "LArOnlineID"));
23  ATH_CHECK(detStore()->retrieve(m_calo_id, "CaloCell_ID"));
24 
25  ATH_CHECK(m_scidtool.retrieve());
26 
27  if (m_testMode) {
29  "Test mode activated with additional debug output. Makes only sense if we try to patch a FEB that is actually there, so we have a reference");
30  }
31 
32  return StatusCode::SUCCESS;
33 }
34 
35 StatusCode LArCelldeadOTXTool::process(CaloCellContainer* cellCollection, const EventContext& ctx) const {
36 
37  ATH_MSG_VERBOSE(" in process...");
38  if (!cellCollection) {
39  ATH_MSG_ERROR("Cell Correction tool receives invalid cell Collection");
40  return StatusCode::FAILURE;
41  }
42 
43  StatusCode sc = StatusCode::SUCCESS;
44  std::call_once(m_onceFlag, &LArCelldeadOTXTool::buildMap, this, ctx, m_scToDead, sc);
45 
46  if (sc.isFailure()) {
47  ATH_MSG_ERROR("Call to LArCelldeadOTXTool::buidMap returned an error");
48  return StatusCode::FAILURE;
49  }
50 
51  if (m_scToDead.empty()) {
52  return StatusCode::SUCCESS; // No dead FEBs, do nothing
53  }
54 
55  // get SuperCellContainer
57  if (!scHdl.isValid()) {
58  ATH_MSG_WARNING("Do not have SuperCell container no patching !!!!");
59  return StatusCode::SUCCESS;
60  }
61 
62  const unsigned int bcid = ctx.eventID().bunch_crossing_id();
63 
64  // get the SC, container is unordered, so have to loop
65  const LArRawSCContainer* scells = scHdl.cptr();
66  for (const auto* sc : *scells) {
67  if (!sc)
68  continue;
69  const HWIdentifier scHwid = sc->hardwareID();
70  auto itr = m_scToDead.find(scHwid);
71  if (itr == m_scToDead.end())
72  continue; // This SC is not connected to any deadFEB cell
73 
74  const std::vector<unsigned short>& bcids = sc->bcids();
75  const std::vector<int>& energies = sc->energies();
76  const std::vector<bool>& satur = sc->satur();
77 
78  // Look for bcid:
79  float scEne = 0;
80  const size_t nBCIDs = bcids.size();
81  size_t i = 0;
82  for (i = 0; i < nBCIDs && bcids[i] != bcid; i++)
83  ;
84 
85  if (ATH_LIKELY(!satur[i]))
86  scEne = energies[i];
87  if (scEne < m_scCut) {
88  ATH_MSG_VERBOSE("SC value " << scEne << " below threshold, ignoring");
89  continue;
90  }
91  float cellESum = 0;
92  float patchEneSum = 0;
93  for (const auto& [h, convFactor] : itr->second) { // Loop over all deadFEB cells connected to this SC
94  CaloCell* cell = cellCollection->findCell(h);
95  if (cell) {
96  const float patchEne = scEne * convFactor; // Convert ET (coming from LATOMEs) into Energy
97  if (m_testMode) {
98  cellESum += cell->energy();
99  patchEneSum += patchEne;
100  }
101  ATH_MSG_DEBUG("Cell id 0x" << std::hex << cell->ID().get_identifier32().get_compact() << " Replacing energy " << cell->energy() << " " << patchEne
102  << ", SCene=" << scEne);
103  cell->setEnergy(patchEne);
104  cell->setProvenance(cell->provenance() | LArProv::PATCHED);
105  } // end if cell obj found
106  } // end loop over all deadFEB cells connected to this SC
107  if (m_testMode) {
108  const float ratio = patchEneSum != 0 ? cellESum / patchEneSum : 0;
109  ATH_MSG_DEBUG("ESums=" << cellESum << "/" << patchEneSum << "=" << ratio);
110  std::scoped_lock l(m_mtx);
111  auto& entry = m_testMap[scEne];
112  entry.first += ratio;
113  entry.second++;
114  } // end if testMode
115  } // End loop over SuperCell container
116 
117  return StatusCode::SUCCESS;
118 }
119 
120 void LArCelldeadOTXTool::buildMap(const EventContext& ctx, scToDeadCellMap_t& scToHwidMap, StatusCode& sc) const {
121  scToHwidMap.clear(); // Just to be sure ...
122 
123  sc = StatusCode::FAILURE;
124 
126  if (!cablingHdl.isValid()) {
127  ATH_MSG_ERROR("Do not have Onl-Ofl cabling map !!!!");
128  return;
129  }
130  const LArOnOffIdMapping* oflCabling = cablingHdl.cptr();
131 
133  if (!cablingSCHdl.isValid()) {
134  ATH_MSG_ERROR("Do not have Onl-Ofl cabling map for SuperCells !!!!");
135  return;
136  }
137 
138  const LArOnOffIdMapping* scCabling = cablingSCHdl.cptr();
139 
141  if (!mfHdl.isValid()) {
142  ATH_MSG_ERROR("Do not have Missing FEBs container !!!!");
143  return;
144  }
145 
147  if (!caloMgrHandle.isValid()) {
148  ATH_MSG_ERROR("Do not have CaloDetDescManager !!!");
149  return;
150  }
151 
152  const CaloDetDescrManager* caloDDM = *caloMgrHandle;
153 
155  if (!bcSCHdl.isValid()) {
156  ATH_MSG_ERROR("Do not have BadSCContainer !!!!");
157  return;
158  }
159  const LArBadChannelCont* bcSCCont = *bcSCHdl;
160 
161  const auto& badFebs = mfHdl->fullCont();
162 
163  unsigned nDeadFebs = 0;
164  for (const auto& idBF : badFebs) {
165  if (idBF.second.deadReadout()) {
166  ++nDeadFebs;
167  const HWIdentifier febid(idBF.first);
168  ATH_MSG_INFO("FEB " << m_onlineID->channel_name(febid) << " labelled as dead");
169  const unsigned nChans = m_onlineID->channelInSlotMax(febid);
170  for (unsigned ch = 0; ch < nChans; ++ch) {
171  const HWIdentifier chid = m_onlineID->channel_Id(febid, ch);
172  const Identifier id = oflCabling->cnvToIdentifier(chid);
173  const IdentifierHash hashId = m_calo_id->calo_cell_hash(id);
174  const Identifier scID = m_scidtool->offlineToSuperCellID(id);
175  const HWIdentifier scHwid = scCabling->createSignalChannelID(scID);
176  if (!bcSCCont->status(scHwid).good()) {
177  ATH_MSG_DEBUG("SuperCell with id 0x" << std::hex << scHwid.get_identifier32().get_compact() << std::dec
178  << " is ignored b/c of it's bad-channel word. Connected to deadFEB channel " << m_onlineID->channel_name(chid));
179  continue;
180  }
181  const unsigned nCell = (m_scidtool->superCellToOfflineID(scID)).size();
182  const CaloDetDescrElement* dde = caloDDM->get_element(hashId);
183  if (ATH_UNLIKELY(!dde)) {
184  ATH_MSG_ERROR("No DetDescElement for cell hash" << hashId);
185  return;
186  }
187  const float convFactor = 12.5 * (1.0 / nCell) * (1.0 / dde->sinTh());
188  // 12.5: Convert SC ADC to MeV (Et), et ->e, scale by the number of regular cells connected to this super-cell
189  scToHwidMap[scHwid].emplace_back(hashId, convFactor);
190  } // end loop over channels of one dead FEB
191  } // end if feb is deadAll
192  } // end loop over dead febs
193 
194  // bit of log-output ...
195  if (msgLvl(MSG::DEBUG)) {
196  ATH_MSG_INFO("Dead Febs for this run:" << nDeadFebs);
197  for (const auto& p : scToHwidMap) {
198  ATH_MSG_DEBUG(" SuperCell with id 0x" << std::hex << p.first.get_identifier32().get_compact() << std::dec << " connected to " << p.second.size()
199  << " deadFEB channels.");
200  for (const auto& [h, convFactor] : p.second) {
201  const HWIdentifier hwid = cablingHdl->createSignalChannelIDFromHash(h);
202  ATH_MSG_DEBUG(" " << m_onlineID->channel_name(hwid) << " " << convFactor);
203  }
204  }
205  }
206  sc = StatusCode::SUCCESS;
207  return;
208 }
209 
211  if (m_testMode) {
212  ATH_MSG_INFO("Test mode for cell-patching:");
213  std::vector<std::pair<float, float> > avgList;
214  for (auto& [scEne, entry] : m_testMap) {
215  avgList.emplace_back(scEne, entry.first / entry.second);
216  }
217  auto ordering = [](const std::pair<float, float>& a, std::pair<float, float>& b) { return (a.first < b.first); };
218  std::sort(avgList.begin(), avgList.end(), ordering);
219  for (auto& p : avgList) {
220  ATH_MSG_INFO("SCEne=" << p.first << "Avg patching ratio=" << p.second);
221  }
222  }
223  return StatusCode::SUCCESS;
224 }
python.PyKernel.retrieve
def retrieve(aClass, aKey=None)
Definition: PyKernel.py:110
LArOnOffIdMapping::createSignalChannelIDFromHash
HWIdentifier createSignalChannelIDFromHash(const IdentifierHash &id_hash) const
create a HWIdentifier from an Identifier (from hash) (inline)
Definition: LArOnOffIdMapping.h:104
LArCelldeadOTXTool::m_scCut
Gaudi::Property< int > m_scCut
Definition: LArCelldeadOTXTool.h:41
sendEI_SPB.ch
ch
Definition: sendEI_SPB.py:35
CaloCell_Base_ID::calo_cell_hash
IdentifierHash calo_cell_hash(const Identifier cellId) const
create hash id from 'global' cell id
ReadCellNoiseFromCool.cell
cell
Definition: ReadCellNoiseFromCool.py:53
LArCelldeadOTXTool::m_MFKey
SG::ReadCondHandleKey< LArBadFebCont > m_MFKey
Definition: LArCelldeadOTXTool.h:35
SG::ReadCondHandle
Definition: ReadCondHandle.h:44
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
SG::ReadHandle::cptr
const_pointer_type cptr()
Dereference the pointer.
LArCelldeadOTXTool::buildMap
void buildMap(const EventContext &ctx, scToDeadCellMap_t &map, StatusCode &sc) const
Definition: LArCelldeadOTXTool.cxx:120
SG::ReadHandle
Definition: StoreGate/StoreGate/ReadHandle.h:70
LArRawSCContainer
Container class for LArRawSC.
Definition: LArRawSCContainer.h:17
LArBadXCont
Conditions-Data class holding LAr Bad Channel or Bad Feb information.
Definition: LArBadChannelCont.h:28
CaloDetDescrElement
This class groups all DetDescr information related to a CaloCell. Provides a generic interface for al...
Definition: Calorimeter/CaloDetDescr/CaloDetDescr/CaloDetDescrElement.h:66
CaloDetDescrManager_Base::get_element
const CaloDetDescrElement * get_element(const Identifier &cellId) const
get element by its identifier
Definition: CaloDetDescrManager.cxx:159
LArCelldeadOTXTool::m_badSCKey
SG::ReadCondHandleKey< LArBadChannelCont > m_badSCKey
Definition: LArCelldeadOTXTool.h:36
SG::ReadCondHandle::isValid
bool isValid()
Definition: ReadCondHandle.h:206
Identifier::get_identifier32
Identifier32 get_identifier32() const
Get the 32-bit version Identifier, will be invalid if >32 bits needed.
CaloCell.h
UploadAMITag.l
list l
Definition: UploadAMITag.larcaf.py:158
ATH_UNLIKELY
#define ATH_UNLIKELY(x)
Definition: AthUnlikelyMacros.h:17
LArCelldeadOTXTool::process
virtual StatusCode process(CaloCellContainer *cellCollection, const EventContext &ctx) const override final
Definition: LArCelldeadOTXTool.cxx:35
LArCelldeadOTXTool::finalize
virtual StatusCode finalize() override final
Definition: LArCelldeadOTXTool.cxx:210
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
HWIdentifier
Definition: HWIdentifier.h:13
LArBadXCont::status
LArBC_t status(const HWIdentifier channel) const
Query the status of a particular channel or FEB This is the main client access method.
Identifier32::get_compact
value_type get_compact() const
Get the compact id.
Definition: Identifier32.h:44
AthenaPoolTestRead.sc
sc
Definition: AthenaPoolTestRead.py:27
CaloCell_ID.h
python.setupRTTAlg.size
int size
Definition: setupRTTAlg.py:39
LArCelldeadOTXTool::m_SCKey
SG::ReadHandleKey< LArRawSCContainer > m_SCKey
Definition: LArCelldeadOTXTool.h:34
LArBadXCont::fullCont
const BadChanVec & fullCont() const
Definition: LArBadChannelCont.h:84
python.utils.AtlRunQueryDQUtils.p
p
Definition: AtlRunQueryDQUtils.py:210
LArCelldeadOTXTool.h
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
LArCelldeadOTXTool::m_cablingKey
SG::ReadCondHandleKey< LArOnOffIdMapping > m_cablingKey
Definition: LArCelldeadOTXTool.h:37
LArProv::PATCHED
@ PATCHED
Definition: LArProvenance.h:21
LArCelldeadOTXTool::m_scidtool
ToolHandle< ICaloSuperCellIDTool > m_scidtool
Definition: LArCelldeadOTXTool.h:45
lumiFormat.i
int i
Definition: lumiFormat.py:85
LArOnlineID_Base::channelInSlotMax
int channelInSlotMax(const HWIdentifier Id) const
Return the Maximum channel number of a given feb slot.
Definition: LArOnlineID_Base.cxx:287
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
LArOnlineID_Base::channel_Id
HWIdentifier channel_Id(int barrel_ec, int pos_neg, int feedthrough, int slot, int channel) const
create channel identifier from fields
Definition: LArOnlineID_Base.cxx:1565
LArCelldeadOTXTool::m_onlineID
const LArOnlineID * m_onlineID
Definition: LArCelldeadOTXTool.h:43
LArCelldeadOTXTool::m_testMode
Gaudi::Property< bool > m_testMode
Definition: LArCelldeadOTXTool.h:42
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
LArCelldeadOTXTool::m_cablingSCKey
SG::ReadCondHandleKey< LArOnOffIdMapping > m_cablingSCKey
Definition: LArCelldeadOTXTool.h:38
SG::VarHandleKey::initialize
StatusCode initialize(bool used=true)
If this object is used as a property, then this should be called during the initialize phase.
Definition: AthToolSupport/AsgDataHandles/Root/VarHandleKey.cxx:103
LArOnOffIdMapping::createSignalChannelID
HWIdentifier createSignalChannelID(const Identifier &id) const
create a HWIdentifier from an Identifier (not inline)
Definition: LArOnOffIdMapping.h:126
SG::ReadHandle::isValid
virtual bool isValid() override final
Can the handle be successfully dereferenced?
CaloCellContainer::findCell
const CaloCell * findCell(const IdentifierHash theHash) const
fast find method given identifier hash.
Definition: CaloCellContainer.cxx:345
GetAllXsec.entry
list entry
Definition: GetAllXsec.py:132
python.PyKernel.detStore
detStore
Definition: PyKernel.py:41
plotBeamSpotMon.b
b
Definition: plotBeamSpotMon.py:77
LArCelldeadOTXTool::m_caloMgrKey
SG::ReadCondHandleKey< CaloDetDescrManager > m_caloMgrKey
Definition: LArCelldeadOTXTool.h:39
SG::CondHandleKey::initialize
StatusCode initialize(bool used=true)
xAOD::bcid
setEventNumber setTimeStamp bcid
Definition: EventInfo_v1.cxx:133
CaloCellContainer.h
CaloCellContainer
Container class for CaloCell.
Definition: CaloCellContainer.h:55
ATH_LIKELY
#define ATH_LIKELY(x)
Definition: AthUnlikelyMacros.h:16
LArCelldeadOTXTool::m_mtx
std::mutex m_mtx
Definition: LArCelldeadOTXTool.h:55
a
TList * a
Definition: liststreamerinfos.cxx:10
h
python.compareTCTs.ratio
ratio
Definition: compareTCTs.py:295
CaloDetDescrManager
This class provides the client interface for accessing the detector description information common to...
Definition: CaloDetDescrManager.h:473
CaloCell
Data object for each calorimeter readout cell.
Definition: CaloCell.h:57
LArOnOffIdMapping::cnvToIdentifier
Identifier cnvToIdentifier(const HWIdentifier &sid) const
create an Identifier from a HWIdentifier (inline)
Definition: LArOnOffIdMapping.h:116
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
DEBUG
#define DEBUG
Definition: page_access.h:11
LArCelldeadOTXTool::m_calo_id
const CaloCell_ID * m_calo_id
Definition: LArCelldeadOTXTool.h:44
LArProvenance.h
CaloDetDescrElement::sinTh
float sinTh() const
for algorithm working in transverse Energy
Definition: Calorimeter/CaloDetDescr/CaloDetDescr/CaloDetDescrElement.h:383
IdentifierHash
This is a "hash" representation of an Identifier. This encodes a 32 bit index which can be used to lo...
Definition: IdentifierHash.h:25
LArOnlineID_Base::channel_name
std::string channel_name(const HWIdentifier id) const
Return a string corresponding to a feedthrough name given an identifier.
Definition: LArOnlineID_Base.cxx:219
hist_file_dump.ordering
ordering
Definition: hist_file_dump.py:80
LArCelldeadOTXTool::initialize
virtual StatusCode initialize() override final
Definition: LArCelldeadOTXTool.cxx:13
LArOnlineID.h
LArOnOffIdMapping
Definition: LArOnOffIdMapping.h:20
SG::ReadCondHandle::cptr
const_pointer_type cptr()
Definition: ReadCondHandle.h:67
LArCelldeadOTXTool::scToDeadCellMap_t
std::map< HWIdentifier, std::vector< std::pair< IdentifierHash, float > > > scToDeadCellMap_t
Definition: LArCelldeadOTXTool.h:47
Identifier
Definition: IdentifierFieldParser.cxx:14