emcTowerContainerT.h

Go to the documentation of this file.
00001 #ifndef __EMCTOWERCONTAINERT_H__
00002 #define __EMCTOWERCONTAINERT_H__
00003 
00004 #ifndef __EMCTOWERCONTAINER_H__
00005 #include "emcTowerContainer.h"
00006 #endif
00007 #include <map>
00008 
00009 class TClonesArray;
00010 
00038 template<class T>
00039 class emcTowerContainerT : public emcTowerContainer
00040 {
00041 public:
00042 
00043   emcTowerContainerT();
00044 
00045   emcTowerContainerT(unsigned int defaultsize);
00046 
00047   emcTowerContainerT(const emcTowerContainerT&);
00048 
00049   emcTowerContainerT& operator=(const emcTowerContainerT&);
00050 
00051   emcTowerContainerT* clone(void) const;
00052 
00053   emcTowerContainerT* create(void) const;
00054 
00055   virtual ~emcTowerContainerT();
00056 
00057   unsigned int capacity(void) const;
00058 
00059   T* addTower(unsigned int i);
00060 
00061   T* addTower(unsigned int i, const emcTowerContent&);
00062 
00063   T* findTower(int towerID) const;
00064 
00065   T* getTower(unsigned int i) const;
00066 
00067   void identify(std::ostream& os=std::cout) const;
00068 
00069   int isValid() const;
00070 
00071   bool removeTower(unsigned int i);
00072 
00073   void Reset();
00074 
00075   bool resize(unsigned int newsize);
00076 
00077   unsigned int size(void) const;
00078 
00079 protected:
00080 
00081   TClonesArray* fEmcTowers;
00082 
00083 private:
00084   void allocate(unsigned int thesize);
00085   void copy(emcTowerContainerT& dest) const;
00086   bool expand(unsigned int);
00087   bool expand_for(unsigned int);
00088 
00089   static const unsigned int fgDefaultSize;
00090   static const unsigned int fgMaxSize;
00091 
00092   mutable std::map<int,int> fTowerIdToIndex; 
00093   mutable bool fTowerIdToIndexIsUpToDate; 
00094 
00095   ClassDef(emcTowerContainerT,1) // Array of T
00096 };
00097 
00098 //_____________________________________________________________________________
00099 //_____________________________________________________________________________
00100 //_____________________________________________________________________________
00101 
00102 #include "TClonesArray.h"
00103 #include "TClass.h"
00104 #include <iostream>
00105 #include <algorithm>
00106 #include "phool.h"
00107 
00108 template<class T> 
00109 const unsigned int emcTowerContainerT<T>::fgMaxSize = 24768;
00110 template<class T> 
00111 const unsigned int emcTowerContainerT<T>::fgDefaultSize = 1000;
00112 
00113 //_____________________________________________________________________________
00114 template<class T>
00115 emcTowerContainerT<T>::emcTowerContainerT() 
00116   : fEmcTowers(0), 
00117     fTowerIdToIndexIsUpToDate(false)
00118 {
00119   allocate(emcTowerContainerT::fgDefaultSize);
00120 }
00121 
00122 //_____________________________________________________________________________
00123 template<class T>
00124 emcTowerContainerT<T>::emcTowerContainerT(unsigned int defaultsize) 
00125   : emcTowerContainer(),
00126     fEmcTowers(0), 
00127     fTowerIdToIndexIsUpToDate(false)
00128 {
00129   allocate(defaultsize);
00130 }
00131 
00132 //_____________________________________________________________________________
00133 template<class T>
00134 emcTowerContainerT<T>::emcTowerContainerT(const emcTowerContainerT& o) 
00135   : emcTowerContainer(),
00136     fEmcTowers(0),
00137     fTowerIdToIndexIsUpToDate(false)
00138 {
00139   o.copy(*this);
00140 }
00141 
00142 //_____________________________________________________________________________
00143 template<class T>
00144 emcTowerContainerT<T>&
00145 emcTowerContainerT<T>::operator=(const emcTowerContainerT& o)
00146 {
00147   if ( this != &o )
00148     {
00149       o.copy(*this);
00150     }
00151   return *this;
00152 }
00153 
00154 //_____________________________________________________________________________
00155 template<class T>
00156 emcTowerContainerT<T>::~emcTowerContainerT()
00157 {
00158   delete fEmcTowers;
00159 }
00160 
00161 //_____________________________________________________________________________
00162 template<class T>
00163 T*
00164 emcTowerContainerT<T>::addTower(unsigned int i)
00165 {
00166   if ( i >= capacity() )
00167     {
00168       bool ok = expand_for(i);
00169       if (!ok) 
00170         {
00171           std::cerr << PHWHERE << " object is full ?!" << std::endl;
00172           return 0;
00173         }
00174     }
00175 
00176   fTowerIdToIndexIsUpToDate = false;
00177 
00178   return new((*fEmcTowers)[i]) T;
00179 }
00180 
00181 //_____________________________________________________________________________
00182 template<class T>
00183 T*
00184 emcTowerContainerT<T>::addTower(unsigned int i, const emcTowerContent& t)
00185 {
00186   const T* test = 
00187     dynamic_cast<const T*>(&t);
00188 
00189   if (!test) 
00190     {
00191       std::cerr << PHWHERE << " emcTowerContent is not of type v3" << std::endl;
00192       return 0;
00193     }
00194 
00195   if ( i >= capacity() )
00196     {
00197       bool ok = expand_for(i);
00198       if (!ok) 
00199         {
00200           std::cerr << PHWHERE << " object is full ?!" << std::endl;
00201           return 0;
00202         }
00203     }
00204 
00205   fTowerIdToIndexIsUpToDate = false;
00206 
00207   return new((*fEmcTowers)[i]) T(*test);
00208 }
00209 
00210 //_____________________________________________________________________________
00211 template<class T>
00212 void
00213 emcTowerContainerT<T>::allocate(unsigned int thesize)
00214 {
00215   delete fEmcTowers;
00216   fEmcTowers = new TClonesArray(T::Class()->GetName(),thesize);
00217   fTowerIdToIndexIsUpToDate = false;
00218 }
00219 
00220 //_____________________________________________________________________________
00221 template<class T>
00222 unsigned int
00223 emcTowerContainerT<T>::capacity(void) const
00224 { 
00225   return fEmcTowers->GetSize(); 
00226 }
00227 
00228 //_____________________________________________________________________________
00229 template<class T>
00230 emcTowerContainerT<T>*
00231 emcTowerContainerT<T>::clone(void) const
00232 {
00233   return new emcTowerContainerT<T>(*this);
00234 }
00235 
00236 //_____________________________________________________________________________
00237 template<class T>
00238 emcTowerContainerT<T>*
00239 emcTowerContainerT<T>::create(void) const
00240 {
00241   return new emcTowerContainerT<T>;
00242 }
00243 
00244 //_____________________________________________________________________________
00245 template<class T>
00246 void
00247 emcTowerContainerT<T>::copy(emcTowerContainerT& dest) const
00248 {
00249   TClonesArray* destarray = dest.fEmcTowers;
00250   if ( !destarray ) 
00251     {
00252       dest.allocate(fEmcTowers->GetSize());
00253       destarray = dest.fEmcTowers;
00254     }
00255   else
00256     {
00257       dest.Reset();
00258     }
00259 
00260   unsigned int idest = 0;
00261 
00262   for ( unsigned int i = 0; i < size(); ++i ) 
00263     {
00264       T* tower = dest.addTower(idest++);
00265       *tower = *(getTower(i));
00266     }
00267 
00268   dest.fTowerIdToIndexIsUpToDate = fTowerIdToIndexIsUpToDate;
00269   dest.fTowerIdToIndex = fTowerIdToIndex;
00270 }
00271 
00272 //_____________________________________________________________________________
00273 template<class T>
00274 bool
00275 emcTowerContainerT<T>::expand(unsigned int newcap)
00276 {
00277   if ( newcap <= fgMaxSize ) 
00278     {
00279       fEmcTowers->Expand(newcap);
00280       return true;
00281     }
00282   else
00283     {
00284       std::cerr << "emcTowerContainerT<T>::expand : "
00285                 << " attemting to go above max capacity of "
00286                 << fgMaxSize << ". That's a *big* failure "
00287                 << "probably"
00288                 << std::endl;
00289       return false;
00290     }
00291 }
00292 
00293 //_____________________________________________________________________________
00294 template<class T>
00295 bool
00296 emcTowerContainerT<T>::expand_for(unsigned int index)
00297 {
00298   unsigned int capa = capacity();
00299 
00300   while ( index >= capa && capa < fgMaxSize ) 
00301     {
00302       capa = std::min(capa*2,fgMaxSize);
00303     }
00304   if ( index >= capa )
00305     {
00306       return false;
00307     }
00308   else
00309     {
00310       assert(capa>capacity());
00311       return expand(capa);
00312     }
00313 }
00314 
00315 //_____________________________________________________________________________
00316 template<class T>
00317 T*
00318 emcTowerContainerT<T>::findTower(int towerID) const
00319 {
00320   if ( !fTowerIdToIndexIsUpToDate )
00321     {
00322       fTowerIdToIndex.clear();
00323       for ( size_t i = 0; i < size(); ++i ) 
00324         {
00325           fTowerIdToIndex[getTower(i)->TowerID()] = i;
00326         }
00327       fTowerIdToIndexIsUpToDate=true;
00328     }
00329 
00330   std::map<int,int>::const_iterator it = fTowerIdToIndex.find(towerID);
00331   if ( it != fTowerIdToIndex.end() )
00332     {
00333       return getTower(it->second);
00334     }
00335   else
00336     {
00337       return 0;
00338     }
00339 }
00340 
00341 //_____________________________________________________________________________
00342 template<class T>
00343 T*
00344 emcTowerContainerT<T>::getTower(unsigned int i) const
00345 {
00346   return static_cast<T*>(fEmcTowers->At(i));
00347 }
00348 
00349 //_____________________________________________________________________________
00350 template<class T>
00351 void
00352 emcTowerContainerT<T>::identify(ostream& os) const
00353 {
00354   os << "emcTowerContainerT<"
00355      << T::Class()->GetName() 
00356      << ">::identify : size=" << size() 
00357      << " capacity=" << capacity() << std::endl;
00358 }
00359 
00360 //_____________________________________________________________________________
00361 template<class T>
00362 int
00363 emcTowerContainerT<T>::isValid() const
00364 {
00365   return 1;
00366 }
00367 
00368 //_____________________________________________________________________________
00369 template<class T>
00370 void
00371 emcTowerContainerT<T>::Reset()
00372 {
00373   fEmcTowers->Clear();
00374   fTowerIdToIndex.clear();
00375   fTowerIdToIndexIsUpToDate=false;
00376 }
00377 
00378 //_____________________________________________________________________________
00379 template<class T>
00380 bool
00381 emcTowerContainerT<T>::removeTower(unsigned int i)
00382 {
00383   if ( i < size() ) 
00384     {
00385       fEmcTowers->RemoveAt(i);
00386       fEmcTowers->Compress();
00387       fTowerIdToIndexIsUpToDate=false;
00388       return true;
00389     }
00390   else
00391     {
00392       return false;
00393     }
00394 }
00395 
00396 //_____________________________________________________________________________
00397 template<class T>
00398 bool
00399 emcTowerContainerT<T>::resize(unsigned int newsize)
00400 {
00401   Reset();
00402   if ( newsize < size() )
00403     {
00404       fEmcTowers->Expand(newsize);
00405       return true;
00406     }
00407   else
00408     {
00409       return expand(newsize);
00410     }
00411 }
00412 
00413 //_____________________________________________________________________________
00414 template<class T>
00415 unsigned int
00416 emcTowerContainerT<T>::size(void) const
00417 {
00418   return fEmcTowers->GetLast()+1;
00419 }
00420 
00421 #endif