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