Coverity fixes
[u/mrichter/AliRoot.git] / MUON / AliMUONClusterStoreV2.cxx
1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3 *                                                                        *
4 * Author: The ALICE Off-line Project.                                    *
5 * Contributors are mentioned in the code where appropriate.              *
6 *                                                                        *
7 * Permission to use, copy, modify and distribute this software and its   *
8 * documentation strictly for non-commercial purposes is hereby granted   *
9 * without fee, provided that the above copyright notice appears in all   *
10 * copies and that both the copyright notice and this permission notice   *
11 * appear in the supporting documentation. The authors make no claims     *
12 * about the suitability of this software for any purpose. It is          *
13 * provided "as is" without express or implied warranty.                  *
14 **************************************************************************/
15
16 // $Id$
17
18 //-----------------------------------------------------------------------------
19 /// \class AliMUONClusterStoreV2
20 ///
21 /// Implementation of VClusterStore.
22 ///
23 /// Note that clusters are identified by their UniqueID, so it MUST be correctly set
24 ///
25 /// \author Philippe Pillot, Subatech
26 ///
27 //-----------------------------------------------------------------------------
28
29 #include "AliMUONClusterStoreV2.h"
30
31 #include "AliMUONRawClusterV2.h"
32 #include "AliMUONClusterStoreV2Iterator.h"
33 #include "AliMUONTreeManager.h"
34 #include "AliMpConstants.h"
35 #include "AliMpExMap.h"
36
37 #include "AliLog.h"
38
39 #include <TTree.h>
40
41 #include <Riostream.h>
42
43 /// \cond CLASSIMP
44 ClassImp(AliMUONClusterStoreV2)
45 /// \endcond
46
47 //_____________________________________________________________________________
48 AliMUONClusterStoreV2::AliMUONClusterStoreV2() 
49 : AliMUONVClusterStore(), 
50   fClusters(new TClonesArray("AliMUONRawClusterV2",100)),
51   fMap(0x0),
52   fMapped(kFALSE)
53 {
54   /// Constructor
55 }
56
57 //_____________________________________________________________________________
58 AliMUONClusterStoreV2::AliMUONClusterStoreV2(const AliMUONClusterStoreV2& store)
59 : AliMUONVClusterStore(), 
60   fClusters(new TClonesArray(*(store.fClusters))),
61   fMap(0x0),
62   fMapped(kFALSE)
63 {
64   /// Copy constructor
65   if (store.fMapped) ReMap();
66 }
67
68 //_____________________________________________________________________________
69 AliMUONClusterStoreV2& AliMUONClusterStoreV2::operator=(const AliMUONClusterStoreV2& store)
70 {
71   /// Assignment operator
72   if ( this != &store )
73   {
74     fClusters = new TClonesArray(*(store.fClusters));
75     fMap = 0x0;
76     fMapped = kFALSE;
77     if (store.fMapped) ReMap();
78   }
79   return *this;
80 }
81
82 //_____________________________________________________________________________
83 AliMUONClusterStoreV2::~AliMUONClusterStoreV2()
84 {
85   /// Destructor
86   delete fClusters;
87   delete fMap;
88 }
89
90 //_____________________________________________________________________________
91 void AliMUONClusterStoreV2::Clear(Option_t*)
92 {
93   /// Clear the internal cluster array AND the index
94   fClusters->Clear("C");
95   if (fMap) {
96     Int_t nChamber = AliMpConstants::NofTrackingChambers();
97     for (Int_t chamber=0; chamber<nChamber; chamber++) {
98       AliMpExMap *map = static_cast<AliMpExMap *>(fMap->UncheckedAt(chamber));
99       map->Clear("C");
100     }
101     fMapped = kFALSE;
102   }
103 }
104
105 //_____________________________________________________________________________
106 Bool_t AliMUONClusterStoreV2::Connect(TTree& tree, Bool_t alone) const
107 {
108   /// Connect this to the tree, i.e. make the branches or set their addresses.
109   
110   AliMUONTreeManager tman;
111   
112   if (tree.GetBranch("MUONRawClusters")) {
113     
114     if (alone) tman.UpdateBranchStatuses(tree,"MUONRawClusters");
115     
116     return tman.SetAddress(tree,"MUONRawClusters", 
117                          const_cast<TClonesArray**>(&fClusters));
118   } else {
119     
120     return tman.MakeBranch(tree,ClassName(),"TClonesArray", "MUONRawClusters",
121                          const_cast<TClonesArray**>(&fClusters));
122   }
123     
124 }
125
126 //_____________________________________________________________________________
127 AliMUONVCluster* AliMUONClusterStoreV2::CreateCluster(Int_t chamberId, Int_t detElemId, Int_t clusterIndex) const
128 {
129   /// Create a cluster
130   return new AliMUONRawClusterV2(chamberId, detElemId, clusterIndex);
131 }
132
133 //_____________________________________________________________________________
134 AliMUONVCluster* AliMUONClusterStoreV2::Add(const AliMUONVCluster& vCluster)
135 {
136   /// Add a cluster to this store
137   const AliMUONRawClusterV2* cluster = dynamic_cast<const AliMUONRawClusterV2*>(&vCluster);
138   
139   if (!cluster) {
140     AliError(Form("Cluster is not of the expected type (%s vs AliMUONRawClusterV2)",
141                   vCluster.ClassName()));
142     return 0x0;
143   }
144   
145   // check chamberId
146   Int_t chamberId = cluster->GetChamberId();
147   if (chamberId < 0 || chamberId >= AliMpConstants::NofTrackingChambers()) {
148     AliError(Form("ChamberId (%d) out of boundaries [0,%d[",chamberId,AliMpConstants::NofTrackingChambers()));
149     return 0x0;
150   }
151   
152   // check that there is no cluster with the same Id
153   AliMUONVCluster *c = FindObject(cluster->GetUniqueID());
154   if (c) {
155     AliError("cluster store already contains a cluster with the same ID --> add() exited:");
156     c->Print("FULL");
157     return 0x0;
158   }
159   
160   // add new cluster
161   c = new((*fClusters)[fClusters->GetLast()+1]) AliMUONRawClusterV2(*cluster);
162   
163   if (c) UpdateMap(*c);
164   
165   return c;
166 }
167
168 //_____________________________________________________________________________
169 AliMUONVCluster* AliMUONClusterStoreV2::Add(Int_t chamberId, Int_t detElemId, Int_t clusterIndex)
170 {
171   /// Add an empty cluster with an unique ID to this store
172   
173   // check chamberId
174   if (chamberId < 0 || chamberId >= AliMpConstants::NofTrackingChambers()) {
175     AliError(Form("ChamberId (%d) out of boundaries [0,%d[",chamberId,AliMpConstants::NofTrackingChambers()));
176     return 0x0;
177   }
178   
179   // check that there is no cluster with the same Id
180   AliMUONVCluster *c = FindObject(AliMUONVCluster::BuildUniqueID(chamberId, detElemId, clusterIndex));
181   if (c) {
182     AliError("cluster store already contains a cluster with the same ID --> add() exited:");
183     c->Print("FULL");
184     return 0x0;
185   }
186   
187   // add new cluster
188   c = new((*fClusters)[fClusters->GetLast()+1]) AliMUONRawClusterV2(chamberId, detElemId, clusterIndex);
189   
190   if (c) UpdateMap(*c);
191   
192   return c;
193 }
194
195 //_____________________________________________________________________________
196 AliMUONVCluster* AliMUONClusterStoreV2::Remove(AliMUONVCluster& cluster)
197 {
198   /// Remove a cluster
199   AliMUONVCluster* c = static_cast<AliMUONVCluster*>(fClusters->Remove(&cluster));
200   
201   if (c) 
202   {
203     fClusters->Compress();
204     fMapped = kFALSE;
205   }
206   else
207   {
208     AliError("Could not remove cluster from array");
209   }
210   
211   return c;
212 }
213
214 //_____________________________________________________________________________
215 void AliMUONClusterStoreV2::ReMap()
216 {
217   /// Recompute the fMap, which map (ch) to an index within the fClusters array
218   fMapped = kTRUE;
219   
220   // Create (or clear) the TClonesArray of map
221   Int_t nChamber = AliMpConstants::NofTrackingChambers();
222   
223   if (!fMap) {
224     fMap = new TClonesArray("AliMpExMap",nChamber);
225     
226     // Create one map per chamber
227     AliMpExMap *map;
228     for (Int_t chamber=0; chamber<nChamber; chamber++) {
229       map = new((*fMap)[chamber]) AliMpExMap;
230       map->SetOwner(kFALSE);
231     }
232   }
233   else {
234     for (Int_t chamber=0; chamber<nChamber; chamber++) {
235       AliMpExMap *map = static_cast<AliMpExMap *>(fMap->UncheckedAt(chamber));
236       map->Clear("C");
237     }
238   }  
239
240   // Fill the maps
241   TIter next(fClusters);
242   AliMUONVCluster* cluster;
243   while ( (cluster = static_cast<AliMUONVCluster*>(next())) ) UpdateMap(*cluster);
244 }
245
246 //_____________________________________________________________________________
247 void AliMUONClusterStoreV2::UpdateMap(AliMUONVCluster& cluster)
248 {
249   /// Update the internal index given this new cluster
250   if (fMapped) static_cast<AliMpExMap*>(fMap->UncheckedAt(cluster.GetChamberId()))->Add(cluster.GetUniqueID(),&cluster);
251   else ReMap();
252 }
253
254 //_____________________________________________________________________________
255 AliMUONVCluster* AliMUONClusterStoreV2::FindObject(const TObject* object) const
256 {
257   /// Find an object, if of AliMUONVCluster type.
258   const AliMUONVCluster* cluster = dynamic_cast<const AliMUONVCluster*>(object);
259   if (cluster) return FindObject(cluster->GetUniqueID());
260   return 0x0;
261 }
262
263 //_____________________________________________________________________________
264 AliMUONVCluster* AliMUONClusterStoreV2::FindObject(UInt_t uniqueID) const
265 {
266   /// Find a cluster by its UniqueID
267   if (!fMapped) (const_cast<AliMUONClusterStoreV2*>(this))->ReMap();
268   AliMpExMap* map = static_cast<AliMpExMap*>(fMap->UncheckedAt(AliMUONVCluster::GetChamberId(uniqueID)));
269   return static_cast<AliMUONVCluster*>(map->GetValue(uniqueID));
270 }
271
272 //_____________________________________________________________________________
273 TIterator* AliMUONClusterStoreV2::CreateIterator() const
274 {
275   /// Return an iterator to loop over all clusters
276   return fClusters->MakeIterator();
277 }
278
279 //_____________________________________________________________________________
280 TIterator* AliMUONClusterStoreV2::CreateChamberIterator(Int_t firstChamber, Int_t lastChamber) const
281 {
282   /// Return an iterator to loop over clusters in the chambers within the given range
283   
284   // check validity of given chamber IDs
285   if (firstChamber < 0 || firstChamber >= AliMpConstants::NofTrackingChambers()) {
286     AliError(Form("First chamber out of boundaries [0,%d[", AliMpConstants::NofTrackingChambers()));
287     return 0x0;
288   }
289   if (lastChamber < 0 || lastChamber >= AliMpConstants::NofTrackingChambers()) {
290     AliError(Form("Last chamber out of boundaries [0,%d[", AliMpConstants::NofTrackingChambers()));
291     return 0x0;
292   }
293   
294   if (!fMapped) (const_cast<AliMUONClusterStoreV2*>(this))->ReMap();
295   return new AliMUONClusterStoreV2Iterator(this,firstChamber,lastChamber);
296 }