ATLAS Offline Software
Loading...
Searching...
No Matches
MultChanContainer.h
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
25// $Id: MultChanContainer.h,v 1.8 2009-03-13 10:14:59 dwhittin Exp $
26
27#ifndef TRTCONDITIONSDATA_MULTCHANNELCONTAINERDEFAULT_H
28#define TRTCONDITIONSDATA_MULTCHANNELCONTAINERDEFAULT_H
29
33#include "GaudiKernel/MsgStream.h"
34#include <cxxabi.h>
35#include <algorithm>
36#include <stdexcept>
37
38namespace TRTCond
39{
40
43 template <class DaughterContainer>
44 class MultChanContainer : public CondMultChanCollection<DaughterContainer>
45 {
46 public:
49
53
54 StatusCode initialize();
55
56
58 size_t channelId( const ExpandedIdentifier& x ) const ;
59
61 size_t layerwheelindex( size_t channelid ) const ;
62
64 size_t barrelecindex( size_t channelid ) const ;
65
67 DaughterContainer* findContainer(const ExpandedIdentifier& id) ;
68 DaughterContainer* findContainer(size_t chanid) ;
69
71 const DaughterContainer* getContainer(size_t chanid) const ;
72
74 void set( const ExpandedIdentifier& id, const typename DaughterContainer::value_type& t) ;
75
77 const typename DaughterContainer::value_type& get( const ExpandedIdentifier& id ) const ;
78
80 const typename DaughterContainer::value_type& get( const ExpandedIdentifier& id , size_t& resolvelevel ) const ;
81
83 typedef std::pair< const DaughterContainer*, const typename DaughterContainer::value_type*> ContainerWithValue ;
85
87 void clear() ;
88
90 size_t footprint() const ;
91
93 void crunch() ;
94
96 void print() const ;
97
99 size_t numObjects() const ;
100
102 void getall( typename DaughterContainer::FlatContainer& entries ) const ;
103
105
106 private:
108 static const size_t m_defaultschannelid = 0 ;
110 std::vector<const DaughterContainer*> m_channelmap ;
112 const typename DaughterContainer::value_type& dummyVal() const;
113 } ;
114
115
117
118 // Dummy Value for empty DaughterContainer
121 template <class DaughterContainer>
122 inline const typename DaughterContainer::value_type&
124 {
125 static typename DaughterContainer::value_type dummyVal;
126 return dummyVal;
127 }
128
129 template <class DaughterContainer>
134
135template <class DaughterContainer>
138 {
139 clear() ;
142 for( ; rhsit != rhs.end(); ++rhsit, ++ rhschanit) {
143 DaughterContainer* lhscontainer = findContainer( *rhschanit ) ;
144 *lhscontainer = **rhsit ;
145 }
146 return *this ;
147 }
148
149
150 template <class DaughterContainer>
151 inline size_t
158
159
160 template <class DaughterContainer>
161 inline size_t
163 {
164 return channelid!=m_defaultschannelid ? (channelid-1)/4 : 99 ;
165 }
166
167
168 template <class DaughterContainer>
169 inline size_t
171 {
172 return channelid!=m_defaultschannelid ? (channelid-1)%4 : 99 ;
173 }
174
175
176 template <class DaughterContainer>
178 {
179 // on the first call, we insert a container for the default. the default is always the first container.
180 if( id.level()==ExpandedIdentifier::BARRELEC ) {
181 MsgStream log(Athena::getMessageSvc(),"TRTCond::MultChanContainer");
182 log << MSG::WARNING << "Sorry: cannot store containers at BARREL_EC granularity" << endmsg ;
183 }
184 return findContainer( channelId( id ) ) ;
185 }
186
187
188 template <class DaughterContainer>
189 inline DaughterContainer* MultChanContainer<DaughterContainer>::findContainer(size_t chanid)
190 {
191 // on the first call, we insert a container for the default. the default is always the first container.
192 if(this->size()==0) {
193 this->push_back( new DaughterContainer() ) ;
195 }
197 std::find( this->chan_begin(), this->chan_end(), chanid ) ;
198 auto chanindex = std::distance(this->chan_begin(),chanit) ;
199 if(chanit==this->chan_end()) {
200 // add a new container
201 this->push_back( new DaughterContainer() ) ;
202 this->add(chanid);
203 chanindex = this->size()-1 ; //std::distance(chan_begin(),chan_end())-1 ;
204 // make sure to clear the cache
205 m_channelmap.clear() ;
206 }
207 if (chanindex < 0 or chanindex >= std::ssize(*this)){
208 throw std::out_of_range("MultiChanContainer::findContainer chanindex out of range");
209 }
210 return this->operator[]( chanindex ) ;
211 }
212
213
214 template <class DaughterContainer>
215 inline const DaughterContainer* MultChanContainer<DaughterContainer>::getContainer(size_t chanid) const
216 {
217 //in the const-version to get the container we rely on the m_channelmap per-filled by initialize
218 //(to be thread-seafe)
219 return chanid < m_channelmap.size() ? m_channelmap[chanid] : nullptr ;
220 }
221
222 template <class DaughterContainer>
223 inline void MultChanContainer<DaughterContainer>::set( const ExpandedIdentifier& id, const typename DaughterContainer::value_type& t )
224 {
225 if( id.level()==ExpandedIdentifier::DETECTOR ) {
226 // set the default value. don't use the id, since it will only confuse the container
227 findContainer(id)->set( t ) ;
228 } else if( id.level()==ExpandedIdentifier::BARRELEC ) {
229 MsgStream log(Athena::getMessageSvc(),"TRTCond::MultChanContainer");
230 log << MSG::WARNING << "Sorry: cannot store containers at BARREL_EC granularity" << endmsg;
231 } else {
232 findContainer(id)->set( id, t ) ;
233 }
234 }
235
236 template <class DaughterContainer>
237 inline const typename DaughterContainer::value_type&
239 {
240 if( id.level() >= ExpandedIdentifier::LAYERWHEEL ) {
241 const DaughterContainer* container = getContainer( channelId(id) ) ;
242 if( container ) {
243 const typename DaughterContainer::value_type& rc = container->get( id ) ;
244 if( DaughterContainer::trait_type::isvalid(rc) ) return rc ;
245 }
246 }
247 // Throw error if the container is empty.
248 if ( this->size() == 0 ) {
249 size_t len;
250 int s;
251 char* tmp = abi::__cxa_demangle(typeid(this).name(),0,&len,&s);
252 std::string error = std::string(tmp) + std::string(" is empty!!");
253 throw std::runtime_error( error );
254 }
255 return this->front()->get() ;
256 //return operator[]( 0 )->set( t ) ;// m_default ;
257 }
258
259 template <class DaughterContainer>
260 inline const typename DaughterContainer::value_type&
261 MultChanContainer<DaughterContainer>::get( const ExpandedIdentifier& id , size_t& resolvelevel) const
262 {
263 if( id.level() >= ExpandedIdentifier::LAYERWHEEL ) {
264 const DaughterContainer* container = getContainer( channelId(id) ) ;
265 if( container ) {
266 const typename DaughterContainer::value_type& rc = container->get( id , resolvelevel) ;
267 if( DaughterContainer::trait_type::isvalid(rc) ) return rc ;
268 }
269 }
270 // Throw error if the container is empty.
271 if ( this->size() == 0 ) {
272 size_t len;
273 int s;
274 char* tmp = abi::__cxa_demangle(typeid(this).name(),0,&len,&s);
275 std::string error = std::string(tmp) + std::string(" is empty!!");
276 throw std::runtime_error( error );
277 return dummyVal();
278 }
279 return this->front()->get(id,resolvelevel) ;
280 }
281
283 template <class DaughterContainer>
286 {
287 if( id.level() >= ExpandedIdentifier::LAYERWHEEL ) {
288 const DaughterContainer* container = getContainer( channelId(id) ) ;
289 if( container ) {
290 const typename DaughterContainer::value_type& value = container->get( id ) ;
291 if( DaughterContainer::trait_type::isvalid(value) ) return ContainerWithValue(container,&value) ;
292 }
293 }
294 // Throw error if the container is empty.
295 if ( this->size() == 0 ) {
296 size_t len;
297 int s;
298 char* tmp = abi::__cxa_demangle(typeid(this).name(),0,&len,&s);
299 std::string error = std::string(tmp) + std::string(" is empty!!");
300 throw std::runtime_error( error );
301 }
302 return ContainerWithValue(this->front(),&(this->front()->get())) ;
303 }
304
305
306 template <class DaughterContainer>
308 {
310 it != this->end(); ++it) (*it)->clear() ;
311 }
312
313
314 template <class DaughterContainer>
316 size_t total=0; //= Trait::footprint(m_default) ;
318 it != this->end(); ++it) total += (*it)->footprint() ;
319 return total ;
320 }
321
322
323 template <class DaughterContainer>
326 it != this->end(); ++it) (*it)->crunch() ;
327 }
328
329
330 template <class DaughterContainer>
332 size_t rc(0) ;
334 it != this->end(); ++it) rc += (*it)->numObjects() ;
335 return rc ;
336 }
337
338
339 template <class DaughterContainer>
340 inline void MultChanContainer<DaughterContainer>::getall( typename DaughterContainer::FlatContainer& entries ) const {
343 for( ; dauit != this->end(); ++dauit, ++chanit) {
344 // get the entries in this subcontainer
345 typename DaughterContainer::FlatContainer newentries ;
346 (*dauit)->getall(newentries) ;
347 // update the identifiers
348 if( dauit == this->begin() ) {
349 // deal with the default value
350 for( typename DaughterContainer::FlatContainer::iterator it = newentries.begin() ; it!= newentries.end(); ++it)
352 } else {
353 for( typename DaughterContainer::FlatContainer::iterator it = newentries.begin() ; it!= newentries.end(); ++it) {
354 it->first.index(ExpandedIdentifier::BARRELEC) = barrelecindex( *chanit) ;
355 it->first.index(ExpandedIdentifier::LAYERWHEEL) = layerwheelindex( *chanit) ;
356 }
357 }
358 entries.insert( entries.end(), newentries.begin(), newentries.end() ) ;
359 }
360 }
361
362
363 template <class DaughterContainer>
367 for( ; dauit != this->end(); ++dauit, ++chanit) {
368 std::cout << "Now printing channel " << *chanit << " layer/becindex: " << layerwheelindex(*chanit) << " " << barrelecindex(*chanit) << std::endl ;
369 (*dauit)->print() ;
370 }
371 }
372
373
374
375 template <class DaughterContainer>
377
378 // sanity check to test we have added a default value
379 if( this->size()>0 && *(this->chan_begin()) != m_defaultschannelid ) {
380 MsgStream log(Athena::getMessageSvc(),"TRTCond::MultChanContainer");
381 log << MSG::ERROR << " first channel id is not defaults channel id!" << endmsg ;
382 }
383
384 // first get the max channel id
385 auto maxchan=std::max_element(this->chan_begin(),this->chan_end());
386 const size_t maxchanid= maxchan==this->chan_end() ? 0 : *maxchan;
387
388 // now allocate the map and fill it
389 m_channelmap.clear() ;
390 m_channelmap.resize( maxchanid + 1, nullptr ) ;
391 //typename CondMultChanCollection<DaughterContainer>::const_iterator dauit = this->begin() ;
392 auto dauit = this->begin() ;
393 for( auto chanit = this->chan_begin();chanit != this->chan_end(); ++chanit, ++dauit ) {
394 m_channelmap[*chanit] = *dauit ;
395 }
396 return StatusCode::SUCCESS;
397 }
398}
399#endif
#define endmsg
This file defines the template class used to register the tokens of T* in a COOL multchannel folder.
static Double_t rc
'Nested' template container for storing TRT conditions data.
#define x
ChanVec::const_iterator chan_const_iterator
chan_const_iterator chan_begin() const
Access to Channel numbers via iterators.
DataModel_detail::const_iterator< DataVector > const_iterator
Standard const_iterator.
Definition DataVector.h:838
const DaughterContainer * operator[](size_type n) const
value_type push_back(value_type pElem)
DataModel_detail::iterator< DataVector > iterator
Standard iterator.
Definition DataVector.h:842
const_iterator end() const noexcept
Return a const_iterator pointing past the end of the collection.
const_iterator begin() const noexcept
Return a const_iterator pointing at the beginning of the collection.
const DaughterContainer * front() const
Class for accessing NestedContainers via channels in a CondMultChanCollection.
void set(const ExpandedIdentifier &id, const typename DaughterContainer::value_type &t)
set a value
static const size_t m_defaultschannelid
now need various forwarding calls for CondMultChanCollection functionality
std::vector< const DaughterContainer * > m_channelmap
cached table for fast access from channel to layercontainer
MultChanContainer & operator=(const MultChanContainer &rhs)
DaughterContainer * findContainer(const ExpandedIdentifier &id)
find a layercontainer from an identifier.
void print() const
dump to standard output
size_t numObjects() const
total number of valid calibration objects
const DaughterContainer * getContainer(size_t chanid) const
get a layercontainer from a channel id.
size_t channelId(const ExpandedIdentifier &x) const
calculate the channel for a given TRT identifier
size_t barrelecindex(size_t channelid) const
calculate the barrel-ec index from a channel id.
size_t layerwheelindex(size_t channelid) const
calculate layer or wheel index from a channel id
void clear()
clear all layercontainers
const DaughterContainer::value_type & dummyVal() const
dummy value to return when DaughterContainer is empty
const DaughterContainer::value_type & get(const ExpandedIdentifier &id) const
get a value
void getall(typename DaughterContainer::FlatContainer &entries) const
get a flat vector with all values.
std::pair< const DaughterContainer *, const typename DaughterContainer::value_type * > ContainerWithValue
get a value with the corresponding container.
void crunch()
crunch the layercontainers.
size_t footprint() const
return the memory allocated by the layercontainers.
ContainerWithValue getWithContainer(const ExpandedIdentifier &id) const
for retrieving t0 values, we need also the container to 'unpack' the t0
StatusCode initialize()
Initialization done after creation or read back - derived classes may augment the functionality.
bool add(const std::string &hname, TKey *tobj)
Definition fastadd.cxx:55
singleton-like access to IMessageSvc via open function and helper
T * get(TKey *tobj)
get a TObject* from a TKey* (why can't a TObject be a TKey?)
Definition hcg.cxx:130
double entries
Definition listroot.cxx:49
IMessageSvc * getMessageSvc(bool quiet=false)