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