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)
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