ATLAS Offline Software
IdentifierHashCalc.h
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 #ifndef MUONCALIBIDENTIFIER_IDENTIFIERHASHCALC_H
6 #define MUONCALIBIDENTIFIER_IDENTIFIERHASHCALC_H
7 
8 /***************************************************************************
9  * Identifier hashes
10  * -----------------------------------------
11  *
12  * Author : Martin Woudstra
13  * Creation Date: 7 May 2004
14  * Last Update : 9 May 2005
15  ***************************************************************************/
16 
21 #include "GaudiKernel/MsgStream.h"
23 
24 #include <limits.h>
25 #include <iostream>
26 #include <iomanip>
27 
28 template <class T>
30 public:
31  //
32  // Nested types
33  //
37  enum { NFIELDS = T::NFIELDS, NMAX=UINT_MAX };
39  typedef T IdFieldsType;
41  typedef typename T::IdentifierType IdType;
43  typedef typename T::HashType HashType;
44  //
45  // Member functions
46  //
51  explicit IdentifierHashCalc( const T& idFields );
53  void clear();
55  unsigned int size() const;
57  bool checkValidity() const;
59  bool addEntry( const IdType& id );
61  void setFieldLimits( unsigned int fieldIndex, int fieldMin, int fieldMax );
63  HashType getHash( const IdType& id ) const;
65  IdType getIdentifier( const HashType& idHash ) const;
67  void dump( std::ostream& os = std::cout ) const;
69  std::string dumpToString() const;
70 private:
71  bool isInRange( const T& idFields ) const;
72  void update();
75  unsigned int m_fieldsSize[NFIELDS];
76  unsigned int m_fieldsFactor[NFIELDS];
77  mutable T m_idFields;
78 };
79 
80 template <class T>
82  clear();
83 }
84 
85 template <class T>
86 inline IdentifierHashCalc<T>::IdentifierHashCalc( const T& idFields )
87  : m_idFields(idFields)
88 {
89  clear();
90 }
91 
92 template <class T>
93 inline bool IdentifierHashCalc<T>::isInRange( const T& idFields ) const {
94  for ( unsigned int i = 0; i < NFIELDS; ++i ) {
95  if ( idFields[i] < m_fieldsMin[i] || idFields[i] > m_fieldsMax[i] ) return false;
96  }
97  return true;
98 }
99 
100 template <class T>
102 IdentifierHashCalc<T>::getHash( const IdType& id ) const {
103  m_idFields.setAll( id );
104  if ( !isInRange( m_idFields ) ) return T::defaultHash();
105  unsigned int hash = m_idFields[0] - m_fieldsMin[0];
106  for ( unsigned int i = 1; i < NFIELDS; ++i ) {
107  hash += m_fieldsFactor[i-1] * ( m_idFields[i] - m_fieldsMin[i] );
108  }
109  return HashType(hash);
110 }
111 
112 template <class T>
114 IdentifierHashCalc<T>::getIdentifier( const HashType& idHash ) const {
115  int fields[NFIELDS];
116  fields[0] = m_fieldsMin[0] + ( idHash % m_fieldsSize[0] );
117  for ( unsigned int i = 1; i < NFIELDS; ++i ) {
118  fields[i] = m_fieldsMin[i] + ( ( idHash / m_fieldsFactor[i-1] ) % m_fieldsSize[i] );
119  }
120  m_idFields.setAll( fields );
121  if ( !isInRange( m_idFields ) ) return IdType();
122  return m_idFields.getId();
123 }
124 
125 template <class T>
127  // update sizes and field factors
128  m_fieldsSize[0] = m_fieldsMax[0] - m_fieldsMin[0] + 1;
129  m_fieldsFactor[0] = m_fieldsSize[0];
130  for ( unsigned int i = 1; i < NFIELDS; ++i ) {
133  }
134 }
135 
136 template <class T>
137 inline bool IdentifierHashCalc<T>::addEntry( const IdType& id ) {
138  if ( !T::isValid( id ) ) return false;
139  // set ranges
140  m_idFields.setAll( id );
141  bool bChanged = false;
142  for ( unsigned int i = 0; i < NFIELDS; ++i ) {
143  if ( m_idFields[i] < m_fieldsMin[i] ) {
145  bChanged = true;
146  }
147  if ( m_idFields[i] > m_fieldsMax[i] ) {
149  bChanged = true;
150  }
151  }
152  if ( bChanged ) update();
153  return true;
154 }
155 
156 template <class T>
157 void IdentifierHashCalc<T>::setFieldLimits( unsigned int fieldIndex, int fieldMin, int fieldMax ) {
158  if ( fieldIndex >= NFIELDS ) return;
159  if ( fieldMin > fieldMax ) return;
160  bool bChanged = false;
161  if ( fieldMin != m_fieldsMin[fieldIndex] ) {
162  m_fieldsMin[fieldIndex] = fieldMin;
163  bChanged = true;
164  }
165  if ( fieldMax != m_fieldsMax[fieldIndex] ) {
166  m_fieldsMax[fieldIndex] = fieldMax;
167  bChanged = true;
168  }
169  if ( bChanged ) update();
170 }
171 
172 template <class T>
174  for ( unsigned int i = 0; i < NFIELDS; ++i ) {
175  m_fieldsMin[i] = INT_MAX;
176  m_fieldsMax[i] = INT_MIN;
177  m_fieldsSize[i] = 0;
178  m_fieldsFactor[i] = 0;
179  }
180 }
181 
182 template <class T>
183 inline unsigned int IdentifierHashCalc<T>::size() const {
184  return m_fieldsFactor[NFIELDS - 1];
185 }
186 
187 template <class T>
189  // check that table is non-empty
190  if ( !size() ) {
191  MsgStream log(Athena::getMessageSvc(),"IdentifierHashCalc");
192  log<<MSG::WARNING<<"IdentifierHashCalc<T>::checkValidity() Table is empty."<<endmsg;
193  return false;
194  }
195  // check that tables are each other's inverse
196  unsigned int nErrors = 0;
197 #ifdef IDENTIFIERHASHCALC_DEBUG
198  MsgStream log(Athena::getMessageSvc(),"IdentifierHashCalc");
199 #endif
200  for ( unsigned int i = 0; i < size(); ++i ) {
201  HashType iHash(i);
202  IdType id = getIdentifier( iHash );
203  unsigned int hash = getHash( id );
204  if ( hash != i ) {
205 #ifndef IDENTIFIERHASHCALC_DEBUG
206  MsgStream log(Athena::getMessageSvc(),"IdentifierHashCalc");
207 #endif
208  log<<MSG::WARNING<<"IdentifierHashCalc<T>::checkValidity() getIdentifier(" << i << ")=0x" << std::hex << id << std::dec << " whereas getHash(" << std::hex << id << std::dec << ")=" << hash<<endmsg;
209  ++nErrors;
210  } else {
211 #ifdef IDENTIFIERHASHCALC_DEBUG
212  log<<MSG::DEBUG<<"hash=" << i << " <--> id=0x" << std::hex << id << std::dec << ": OK"<<endmsg;
213 #endif
214  }
215  }
216 #ifdef IDENTIFIERHASHCALC_DEBUG
217  if ( nErrors ) {
218  log<<MSG::WARNING<<"IdentifierHashCalc<T>::checkValidity() table contains " << nErrors << " errors." << endmsg;
219  } else {
220  log<<MSG::DEBUG<<"IdentifierHashCalc<T>::checkValidity(): table OK"<<endmsg;
221  }
222 #endif
223 
224  if ( nErrors ) return false;
225 
226  // if we get here, everything is OK!
227  return true;
228 }
229 
230 template <class T>
231 void IdentifierHashCalc<T>::dump( std::ostream& os ) const {
232  unsigned int n = size();
233  for ( unsigned int i = 0; i < n; ++i ) {
234  HashType iHash(i);
235  IdType id = getIdentifier( iHash );
236  m_idFields.setAll( id );
237  os << "ID=0x" << std::hex << id << std::dec << " fields=(";
238  for ( int j = NFIELDS-1; j >= 0; --j ) {
239  os << m_idFields[j];
240  if ( j != 0 ) os << ",";
241  }
242  os << ") hash=" << i << "\n";
243  }
244  os << "IdentifierHashTable has " << n << " entries.\n";
245  os << "\nSummary:\n";
246  os << "field min max size factor\n";
247  for ( unsigned int i = 0; i < NFIELDS; ++i ) {
248  os << std::setw(5) << i << " "
249  << std::setw(3) << m_fieldsMin[i] << " "
250  << std::setw(3) << m_fieldsMax[i] << " "
251  << std::setw(4) << m_fieldsSize[i] << " "
252  << std::setw(6) << m_fieldsFactor[i] << "\n";
253  }
254  os.flush();
255 }
256 
257 template <class T>
258 inline std::string IdentifierHashCalc<T>::dumpToString() const {
259  std::ostringstream oss;
260  dump( oss );
261  return oss.str();
262 }
263 
264 
265 
266 
267 #endif // MUONCALIBIDENTIFIER_IDENTIFIERHASHCALC_H
IdentifierHashCalc::getHash
HashType getHash(const IdType &id) const
Get hash from 0 to size()-1.
IdentifierHashCalc::m_idFields
T m_idFields
Definition: IdentifierHashCalc.h:77
IdentifierHashCalc::m_fieldsMin
int m_fieldsMin[NFIELDS]
Definition: IdentifierHashCalc.h:73
IdentifierHashCalc::addEntry
bool addEntry(const IdType &id)
Add an identifier to the table.
getMessageSvc.h
singleton-like access to IMessageSvc via open function and helper
IdentifierHashCalc::checkValidity
bool checkValidity() const
Check that the table is internally consistent.
IdentifierHashCalc::IdentifierHashCalc
IdentifierHashCalc()
Default constructor makes empty hash table.
IdentifierHashCalc::setFieldLimits
void setFieldLimits(unsigned int fieldIndex, int fieldMin, int fieldMax)
Set the limits of a specific field.
isValid
bool isValid(const T &p)
Definition: AtlasPID.h:214
IdentifierHashCalc::dumpToString
std::string dumpToString() const
Dump complete table into a string.
IdentifierHashCalc::dump
void dump(std::ostream &os=std::cout) const
Dump complete table to output stream.
Athena::getMessageSvc
IMessageSvc * getMessageSvc(bool quiet=false)
Definition: getMessageSvc.cxx:20
IdentifierHashCalc::m_fieldsMax
int m_fieldsMax[NFIELDS]
Definition: IdentifierHashCalc.h:74
IdentifierHashCalc::m_fieldsFactor
unsigned int m_fieldsFactor[NFIELDS]
Definition: IdentifierHashCalc.h:76
lumiFormat.i
int i
Definition: lumiFormat.py:92
beamspotman.n
n
Definition: beamspotman.py:731
endmsg
#define endmsg
Definition: AnalysisConfig_Ntuple.cxx:63
IdentifierHashCalc::update
void update()
IdentifierHashCalc::IdFieldsType
T IdFieldsType
define the type IdFieldsType
Definition: IdentifierHashCalc.h:39
IdentifierHashCalc::NMAX
@ NMAX
Definition: IdentifierHashCalc.h:37
IdentifierHashCalc::isInRange
bool isInRange(const T &idFields) const
IdentifierHashCalc::IdentifierHashCalc
IdentifierHashCalc(const T &idFields)
Make empty table with pointer set to external idHelper, which will be transmitted to the constructor ...
IdentifierHashCalc::NFIELDS
@ NFIELDS
Definition: IdentifierHashCalc.h:37
ReadFromCoolCompare.os
os
Definition: ReadFromCoolCompare.py:231
IdentifierHashCalc::IdType
T::IdentifierType IdType
define the type IdType
Definition: IdentifierHashCalc.h:41
IdentifierHashCalc::clear
void clear()
Clear the hashtable.
CaloCondBlobAlgs_fillNoiseFromASCII.hash
dictionary hash
Definition: CaloCondBlobAlgs_fillNoiseFromASCII.py:109
IdentifierHashCalc::m_fieldsSize
unsigned int m_fieldsSize[NFIELDS]
Definition: IdentifierHashCalc.h:75
DEBUG
#define DEBUG
Definition: page_access.h:11
python.CaloCondTools.log
log
Definition: CaloCondTools.py:20
IdentifierHashCalc
Definition: IdentifierHashCalc.h:29
IdentifierHashCalc::HashType
T::HashType HashType
define the type HashType
Definition: IdentifierHashCalc.h:43
IdentifierHashCalc::size
unsigned int size() const
Number of hashes in the table.
CaloCondBlobAlgs_fillNoiseFromASCII.fields
fields
Definition: CaloCondBlobAlgs_fillNoiseFromASCII.py:106
IdentifierHashCalc::getIdentifier
IdType getIdentifier(const HashType &idHash) const
Get identifier from hash.
TSU::T
unsigned long long T
Definition: L1TopoDataTypes.h:35