ATLAS Offline Software
CaloNoiseCondAlg.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 #include "CaloNoiseCondAlg.h"
6 #include <forward_list>
9 
11 
12  unsigned nFolders=0;
13  if (!m_caloNoiseKey.key().empty()) {
15  nFolders++;
16  }
17  if (!m_larNoiseKey.key().empty()) {
19  nFolders++;
20  }
21  if (!m_tileNoiseKey.key().empty()) {
23  nFolders++;
24  }
25 
26  if (nFolders==0) {
27  ATH_MSG_ERROR("No noise DB folder found, LArNoiseFolder, TileNoiseFolder and CaloNoiseFolder properties are all empty!");
28  return StatusCode::FAILURE;
29  }
30 
31  const std::string& noiseKey=m_outputKey.key();
32  if(noiseKey=="electronicNoise") {
33  ATH_MSG_INFO("Will compute electronic noise");
35  }
36  else if (noiseKey == "electronicNoiseNoHV") {
37  ATH_MSG_INFO("Will compute electronic noise without HV corrections");
39  if (m_useHVCorr) {
40  ATH_MSG_WARNING("Inconsistent configuration, set useHVCorr=False");
41  m_useHVCorr=false;
42  }
43  }
44  else if (noiseKey == "pileupNoise") {
45  ATH_MSG_INFO("Will compute pileup noise");
47  if (m_useHVCorr) {
48  ATH_MSG_INFO("Disabling HV correction, only pile-up noise");
49  }
50  m_useHVCorr=false;
51  } else if (noiseKey == "totalNoise") {
53  ATH_MSG_INFO("Will compute total (electronic + pileup) noise");
54  } else {
55  ATH_MSG_ERROR("Unexpected noise key given: " << noiseKey << ". Expeced 'electronicNoise' or 'pileupNoise' or 'totalNoise'.");
56  return StatusCode::FAILURE;
57  }
58 
60 
61  const bool doLumiFolderInit = m_lumi0 < 0 && m_noiseType!=CaloNoise::ELEC;
62  if (m_lumiFolderKey.initialize(doLumiFolderInit).isFailure()) {
63  ATH_MSG_ERROR("Luminosity set to < 0 but failed to initialize LumiFolder");
64  }
65 
66 
68 
69  ATH_CHECK(detStore()->retrieve(m_caloCellID,"CaloCell_ID"));
70 
71  m_hashRange=std::make_unique<CaloNoiseHashRanges>(m_caloCellID);
72 
73  return StatusCode::SUCCESS;
74 }
75 
76 
77 StatusCode CaloNoiseCondAlg::execute(const EventContext& ctx) const {
78 
79  //Set up write handle
81  if (writeHandle.isValid()) {
82  ATH_MSG_DEBUG("Found valid write handle");
83  return StatusCode::SUCCESS;
84  }
85 
86  //Obtain AttrListsCollections for all possible folders (LAr,Tile,Calo)
87  std::vector<const CondAttrListCollection*> attrListNoise;
88 
89  if (!m_larNoiseKey.key().empty()) {
90  //Separete LAr/Tile folder
92  attrListNoise.push_back(*larNoiseHdl);
93  writeHandle.addDependency(larNoiseHdl);
94  ATH_MSG_DEBUG("Range of LArNoise " << larNoiseHdl.getRange() << ", intersection:" << writeHandle.getRange());
95  }
96 
97  if (!m_tileNoiseKey.key().empty()) {
99  attrListNoise.push_back(*tileNoiseHdl);
100  writeHandle.addDependency(tileNoiseHdl);
101  ATH_MSG_DEBUG("Range of TileNoise " << tileNoiseHdl.getRange() << ", intersection:" << writeHandle.getRange());
102  }
103 
104  if (!m_caloNoiseKey.key().empty()) {
106  attrListNoise.push_back(*caloNoiseHdl);
107  writeHandle.addDependency(caloNoiseHdl);
108  ATH_MSG_DEBUG("Range of CaloNoise " << caloNoiseHdl.getRange() << ", intersection:" << writeHandle.getRange());
109  }
110 
111  //Get noise-blobs out of all COOL-channels in all COOL Folders we know about:
112  std::forward_list<std::pair<unsigned, const coral::Blob&> > blobList;
113  for (const auto& attrListColl : attrListNoise) {
114  for (const auto& coll : *attrListColl) {
115  ATH_MSG_DEBUG("Working on channel " << coll.first);
116  const coral::Blob& blob = (coll.second)["CaloCondBlob16M"].data<coral::Blob>();
117  if (blob.size()<1) {
118  ATH_MSG_DEBUG("Empty blob in channel " << coll.first << ". Ignored.");
119  continue;
120  }
121  blobList.emplace_front(coll.first, blob);
122  }
123  }
124 
125  //Get LAr HVScale Corr (if requested)
126  const LArHVCorr* larHVCorr=nullptr;
127  if (m_useHVCorr) {
128  SG::ReadCondHandle<LArHVCorr> larHVCorrHdl{m_hvCorrKey,ctx};
129  larHVCorr=*larHVCorrHdl;
130  writeHandle.addDependency(larHVCorrHdl);
131  ATH_MSG_DEBUG("Range of LArHVScale " << larHVCorrHdl.getRange() << ", intersection:" << writeHandle.getRange());
132  }
133 
134  //Get Luminosity:
135  float lumi=m_lumi0;
136  //if (m_lumi0<0 && m_noiseType!=CaloNoise::ELEC) {
137  if (not m_lumiFolderKey.empty()) {
139  const CondAttrListCollection* lumiAttrListColl=*lumiHdl;
140  writeHandle.addDependency(lumiHdl);
141  ATH_MSG_DEBUG("Range of Luminosity " << lumiHdl.getRange() << ", intersection:" << writeHandle.getRange() );
142  const coral::AttributeList& attrList = lumiAttrListColl->attributeList(0); //Get lumi from COOL channel 0
143  if (attrList["LBAvInstLumi"].isNull()) {
144  ATH_MSG_WARNING( " NULL Luminosity information in database ... set it to 0 " );
145  lumi = 0.;
146  } else {
147  lumi = attrList["LBAvInstLumi"].data<float>() *1e-3; // luminosity (from 10**30 units in db to 10*33 units)
148  }
149  if (std::isnan(lumi)) {
150  ATH_MSG_WARNING( " Luminosity is not a number.. " << m_lumi0 << " ... set it to 0 " );
151  lumi=0.;
152  }
153  }//end if m_lumi0<0
154  else if (lumi < 0) {
155  // Clang may speculatively evaluate the sqrt(lumi) below even if
156  // m_noiseType is ELEC, which can then be an issue if one looks
157  // at FPEs. Protect against this by making sure that lumi
158  // is not negative.
159  lumi = 0;
160  }
161 
162 
163  const size_t maxCells=m_caloCellID->calo_cell_hash_max();
164  //Create the CaloNoise CDO:
165  const size_t nLArCells=m_hashRange->maxLArCells();
166  const size_t nTileCells=m_hashRange->maxTileCells();
167  std::unique_ptr<CaloNoise> caloNoiseObj=std::make_unique<CaloNoise>(nLArCells,3,
168  nTileCells,4,
170 
171  //Counters for crosschecks
172  std::array<unsigned,4> cellsPerGain{0,0,0,0};
173  unsigned nBlobs=0;
174 
175  //Loop over the list of blobs we got:
176  for (auto& blobPair : blobList) {
177  nBlobs++;
178  const CaloNoiseHashRanges::SYSTEM sys=static_cast<CaloNoiseHashRanges::SYSTEM>(blobPair.first);
179  const IdentifierHash offset=m_hashRange->hashOffsets().at(sys);
180  std::unique_ptr<const CaloCondBlobFlt> blob(CaloCondBlobFlt::getInstance(blobPair.second));
181  if (blob->getObjVersion()!=1) {
182  ATH_MSG_ERROR("Unexpected blob object version in COOL channel " << blobPair.first
183  << ". Found " << blob->getObjVersion() << ", expected 1");
184  return StatusCode::FAILURE;
185  }
186  //Get writeable access to underlying storage (boost::multi_array)
187  auto& noise = (sys==CaloNoiseHashRanges::TILE) ? caloNoiseObj->tileStorage() : caloNoiseObj->larStorage();
188 
189  const unsigned nChansThisblob=blob->getNChans();
190  const unsigned nGains=blob->getNGains();
191  for (unsigned igain=0;igain<nGains;++igain) {
192  for (unsigned i=0;i<nChansThisblob;++i) {
193  float hvcorr=1.0;
194  if (sys!=CaloNoiseHashRanges::TILE && larHVCorr) {
195  const IdentifierHash oflHash(offset+i);
196  hvcorr=larHVCorr->HVScaleCorr_oflHash(oflHash);
197  //hvcorr might be zero in case of problems with the DCS database
198  if (hvcorr<0.01) hvcorr=1.0;
199  }
200  const float a=blob->getData(i,igain,0)*hvcorr;
201  const float b=blob->getData(i,igain,1);
202  ++(cellsPerGain[igain]);
203  const size_t hash = (sys==CaloNoiseHashRanges::TILE) ? i : i+offset;
204  switch (m_noiseType){
205  case CaloNoise::ELEC:
206  noise[igain][hash]=a;
207  break;
208  case CaloNoise::PILEUP:
209  noise[igain][hash]=b*std::sqrt(lumi);
210  break;
211  case CaloNoise::TOTAL:
212  noise[igain][hash]=std::sqrt(a*a + b*b*lumi);
213  break;
214  default:
215  break;
216  }
217  }//end loop over channels
218  }//end loop over gains
219 
220 
221  // Cache data to calculate effective sigma for tile double-gaussian noise
222  // Matters for Electronic and total noise
224  caloNoiseObj->setTileBlob(blob.release(),lumi);
225  }
226 
227  }//end loop over blob (COOL channels)
228 
229 
230 
231  if (nBlobs!=7) {
232  ATH_MSG_ERROR("Unexpected number of COOL channels containing noise-blobs. Got " << nBlobs << " expected 7 (6 LAr, 1 Tile)");
233  return StatusCode::FAILURE;
234  }
235 
236 
237  switch (m_noiseType){
238  case CaloNoise::ELEC:
239  ATH_MSG_INFO("Calculated electronic noise" << (larHVCorr ? " with " : " without ") << "HV Scale correction");
240  break;
241  case CaloNoise::PILEUP:
242  ATH_MSG_INFO("Calculated pile-up noise for lumi " << lumi);
243  break;
244  case CaloNoise::TOTAL:
245  ATH_MSG_INFO("Calculated total noise for lumi " << lumi<< (larHVCorr ? " with " : " without ") << "HV Scale correction");
246  break;
247  default:
248  break;
249  }
250 
251  for (unsigned igain=0;igain<4;++igain) {
252 
253  if (igain<3 && cellsPerGain[igain]!=maxCells) {
254  ATH_MSG_ERROR("Expected " << maxCells << " cells for gain " << igain << ", got " << cellsPerGain[igain]);
255  }
256  else {
257  ATH_MSG_DEBUG("Gain " << igain << " Nbr of cells: " << cellsPerGain[igain]);
258  }
259 
260  }
261 
262  //Create output object
263  ATH_CHECK(writeHandle.record(std::move(caloNoiseObj)));
264  ATH_MSG_INFO("recorded new CaloNoise object with key " << writeHandle.key() << " and range " << writeHandle.getRange());
265 
266  return StatusCode::SUCCESS;
267 }
python.PyKernel.retrieve
def retrieve(aClass, aKey=None)
Definition: PyKernel.py:110
AllowedVariables::e
e
Definition: AsgElectronSelectorTool.cxx:37
CaloNoiseCondAlg::m_noiseType
CaloNoise::NOISETYPE m_noiseType
Definition: CaloNoiseCondAlg.h:58
SG::ReadCondHandle
Definition: ReadCondHandle.h:44
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
CaloNoise::TOTAL
@ TOTAL
Definition: CaloNoise.h:23
CaloNoiseCondAlg::initialize
StatusCode initialize() override final
Definition: CaloNoiseCondAlg.cxx:10
CaloNoise::setTileBlob
void setTileBlob(const CaloCondBlobFlt *flt, const float lumi)
Definition: CaloNoise.cxx:31
CaloNoise::ELEC
@ ELEC
Definition: CaloNoise.h:21
CaloNoiseCondAlg::m_caloNoiseKey
SG::ReadCondHandleKey< CondAttrListCollection > m_caloNoiseKey
Definition: CaloNoiseCondAlg.h:39
python.subdetectors.tile.Blob
Blob
Definition: tile.py:17
CaloNoiseCondAlg::m_outputKey
SG::WriteCondHandleKey< CaloNoise > m_outputKey
Definition: CaloNoiseCondAlg.h:46
python.PyKernel.AttributeList
AttributeList
Definition: PyKernel.py:36
CaloNoiseCondAlg::m_useHVCorr
Gaudi::Property< bool > m_useHVCorr
Definition: CaloNoiseCondAlg.h:48
SG::VarHandleKey::key
const std::string & key() const
Return the StoreGate ID for the referenced object.
Definition: AthToolSupport/AsgDataHandles/Root/VarHandleKey.cxx:141
SG::VarHandleKey::empty
bool empty() const
Test if the key is blank.
Definition: AthToolSupport/AsgDataHandles/Root/VarHandleKey.cxx:150
CondAttrListCollection
This class is a collection of AttributeLists where each one is associated with a channel number....
Definition: CondAttrListCollection.h:52
CaloNoiseCondAlg::m_hashRange
std::unique_ptr< CaloNoiseHashRanges > m_hashRange
Definition: CaloNoiseCondAlg.h:56
mapkey::sys
@ sys
Definition: TElectronEfficiencyCorrectionTool.cxx:42
CaloCell_ID.h
CaloNoiseCondAlg::execute
StatusCode execute(const EventContext &ctx) const override final
Definition: CaloNoiseCondAlg.cxx:77
AthCommonDataStore< AthCommonMsg< Gaudi::Algorithm > >::detStore
const ServiceHandle< StoreGateSvc > & detStore() const
The standard StoreGateSvc/DetectorStore Returns (kind of) a pointer to the StoreGateSvc.
Definition: AthCommonDataStore.h:95
CaloNoiseHashRanges::TILE
@ TILE
Definition: CaloNoiseHashRanges.h:42
LArHVCorr::HVScaleCorr_oflHash
const float & HVScaleCorr_oflHash(const IdentifierHash &h) const
Definition: LArHVCorr.h:32
CaloNoiseCondAlg::m_larNoiseKey
SG::ReadCondHandleKey< CondAttrListCollection > m_larNoiseKey
Definition: CaloNoiseCondAlg.h:34
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
CaloNoiseCondAlg::m_hvCorrKey
SG::ReadCondHandleKey< LArHVCorr > m_hvCorrKey
Definition: CaloNoiseCondAlg.h:41
CaloCell_Base_ID::calo_cell_hash_max
size_type calo_cell_hash_max() const
cell 'global' hash table max size
CaloNoiseCondAlg.h
lumiFormat.i
int i
Definition: lumiFormat.py:85
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
LArHVCorr
Definition: LArHVCorr.h:16
CaloNoiseCondAlg::m_tileNoiseKey
SG::ReadCondHandleKey< CondAttrListCollection > m_tileNoiseKey
Definition: CaloNoiseCondAlg.h:36
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
WriteCellNoiseToCool.igain
igain
Definition: WriteCellNoiseToCool.py:338
CondAttrListCollection::attributeList
const AttributeList & attributeList(ChanNum chanNum) const
attribute list for a given channel number
Definition: CondAttrListCollection.h:401
CaloNoiseCondAlg::m_lumi0
Gaudi::Property< float > m_lumi0
Definition: CaloNoiseCondAlg.h:49
plotBeamSpotMon.b
b
Definition: plotBeamSpotMon.py:76
SG::CondHandleKey::initialize
StatusCode initialize(bool used=true)
CaloNoiseCondAlg::m_lumiFolderKey
SG::ReadCondHandleKey< CondAttrListCollection > m_lumiFolderKey
Definition: CaloNoiseCondAlg.h:43
CaloNoise::PILEUP
@ PILEUP
Definition: CaloNoise.h:22
CaloNoise::tileStorage
boost::multi_array< float, 2 > & tileStorage()
Definition: CaloNoise.h:72
CaloCondBlobFlt.h
lumiFormat.lumi
lumi
Definition: lumiFormat.py:106
a
TList * a
Definition: liststreamerinfos.cxx:10
CaloCondBlobAlgs_fillNoiseFromASCII.hash
dictionary hash
Definition: CaloCondBlobAlgs_fillNoiseFromASCII.py:108
CaloCondBlobFlt::getInstance
static CaloCondBlobFlt * getInstance(coral::Blob &blob)
Returns a pointer to a non-const CaloCondBlobFlt.
Definition: CaloCondBlobFlt.cxx:12
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
CaloNoise::larStorage
boost::multi_array< float, 2 > & larStorage()
Non-const accessor to underlying storage for filling:
Definition: CaloNoise.h:71
convertTimingResiduals.offset
offset
Definition: convertTimingResiduals.py:71
CaloNoiseHashRanges::SYSTEM
SYSTEM
Definition: CaloNoiseHashRanges.h:36
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
SG::WriteCondHandle
Definition: WriteCondHandle.h:26
WriteCellNoiseToCool.noise
noise
Definition: WriteCellNoiseToCool.py:380
CaloCondBlobAlgs_fillNoiseFromASCII.blob
blob
Definition: CaloCondBlobAlgs_fillNoiseFromASCII.py:95
CaloNoiseCondAlg::m_caloCellID
const CaloCell_ID * m_caloCellID
Definition: CaloNoiseCondAlg.h:54