emcClusterContainerT.h

Go to the documentation of this file.
00001 #ifndef __emcClusterContainerT_h__
00002 #define __emcClusterContainerT_h__
00003 
00004 #include "emcClusterContent.h"
00005 #include "emcClusterContainer.h"
00006 #include <cassert>
00007 
00008 class TClonesArray;
00009 
00014 template<class T>
00015 class emcClusterContainerT : public emcClusterContainer
00016 {
00017 public:
00018 
00019   emcClusterContainerT();
00020   emcClusterContainerT(unsigned int defaultsize);
00021   emcClusterContainerT(const emcClusterContainerT&);
00022   emcClusterContainerT& operator=(const emcClusterContainerT&);
00023 
00024   unsigned int capacity(void) const;
00025 
00026   emcClusterContainerT* clone(void) const;
00027   emcClusterContainerT* create(void) const;
00028 
00029   virtual ~emcClusterContainerT();
00030 
00031   T* addCluster(unsigned int i);
00032   
00033   T* addCluster(unsigned int i, const emcClusterContent& c);
00034   
00035   T* findCluster(int clusterid) const;
00036 
00037   T* getCluster(unsigned int i) const;
00038 
00039   void identify(std::ostream& os=std::cout) const;
00040 
00041   int isValid() const;
00042 
00043   bool removeCluster(unsigned int i) ;
00044 
00045   void Reset();
00046 
00047   bool resize(unsigned int newsize);
00048 
00049   unsigned int size(void) const;
00050 
00051 protected:
00052 
00053   TClonesArray* fEmcClusters;
00054 
00055 private:
00056   void allocate(unsigned int thesize);
00057   void copy(emcClusterContainerT<T>& dest) const;
00058   void clear(TClonesArray& array);
00059   bool expand(unsigned int);
00060   bool expand_for(unsigned int);
00061 
00062   static const unsigned int fgDefaultSize;
00063   static const unsigned int fgMaxSize;
00064 
00065   ClassDef(emcClusterContainerT,1) // Template of an array of emcClusterContent
00066 };
00067 
00068 //_____________________________________________________________________________
00069 //_____________________________________________________________________________
00070 //_____________________________________________________________________________
00071 
00072 #include "phool.h"
00073 #include "TClass.h"
00074 #include <iostream>
00075 #include <algorithm>
00076 #include "TClonesArray.h"
00077 
00078 template<class T>
00079 const unsigned int emcClusterContainerT<T>::fgDefaultSize = 1000;
00080 
00081 template<class T>
00082 const unsigned int emcClusterContainerT<T>::fgMaxSize = 24768;
00083 
00084 //_____________________________________________________________________________
00085 template<class T>
00086 emcClusterContainerT<T>::emcClusterContainerT() : fEmcClusters(0)
00087 {
00088   allocate(emcClusterContainerT<T>::fgDefaultSize);
00089 }
00090 
00091 //_____________________________________________________________________________
00092 template<class T>
00093 emcClusterContainerT<T>::emcClusterContainerT(unsigned int defaultsize) 
00094   : fEmcClusters(0)
00095 {
00096   allocate(defaultsize);
00097 }
00098 //_____________________________________________________________________________
00099 template<class T>
00100 emcClusterContainerT<T>::emcClusterContainerT(const emcClusterContainerT<T>& o) 
00101   : fEmcClusters(0)
00102 {
00103   o.copy(*this);
00104 }
00105 
00106 //_____________________________________________________________________________
00107 template<class T>
00108 emcClusterContainerT<T>&
00109 emcClusterContainerT<T>::operator=(const emcClusterContainerT<T>& o)
00110 {
00111   if ( this != &o )
00112     {
00113       Reset();
00114       o.copy(*this);
00115     }
00116   return *this;
00117 }
00118 
00119 //_____________________________________________________________________________
00120 template<class T>
00121 emcClusterContainerT<T>::~emcClusterContainerT()
00122 {
00123   clear(*fEmcClusters);
00124   delete fEmcClusters;
00125 }
00126 
00127 //_____________________________________________________________________________
00128 template<class T>
00129 T*
00130 emcClusterContainerT<T>::addCluster(unsigned int i)
00131 {
00132   if ( i > capacity() )
00133     {
00134       bool ok = expand_for(i);
00135       if (!ok) 
00136         {
00137           std::cerr << PHWHERE << " object is full ?!" << std::endl;
00138           return 0;
00139         }
00140     }
00141 
00142   return new((*fEmcClusters)[i]) T;
00143 }
00144 
00145 //_____________________________________________________________________________
00146 template<class T>
00147 T*
00148 emcClusterContainerT<T>::addCluster(unsigned int i, const emcClusterContent& c)
00149 {
00150   const T* test = 
00151     dynamic_cast<const T*>(&c);
00152 
00153   if (!test)
00154     {
00155       std::cerr << PHWHERE << " emcClusterContent is not of type "
00156                 << T::Class()->GetName() << std::endl;
00157       return 0;
00158     }
00159 
00160   if ( i >= capacity() )
00161     {
00162       bool ok = expand_for(i);
00163       if (!ok) 
00164         {
00165           std::cerr << PHWHERE << " object is full ?!" << std::endl;
00166           return 0;
00167         }
00168     }
00169 
00170   return new((*fEmcClusters)[i]) T(*test);
00171 }
00172 
00173 //_____________________________________________________________________________
00174 template<class T>
00175 void
00176 emcClusterContainerT<T>::allocate(unsigned int thesize)
00177 {
00178   if (fEmcClusters)
00179     {
00180       clear(*fEmcClusters);
00181       delete fEmcClusters;
00182     }
00183   fEmcClusters = new TClonesArray(T::Class()->GetName(),thesize);
00184 }
00185 
00186 //_____________________________________________________________________________
00187 template<class T>
00188 unsigned int
00189 emcClusterContainerT<T>::capacity(void) const
00190 { 
00191   return fEmcClusters->GetSize(); 
00192 }
00193 
00194 
00195 //_____________________________________________________________________________
00196 template<class T>
00197 void emcClusterContainerT<T>::clear(TClonesArray& array)
00198 {
00199 #if ROOT_VERSION_CODE > ROOT_VERSION(3,01,5)
00200     // for recent version, it's taken care of by ROOT itself. Easy.
00201     array.Clear("C");
00202 #else
00203 #  pragma error "Code not valid for this old version of root"
00204 #endif
00205 }
00206 
00207 //_____________________________________________________________________________
00208 template<class T>
00209 emcClusterContainerT<T>*
00210 emcClusterContainerT<T>::clone(void) const
00211 {
00212   return new emcClusterContainerT<T>(*this);
00213 }
00214 
00215 //_____________________________________________________________________________
00216 template<class T>
00217 emcClusterContainerT<T>*
00218 emcClusterContainerT<T>::create(void) const
00219 {
00220   return new emcClusterContainerT<T>(*this);
00221 }
00222 
00223 //_____________________________________________________________________________
00224 template<class T>
00225 void
00226 emcClusterContainerT<T>::copy(emcClusterContainerT<T>& dest) const
00227 {
00228   TClonesArray* destarray = dest.fEmcClusters;
00229   if ( !destarray ) 
00230     {
00231       dest.allocate(fEmcClusters->GetSize());
00232       destarray = dest.fEmcClusters;
00233     }
00234   else
00235     {
00236       dest.Reset();
00237     }
00238 
00239   unsigned int idest = 0;
00240 
00241   for ( unsigned int i = 0; i < size(); ++i ) 
00242     {
00243       T* cluster = dest.addCluster(idest++);
00244       *cluster = *(getCluster(i));
00245     }
00246 }
00247 
00248 //_____________________________________________________________________________
00249 template<class T>
00250 bool
00251 emcClusterContainerT<T>::expand(unsigned int newcap)
00252 {
00253   if ( newcap <= fgMaxSize ) 
00254     {
00255       fEmcClusters->Expand(newcap);
00256       return true;
00257     }
00258   else
00259     {
00260       std::cerr << "emcClusterContainerT<" << T::Class()->GetName()
00261                 << ">::expand : "
00262                 << " attemting to go above max capacity of "
00263                 << fgMaxSize << ". That's a *big* failure "
00264                 << "probably"
00265                 << std::endl;
00266       return false;
00267     }
00268 }
00269 
00270 //_____________________________________________________________________________
00271 template<class T>
00272 bool
00273 emcClusterContainerT<T>::expand_for(unsigned int index)
00274 {
00275   unsigned int capa = capacity();
00276 
00277   while ( index >= capa && capa < fgMaxSize ) 
00278     {
00279       capa = std::min(capa*2,fgMaxSize);
00280     }
00281   if ( index >= capa )
00282     {
00283       return false;
00284     }
00285   else
00286     {
00287       assert(capa>capacity());
00288       return expand(capa);
00289     }
00290 }
00291 
00292 //_____________________________________________________________________________
00293 template<class T>
00294 T*
00295 emcClusterContainerT<T>::findCluster(int clusterid) const
00296 {
00297   for ( size_t i = 0; i < size(); ++i ) 
00298     {
00299       if ( getCluster(i)->id() == clusterid ) 
00300         {
00301           return getCluster(i);
00302         }
00303     }
00304   return 0;
00305 }
00306 
00307 //_____________________________________________________________________________
00308 template<class T>
00309 T*
00310 emcClusterContainerT<T>::getCluster(unsigned int i) const
00311 {
00312   return static_cast<T*>(fEmcClusters->At(i));
00313 }
00314 
00315 //_____________________________________________________________________________
00316 template<class T>
00317 void
00318 emcClusterContainerT<T>::identify(ostream& os) const
00319 {
00320   std::cout << "emcClusterContainerT<" << T::Class()->GetName()
00321             << ">::identify : size=" << size() 
00322             << " capacity=" << capacity() << std::endl;
00323 }
00324 
00325 //_____________________________________________________________________________
00326 template<class T>
00327 int
00328 emcClusterContainerT<T>::isValid() const
00329 {
00330   return 1;
00331 }
00332 
00333 //_____________________________________________________________________________
00334 template<class T>
00335 void
00336 emcClusterContainerT<T>::Reset()
00337 {
00338   clear(*fEmcClusters);
00339 }
00340 
00341 //_____________________________________________________________________________
00342 template<class T>
00343 bool
00344 emcClusterContainerT<T>::removeCluster(unsigned int i)
00345 {
00346   if ( i < size() ) 
00347     {
00348       fEmcClusters->RemoveAt(i);
00349       fEmcClusters->Compress();
00350       return true;
00351     }
00352   else
00353     {
00354       return false;
00355     }
00356 }
00357 
00358 //_____________________________________________________________________________
00359 template<class T>
00360 bool
00361 emcClusterContainerT<T>::resize(unsigned int newsize)
00362 {
00363   Reset();
00364   if ( newsize < size() )
00365     {
00366       fEmcClusters->Expand(newsize);
00367       return true;
00368     }
00369   else
00370     {
00371       return expand(newsize);
00372     }
00373 }
00374 
00375 //_____________________________________________________________________________
00376 template<class T>
00377 unsigned int
00378 emcClusterContainerT<T>::size(void) const
00379 {
00380   return fEmcClusters->GetLast()+1;
00381 }
00382 
00383 #endif