ATLAS Offline Software
CaloCellContainerCheckerTool.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 /********************************************************************
6 
7 NAME: CaloCellContainerCheckerTool
8 PACKAGE: offline/Calorimeter/CaloRec
9 
10 AUTHORS: David Rousseau
11 CREATED: May 12,2004
12 
13 PURPOSE: check integrity of CaloCellContainer find and iterators
14 
15 ********************************************************************/
16 
18 
22 
23 #include "CLHEP/Units/SystemOfUnits.h"
24 
26 #include "FourMom/P4PxPyPzE.h"
27 
28 using CLHEP::MeV;
29 
31 // CONSTRUCTOR:
33 
35  const std::string& type,
36  const std::string& name,
37  const IInterface* parent)
38  :base_class(type, name, parent)
39 {
40  declareProperty ("EventsToCheck",m_eventsToCheck = 5);
41 }
42 
43 
44 
45 
47 // INITIALIZE:
48 // The initialize method will create all the required algorithm objects
50 
52 
53  ATH_CHECK(detStore()->retrieve(m_theCaloCCIDM,"CaloCell_ID"));
54  return StatusCode::SUCCESS;
55 }
56 
57 
60  const EventContext& ctx) const
61 {
62  return doProcess (theCont, ctx);
63 }
64 
65 
68  const EventContext& ctx) const
69 {
70  return doProcess (theCont->asDataVector(), ctx);
71 }
72 
73 
76  const EventContext& ctx) const
77 {
78  if (ctx.evt() >= m_eventsToCheck) {
79  return StatusCode::SUCCESS;
80  }
81 
82  StatusCode returnSc = StatusCode::SUCCESS ;
83 
84  double eSum = 0;
85  unsigned int index = 0;
86  std::vector<double> eSumCalos;
87  std::vector<unsigned int> nCellCalos;
88  for (int iCalo=CaloCell_ID::LAREM; iCalo<CaloCell_ID::NSUBCALO ; ++iCalo) {
89  eSumCalos.push_back(0.);
90  nCellCalos.push_back(0);
91  }
92 
93 
94  for (const CaloCell* aCell : *theCont) {
95  const CaloDetDescrElement * theDDE=aCell->caloDDE();
96  int iCalo = static_cast<int>(theDDE->getSubCalo());
97  eSum+=aCell->e();
98  eSumCalos[iCalo]+=aCell->e();
99  ++(nCellCalos[iCalo]);
100  ++index ;
101  P4PxPyPzE aP(aCell);
102  const double aPeta=aP.e() != 0 ? aP.eta() : 0;
103  const double aPphi=aP.phi() ;
104 
105  // not needed anymore : now implemented in FOurMom
106  // if (aCell->e()<0) {
107  // aPeta=-aPeta;
108  // aPphi=aCaloPhiRange.fix(aPphi+aCaloPhiRange.twopi()/2.);
109  //}
110 
111  if (aCell->e()!=0 && std::abs(aCell->eta()-aPeta)>0.0001) {
112  msg(MSG::WARNING) << "Cell " << index << " eta inconsistency : " << aCell->eta()
113  << " vs recalculated " << aPeta << endmsg ;
114  }
115  if (aCell->e()!=0 && std::abs(CaloPhiRange::diff(aCell->phi(),aPphi))>0.0001) {
116  msg(MSG::WARNING) << "Cell " << index << " phi inconsistency : " << aCell->phi()
117  << " vs recalculated " << aPphi << endmsg ;
118  }
119  }
120  index =0;
121  if (msgLvl(MSG::VERBOSE)) {
122  for (const CaloCell* aCell : *theCont) {
123  const CaloDetDescrElement * theDDE=aCell->caloDDE();
124  msg(MSG::VERBOSE) << index << " " << " " << aCell
125  << " hash id " << theDDE->calo_hash()
126  << " eta " << theDDE->eta()
127  << " phi " << theDDE->phi()
128  << " e " << aCell->e() << endmsg ;
129  ++index;
130  }
131  }
132 
133  //check hasCalo() flags
134  for (int iCalo=CaloCell_ID::LAREM; iCalo<CaloCell_ID::NSUBCALO ; ++iCalo) {
135  if (nCellCalos[iCalo]>0 && !theCont->hasCalo(static_cast<CaloCell_ID::SUBCALO>(iCalo) ) )
136  {
137  msg(MSG::WARNING) << " There are cells for calo "
138  << iCalo << " but hasCalo is not set. " << endmsg ;
139  }
140  }
141 
142  ATH_MSG_DEBUG(" eSum " << eSum);
143 
144  //check now the sub calo iterators
145  for (int iCalo=CaloCell_ID::LAREM; iCalo<CaloCell_ID::NSUBCALO ; ++iCalo) {
146  CaloCell_ID::SUBCALO enumCalo=static_cast<CaloCell_ID::SUBCALO>(iCalo);
147  double theESumCalo=0;
148  unsigned int theNCellCalo=0;
149 
150  CaloCellContainer::const_iterator itrCell=theCont->beginConstCalo(enumCalo);
151  CaloCellContainer::const_iterator endCell=theCont->endConstCalo(enumCalo);
152  for (;itrCell!=endCell;++itrCell){
153  theESumCalo+=(*itrCell)->e();
154  ++theNCellCalo;
155  }
156 
157 
158  ATH_MSG_DEBUG(" theNCellCalo="<<theNCellCalo
159  <<" nCellCalos[iCalo]=" <<nCellCalos[iCalo]
160  <<" theCont->nCellsCalo(enumCalo)=" << theCont->nCellsCalo(enumCalo) );
161 
162  if (theNCellCalo!=nCellCalos[iCalo] ||
163  static_cast<int>(theNCellCalo)!=theCont->nCellsCalo(enumCalo) ) {
164  msg(MSG::ERROR) << " Iterators: ncell do not match"
165  << " theNCellCalo="<<theNCellCalo
166  <<" nCellCalos[iCalo]=" <<nCellCalos[iCalo]
167  <<" theCont->nCellsCalo(enumCalo)=" << theCont->nCellsCalo(enumCalo)
168  << endmsg;
169  returnSc = StatusCode::FAILURE;
170  }
171 
172 
173 
174  ATH_MSG_DEBUG("theESumCalo eSumCalos[iCalo] "<< theESumCalo << " " << eSumCalos[iCalo]);
175  const double epsilon=1e-5;
176  if (fabs(theESumCalo-eSumCalos[iCalo])>epsilon) {
177  msg(MSG::ERROR) << " Non const iterators: E sum do not match"
178  << " subcalo " << iCalo
179  << " should be " << eSumCalos[iCalo]
180  << " is " << theESumCalo <<" (" << theESumCalo-eSumCalos[iCalo] << ")" << endmsg ;
181  returnSc = StatusCode::FAILURE;
182  }
183 
184 
185  }
186 
187  // check find methods
188 
189  // count number of holes
190  const unsigned int hashMax=m_theCaloCCIDM->calo_cell_hash_max();
191  unsigned int nHoles =0;
192 
193  ATH_MSG_DEBUG("Now check all hashes give meaningful answer");
194  for (unsigned int theHash=0;theHash<hashMax;++theHash){
195  const CaloCell * theCell = theCont->findCell(theHash) ;
196  if (theCell==nullptr) {
197  ++nHoles;
198  if (msgLvl(MSG::VERBOSE)) {
199  //const CaloDetDescrElement* theCaloDDM->dde=get_element(theHash);
200  const Identifier id=m_theCaloCCIDM->cell_id(theHash);
201  const int subcalo=m_theCaloCCIDM->sub_calo(theHash);
202  const int sampling=m_theCaloCCIDM->calo_sample(theHash);
203  const int pos_neg=m_theCaloCCIDM->pos_neg(id);
204  const int region=m_theCaloCCIDM->region(id);
205  const int sample=m_theCaloCCIDM->sample(id);
206  msg(MSG::VERBOSE) << "Cell not found: id=0x" << std::hex << id << std::dec
207  << ", SubCalo=" <<subcalo <<", sampling="<< sampling << ", pos_neg="
208  << pos_neg << ", region=" << region << ", sample=" << sample << endmsg;
209  }//end if verbose
210  }//end if cell==0
211  }//end loop over hashes
212  ATH_MSG_DEBUG("Number of hash with no cells: " << nHoles << " out of " << hashMax);
213 
214  std::vector<IdentifierHash> hashes ;
215  hashes.clear();
216  double eSumFound=0;
217 
218  index =0;
219 
220  for ( CaloCellContainer::const_iterator itrCell=theCont->begin();itrCell!=theCont->end();++itrCell){
221  IdentifierHash theHash = (*itrCell)->caloDDE()->calo_hash();
222  if ((*itrCell)->et()>2000 * MeV ) {
223  hashes.push_back(theHash);
224  eSumFound+=(*itrCell)->energy();
225  }
226  const CaloCell * reCell=theCont->findCell(theHash);
227  if (reCell!=*itrCell){
228 
229  const CaloDetDescrElement * reCaloDDE=nullptr ;
230  unsigned int reHash=0 ;
231 
232 
233  if (reCell!=nullptr) reCaloDDE=reCell->caloDDE();
234  if (reCaloDDE!=nullptr) reHash = reCaloDDE->calo_hash();
235 
236 
237  msg(MSG::ERROR) << index << "Cell " << theHash << " " << *itrCell
238  << " not found back " << reCell
239  << " reCaloDDE " << reCaloDDE
240  << " rehash " << reHash << endmsg ;
241  returnSc = StatusCode::FAILURE;
242  }
243  ++index;
244  }
245 
246  ATH_MSG_DEBUG("number of cells to be refound " << hashes.size() << " total energy " << eSumFound);
247 
249  foundCells.clear();
250 
251  theCont->findCellVector(hashes,foundCells);
252 
253  if (hashes.size()!=foundCells.size()){
254  msg(MSG::ERROR) << "number of cells to be found " << hashes.size() << "number found: " << foundCells.size() << endmsg ;
255  returnSc = StatusCode::FAILURE;
256  }
257 
258 
259  double reSumFound=0;
260 
261  for (CaloCellContainer::CellVector::const_iterator itrCell=foundCells.begin();itrCell!=foundCells.end(); ++itrCell)
262  if (*itrCell!=0) reSumFound+=(*itrCell)->e();
263 
264 
265  if (std::abs(reSumFound-eSumFound)>10 * MeV ){
266  msg(MSG::ERROR) << "Found cells wrong E sum " << reSumFound << " instead of " << eSumFound << endmsg ;
267  returnSc = StatusCode::FAILURE;
268  }
269 
270  return returnSc ;
271 }
272 
273 
274 
275 
276 
277 
278 
279 
CaloCellContainerCheckerTool::doProcess
StatusCode doProcess(const CaloCellContainer *theCellContainer, const EventContext &ctx) const
Definition: CaloCellContainerCheckerTool.cxx:75
python.root_lsr_rank.hashes
hashes
Definition: root_lsr_rank.py:34
python.PyKernel.retrieve
def retrieve(aClass, aKey=None)
Definition: PyKernel.py:110
DataModel_detail::const_iterator
Const iterator class for DataVector/DataList.
Definition: DVLIterator.h:82
CaloCellContainerCheckerTool::m_theCaloCCIDM
const CaloCell_ID * m_theCaloCCIDM
Definition: CaloCellContainerCheckerTool.h:39
CaloCell_Base_ID::region
int region(const Identifier id) const
LAr field values (NOT_VALID == invalid request)
P4PxPyPzE::e
virtual double e() const
get energy data member
Definition: P4PxPyPzE.h:132
index
Definition: index.py:1
P4PxPyPzEBase::eta
virtual double eta() const
pseudo rapidity
Definition: P4PxPyPzEBase.cxx:32
CaloCell_Base_ID::pos_neg
int pos_neg(const Identifier id) const
LAr field values (NOT_VALID == invalid request)
CaloDetDescrElement
This class groups all DetDescr information related to a CaloCell. Provides a generic interface for al...
Definition: Calorimeter/CaloDetDescr/CaloDetDescr/CaloDetDescrElement.h:66
python.SystemOfUnits.MeV
int MeV
Definition: SystemOfUnits.py:154
CaloCellContainerCheckerTool::m_eventsToCheck
size_t m_eventsToCheck
Definition: CaloCellContainerCheckerTool.h:38
CaloCellContainerCheckerTool.h
CaloCell_Base_ID::calo_sample
int calo_sample(const Identifier id) const
returns an int taken from Sampling enum and describing the subCalo to which the Id belongs.
Definition: CaloCell_Base_ID.cxx:141
ConstDataVector::asDataVector
const DV * asDataVector() const
Return a pointer to this object, as a const DataVector.
CaloCell_ID.h
CaloDetDescrElement::getSubCalo
CaloCell_ID::SUBCALO getSubCalo() const
cell subcalo
Definition: Calorimeter/CaloDetDescr/CaloDetDescr/CaloDetDescrElement.h:433
CaloDetDescrElement::calo_hash
IdentifierHash calo_hash() const
cell calo hash
Definition: Calorimeter/CaloDetDescr/CaloDetDescr/CaloDetDescrElement.h:412
FullCPAlgorithmsTest_eljob.sample
sample
Definition: FullCPAlgorithmsTest_eljob.py:100
CaloCell_Base_ID::sample
int sample(const Identifier id) const
Tile field values (NOT_VALID == invalid request)
Identifier
Definition: DetectorDescription/Identifier/Identifier/Identifier.h:32
endmsg
#define endmsg
Definition: AnalysisConfig_Ntuple.cxx:63
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
CaloCell::caloDDE
const CaloDetDescrElement * caloDDE() const
get pointer to CaloDetDescrElement (data member)
Definition: CaloCell.h:305
CaloCell_Base_ID::SUBCALO
SUBCALO
enumeration of sub calorimeters
Definition: CaloCell_Base_ID.h:46
CaloCellContainerCheckerTool::initialize
virtual StatusCode initialize() override
Definition: CaloCellContainerCheckerTool.cxx:51
test_pyathena.parent
parent
Definition: test_pyathena.py:15
CaloPhiRange.h
CaloPhiRange class declaration.
CaloCell_Base_ID::sub_calo
int sub_calo(const Identifier id) const
returns an int taken from SUBCALO enum and describing the subCalo to which the Id belongs.
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
CaloCellContainerCheckerTool::process
virtual StatusCode process(CaloCellContainer *theCellContainer, const EventContext &ctx) const override
Definition: CaloCellContainerCheckerTool.cxx:59
python.PyKernel.detStore
detStore
Definition: PyKernel.py:41
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:195
CaloCellContainer.h
CaloCellContainer
Container class for CaloCell.
Definition: CaloCellContainer.h:55
CaloCell_Base_ID::cell_id
Identifier cell_id(const int subCalo, const int barec_or_posneg, const int sampling_or_fcalmodule, const int region_or_dummy, const int eta, const int phi) const
Make a cell (== channel) ID from constituting fields and subCalo index; for (Mini)FCAL,...
CaloCellContainerCheckerTool::CaloCellContainerCheckerTool
CaloCellContainerCheckerTool(const std::string &type, const std::string &name, const IInterface *parent)
Definition: CaloCellContainerCheckerTool.cxx:34
DeMoScan.index
string index
Definition: DeMoScan.py:362
DiTauMassTools::MaxHistStrategyV2::e
e
Definition: PhysicsAnalysis/TauID/DiTauMassTools/DiTauMassTools/HelperFunctions.h:26
P4PxPyPzE
Definition: P4PxPyPzE.h:29
CaloCell
Data object for each calorimeter readout cell.
Definition: CaloCell.h:57
CaloConstCellContainer
CaloCellContainer that can accept const cell pointers.
Definition: CaloConstCellContainer.h:45
python.CaloScaleNoiseConfig.type
type
Definition: CaloScaleNoiseConfig.py:78
declareProperty
#define declareProperty(n, p, h)
Definition: BaseFakeBkgTool.cxx:15
CaloDetDescrElement::eta
float eta() const
cell eta
Definition: Calorimeter/CaloDetDescr/CaloDetDescr/CaloDetDescrElement.h:344
CaloCell_Base_ID::NSUBCALO
@ NSUBCALO
Definition: CaloCell_Base_ID.h:46
CaloDetDescrElement::phi
float phi() const
cell phi
Definition: Calorimeter/CaloDetDescr/CaloDetDescr/CaloDetDescrElement.h:346
python.Constants.VERBOSE
int VERBOSE
Definition: Control/AthenaCommon/python/Constants.py:14
P4PxPyPzE.h
IdentifierHash
Definition: IdentifierHash.h:38
CaloConstCellContainer.h
CaloCellContainer that can accept const cell pointers.
P4PxPyPzEBase::phi
virtual double phi() const
phi in [-pi,pi[
Definition: P4PxPyPzEBase.cxx:50
CaloCell_Base_ID::LAREM
@ LAREM
Definition: CaloCell_Base_ID.h:46
python.AutoConfigFlags.msg
msg
Definition: AutoConfigFlags.py:7
CaloCellContainer::CellVector
std::vector< const CaloCell * > CellVector
type to be used for the internal lookup table, and to return list of cells
Definition: CaloCellContainer.h:83
CaloPhiRange::diff
static double diff(double phi1, double phi2)
simple phi1 - phi2 calculation, but result is fixed to respect range.
Definition: CaloPhiRange.cxx:22
CaloCell_Base_ID::calo_cell_hash_max
size_type calo_cell_hash_max(void) const
cell 'global' hash table max size