Fixed memory leak
[u/mrichter/AliRoot.git] / MUON / AliMUONClusterStoreV2.cxx
CommitLineData
2060b217 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
44ClassImp(AliMUONClusterStoreV2)
45/// \endcond
46
47//_____________________________________________________________________________
ce350193 48AliMUONClusterStoreV2::AliMUONClusterStoreV2(TRootIOCtor* /*dummy*/)
49: AliMUONVClusterStore(),
50fClusters(0x0),
51fMap(0x0),
52fMapped(kFALSE)
53{
54 /// Dummy IO ctor that does not allocate memory
55}
56
57//_____________________________________________________________________________
2060b217 58AliMUONClusterStoreV2::AliMUONClusterStoreV2()
59: AliMUONVClusterStore(),
60 fClusters(new TClonesArray("AliMUONRawClusterV2",100)),
61 fMap(0x0),
62 fMapped(kFALSE)
63{
64 /// Constructor
65}
66
67//_____________________________________________________________________________
68AliMUONClusterStoreV2::AliMUONClusterStoreV2(const AliMUONClusterStoreV2& store)
69: AliMUONVClusterStore(),
70 fClusters(new TClonesArray(*(store.fClusters))),
71 fMap(0x0),
72 fMapped(kFALSE)
73{
74 /// Copy constructor
75 if (store.fMapped) ReMap();
76}
77
78//_____________________________________________________________________________
79AliMUONClusterStoreV2& AliMUONClusterStoreV2::operator=(const AliMUONClusterStoreV2& store)
80{
81 /// Assignment operator
0d66cd7d 82 if ( this != &store )
83 {
84 fClusters = new TClonesArray(*(store.fClusters));
85 fMap = 0x0;
86 fMapped = kFALSE;
87 if (store.fMapped) ReMap();
88 }
2060b217 89 return *this;
90}
91
92//_____________________________________________________________________________
93AliMUONClusterStoreV2::~AliMUONClusterStoreV2()
94{
95 /// Destructor
96 delete fClusters;
97 delete fMap;
98}
99
100//_____________________________________________________________________________
101void AliMUONClusterStoreV2::Clear(Option_t*)
102{
103 /// Clear the internal cluster array AND the index
ce350193 104 if ( fClusters )
105 {
106 fClusters->Clear("C");
107 if (fMap) {
108 Int_t nChamber = AliMpConstants::NofTrackingChambers();
109 for (Int_t chamber=0; chamber<nChamber; chamber++) {
110 AliMpExMap *map = static_cast<AliMpExMap *>(fMap->UncheckedAt(chamber));
111 map->Clear("C");
112 }
113 fMapped = kFALSE;
630711ed 114 }
2060b217 115 }
116}
117
118//_____________________________________________________________________________
119Bool_t AliMUONClusterStoreV2::Connect(TTree& tree, Bool_t alone) const
120{
121 /// Connect this to the tree, i.e. make the branches or set their addresses.
122
123 AliMUONTreeManager tman;
124
125 if (tree.GetBranch("MUONRawClusters")) {
126
127 if (alone) tman.UpdateBranchStatuses(tree,"MUONRawClusters");
128
129 return tman.SetAddress(tree,"MUONRawClusters",
130 const_cast<TClonesArray**>(&fClusters));
131 } else {
132
133 return tman.MakeBranch(tree,ClassName(),"TClonesArray", "MUONRawClusters",
134 const_cast<TClonesArray**>(&fClusters));
135 }
136
137}
138
139//_____________________________________________________________________________
140AliMUONVCluster* AliMUONClusterStoreV2::CreateCluster(Int_t chamberId, Int_t detElemId, Int_t clusterIndex) const
141{
142 /// Create a cluster
143 return new AliMUONRawClusterV2(chamberId, detElemId, clusterIndex);
144}
145
146//_____________________________________________________________________________
7332f213 147AliMUONVCluster* AliMUONClusterStoreV2::Add(const AliMUONVCluster& vCluster)
2060b217 148{
149 /// Add a cluster to this store
150 const AliMUONRawClusterV2* cluster = dynamic_cast<const AliMUONRawClusterV2*>(&vCluster);
151
152 if (!cluster) {
153 AliError(Form("Cluster is not of the expected type (%s vs AliMUONRawClusterV2)",
154 vCluster.ClassName()));
7332f213 155 return 0x0;
2060b217 156 }
157
96ebe67e 158 // check chamberId
159 Int_t chamberId = cluster->GetChamberId();
160 if (chamberId < 0 || chamberId >= AliMpConstants::NofTrackingChambers()) {
161 AliError(Form("ChamberId (%d) out of boundaries [0,%d[",chamberId,AliMpConstants::NofTrackingChambers()));
162 return 0x0;
163 }
164
2060b217 165 // check that there is no cluster with the same Id
7332f213 166 AliMUONVCluster *c = FindObject(cluster->GetUniqueID());
167 if (c) {
9ee1d6ff 168 AliError("cluster store already contains a cluster with the same ID --> add() exited:");
7332f213 169 c->Print("FULL");
170 return 0x0;
2060b217 171 }
172
173 // add new cluster
7332f213 174 c = new((*fClusters)[fClusters->GetLast()+1]) AliMUONRawClusterV2(*cluster);
2060b217 175
176 if (c) UpdateMap(*c);
177
7332f213 178 return c;
2060b217 179}
180
181//_____________________________________________________________________________
182AliMUONVCluster* AliMUONClusterStoreV2::Add(Int_t chamberId, Int_t detElemId, Int_t clusterIndex)
183{
184 /// Add an empty cluster with an unique ID to this store
185
96ebe67e 186 // check chamberId
187 if (chamberId < 0 || chamberId >= AliMpConstants::NofTrackingChambers()) {
188 AliError(Form("ChamberId (%d) out of boundaries [0,%d[",chamberId,AliMpConstants::NofTrackingChambers()));
189 return 0x0;
190 }
191
2060b217 192 // check that there is no cluster with the same Id
193 AliMUONVCluster *c = FindObject(AliMUONVCluster::BuildUniqueID(chamberId, detElemId, clusterIndex));
194 if (c) {
9ee1d6ff 195 AliError("cluster store already contains a cluster with the same ID --> add() exited:");
2060b217 196 c->Print("FULL");
197 return 0x0;
198 }
199
200 // add new cluster
201 c = new((*fClusters)[fClusters->GetLast()+1]) AliMUONRawClusterV2(chamberId, detElemId, clusterIndex);
202
203 if (c) UpdateMap(*c);
204
205 return c;
206}
207
208//_____________________________________________________________________________
209AliMUONVCluster* AliMUONClusterStoreV2::Remove(AliMUONVCluster& cluster)
210{
211 /// Remove a cluster
212 AliMUONVCluster* c = static_cast<AliMUONVCluster*>(fClusters->Remove(&cluster));
213
9bf6860b 214 if (c)
215 {
2060b217 216 fClusters->Compress();
217 fMapped = kFALSE;
218 }
9bf6860b 219 else
220 {
221 AliError("Could not remove cluster from array");
222 }
2060b217 223
224 return c;
225}
226
227//_____________________________________________________________________________
228void AliMUONClusterStoreV2::ReMap()
229{
230 /// Recompute the fMap, which map (ch) to an index within the fClusters array
231 fMapped = kTRUE;
232
233 // Create (or clear) the TClonesArray of map
234 Int_t nChamber = AliMpConstants::NofTrackingChambers();
2060b217 235
9bf6860b 236 if (!fMap) {
237 fMap = new TClonesArray("AliMpExMap",nChamber);
238
239 // Create one map per chamber
240 AliMpExMap *map;
241 for (Int_t chamber=0; chamber<nChamber; chamber++) {
630711ed 242 map = new((*fMap)[chamber]) AliMpExMap;
9bf6860b 243 map->SetOwner(kFALSE);
244 }
245 }
246 else {
247 for (Int_t chamber=0; chamber<nChamber; chamber++) {
630711ed 248 AliMpExMap *map = static_cast<AliMpExMap *>(fMap->UncheckedAt(chamber));
9bf6860b 249 map->Clear("C");
250 }
251 }
252
2060b217 253 // Fill the maps
254 TIter next(fClusters);
255 AliMUONVCluster* cluster;
256 while ( (cluster = static_cast<AliMUONVCluster*>(next())) ) UpdateMap(*cluster);
257}
258
259//_____________________________________________________________________________
260void AliMUONClusterStoreV2::UpdateMap(AliMUONVCluster& cluster)
261{
262 /// Update the internal index given this new cluster
263 if (fMapped) static_cast<AliMpExMap*>(fMap->UncheckedAt(cluster.GetChamberId()))->Add(cluster.GetUniqueID(),&cluster);
264 else ReMap();
265}
266
267//_____________________________________________________________________________
268AliMUONVCluster* AliMUONClusterStoreV2::FindObject(const TObject* object) const
269{
270 /// Find an object, if of AliMUONVCluster type.
271 const AliMUONVCluster* cluster = dynamic_cast<const AliMUONVCluster*>(object);
272 if (cluster) return FindObject(cluster->GetUniqueID());
273 return 0x0;
274}
275
276//_____________________________________________________________________________
277AliMUONVCluster* AliMUONClusterStoreV2::FindObject(UInt_t uniqueID) const
278{
279 /// Find a cluster by its UniqueID
280 if (!fMapped) (const_cast<AliMUONClusterStoreV2*>(this))->ReMap();
281 AliMpExMap* map = static_cast<AliMpExMap*>(fMap->UncheckedAt(AliMUONVCluster::GetChamberId(uniqueID)));
282 return static_cast<AliMUONVCluster*>(map->GetValue(uniqueID));
283}
284
285//_____________________________________________________________________________
286TIterator* AliMUONClusterStoreV2::CreateIterator() const
287{
288 /// Return an iterator to loop over all clusters
289 return fClusters->MakeIterator();
290}
291
292//_____________________________________________________________________________
293TIterator* AliMUONClusterStoreV2::CreateChamberIterator(Int_t firstChamber, Int_t lastChamber) const
294{
295 /// Return an iterator to loop over clusters in the chambers within the given range
296
297 // check validity of given chamber IDs
298 if (firstChamber < 0 || firstChamber >= AliMpConstants::NofTrackingChambers()) {
299 AliError(Form("First chamber out of boundaries [0,%d[", AliMpConstants::NofTrackingChambers()));
300 return 0x0;
301 }
302 if (lastChamber < 0 || lastChamber >= AliMpConstants::NofTrackingChambers()) {
303 AliError(Form("Last chamber out of boundaries [0,%d[", AliMpConstants::NofTrackingChambers()));
304 return 0x0;
305 }
306
307 if (!fMapped) (const_cast<AliMUONClusterStoreV2*>(this))->ReMap();
308 return new AliMUONClusterStoreV2Iterator(this,firstChamber,lastChamber);
309}