]> git.uio.no Git - u/mrichter/AliRoot.git/blob - MUON/AliMUONRefitter.cxx
Version number incremented
[u/mrichter/AliRoot.git] / MUON / AliMUONRefitter.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 #include "AliMUONRefitter.h"
19 #include "AliMUONGeometryTransformer.h"
20 #include "AliMUONClusterFinderCOG.h"
21 #include "AliMUONClusterFinderMLEM.h"
22 #include "AliMUONClusterFinderSimpleFit.h"
23 #include "AliMUONPreClusterFinder.h"
24 #include "AliMUONPreClusterFinderV2.h"
25 #include "AliMUONPreClusterFinderV3.h"
26 #include "AliMUONSimpleClusterServer.h"
27 #include "AliMUONTrackReconstructor.h"
28 #include "AliMUONTrackReconstructorK.h"
29 #include "AliMUONRecoParam.h"
30 #include "AliMUONESDInterface.h"
31 #include "AliMUONVClusterStore.h"
32 #include "AliMUONVTrackStore.h"
33 #include "AliMUONTrack.h"
34 #include "AliMUONTracker.h"
35 #include "AliLog.h"
36
37 //-----------------------------------------------------------------------------
38 /// \class AliMUONRefitter
39 ///
40 /// create new MUON object from ESD objects given as input (through the ESDInterface):
41 ///
42 /// - re-clusterize the ESD clusters using the attached ESD pads
43 ///   (several new clusters can be reconstructed per ESD cluster)
44 /// - re-fit the ESD tracks using the attached ESD clusters
45 /// - reconstruct the ESD tracks from ESD pads (i.e. re-clusterized the attached clusters)
46 ///
47 /// note:
48 /// - connexion between an ESD cluster and corresponding MUON clusters from re-clustering
49 ///   can be made through the detection element ID
50 /// - connexion between an ESD track and the corresponding refitted MUON track
51 ///   can be made through their unique ID
52 ///
53 /// \author Philippe Pillot
54 //-----------------------------------------------------------------------------
55
56 /// \cond CLASSIMP
57 ClassImp(AliMUONRefitter)
58 /// \endcond
59
60 //_____________________________________________________________________________
61 AliMUONRefitter::AliMUONRefitter()
62 : TObject(),
63   fGeometryTransformer(0x0),
64   fClusterServer(0x0),
65   fTracker(0x0),
66   fESDInterface(0x0)
67 {
68   /// Default constructor
69   CreateGeometryTransformer();
70   CreateClusterServer(*fGeometryTransformer);
71   if (fClusterServer) fTracker = AliMUONTracker::CreateTrackReconstructor(AliMUONReconstructor::GetRecoParam()->GetTrackingMode(),fClusterServer);
72   if (!fClusterServer || !fTracker) {
73     AliFatal("refitter initialization failed");
74     exit(-1);
75   }
76 }
77
78 //_____________________________________________________________________________
79 AliMUONRefitter::~AliMUONRefitter()
80 {
81   /// Destructor
82   delete fGeometryTransformer;
83   delete fClusterServer;
84   delete fTracker;
85 }
86
87 //_____________________________________________________________________________
88 AliMUONVTrackStore* AliMUONRefitter::ReconstructFromDigits()
89 {
90   /// re-reconstruct all tracks and attached clusters from the digits
91   /// it is the responsability of the user to delete the returned store
92   
93   if (!fESDInterface) {
94     AliError("the refitter must be connected to an ESDInterface containing the ESD event to reconstruct");
95     return 0x0;
96   }
97   
98   // prepare new track(s)
99   AliMUONVTrackStore* newTrackStore = AliMUONESDInterface::NewTrackStore();
100   if (!newTrackStore) return 0x0;
101   
102   // loop over tracks and refit them (create new tracks)
103   Int_t nTracks = fESDInterface->GetNTracks();
104   for (Int_t iTrack = 0; iTrack < nTracks; iTrack++) {
105     AliMUONTrack *track = RetrackFromDigits(iTrack);
106     newTrackStore->Add(track);
107     delete track;
108   }
109   
110   return newTrackStore;
111 }
112
113 //_____________________________________________________________________________
114 AliMUONVTrackStore* AliMUONRefitter::ReconstructFromClusters()
115 {
116   /// refit all tracks from the attached clusters
117   /// it is the responsability of the user to delete the returned store
118   
119   if (!fESDInterface) {
120     AliError("the refitter must be connected to an ESDInterface containing the ESD event to reconstruct");
121     return 0x0;
122   }
123   
124   // prepare new track(s)
125   AliMUONVTrackStore* newTrackStore = AliMUONESDInterface::NewTrackStore();
126   if (!newTrackStore) return 0x0;
127   
128   // loop over tracks and refit them (create new tracks)
129   AliMUONTrack *track;
130   TIter next(fESDInterface->CreateTrackIterator());
131   while ((track = static_cast<AliMUONTrack*>(next()))) {
132     AliMUONTrack* newTrack = newTrackStore->Add(*track);
133     if (!fTracker->RefitTrack(*newTrack)) newTrackStore->Remove(*newTrack);
134   }
135   
136   return newTrackStore;
137 }
138
139 //_____________________________________________________________________________
140 AliMUONTrack* AliMUONRefitter::RetrackFromDigits(Int_t iTrack)
141 {
142   /// refit track "iTrack" from the digits (i.e. re-clusterized the attached clusters):
143   /// several new clusters may be reconstructed per initial ESD cluster:
144   /// -> all the combinations of clusters are considered to build the new tracks
145   /// -> return the best track (largest number of clusters or best chi2 in case of equality)
146   /// it is the responsability of the user to delete the returned track
147   
148   if (!fESDInterface) {
149     AliError("the refitter must be connected to an ESDInterface containing the ESD event to reconstruct");
150     return 0x0;
151   }
152   
153   // get the track to refit
154   AliMUONTrack* track = fESDInterface->GetTrack(iTrack);
155   if (!track) return 0x0;
156   
157   // check if digits exist
158   if (fESDInterface->GetNDigits(iTrack) == 0) {
159     AliError(Form("no digit attached to track #%d",iTrack));
160     return 0x0;
161   }
162   
163   // prepare new track(s)
164   AliMUONVTrackStore* newTrackStore = AliMUONESDInterface::NewTrackStore();
165   if (!newTrackStore) return 0x0;
166   newTrackStore->Add(*track)->Clear("C");
167   
168   // prepare new cluster store
169   AliMUONVClusterStore* newClusterStore = AliMUONESDInterface::NewClusterStore();
170   if (!newClusterStore) {
171     delete newTrackStore;
172     return 0x0;
173   }
174   
175   // loop over clusters, re-clusterize and build new tracks
176   Int_t nClusters = track->GetNClusters();
177   for (Int_t iCluster = 0; iCluster < nClusters; iCluster++) {
178     
179     // reset the new cluster store
180     newClusterStore->Clear();
181     
182     // get the current cluster
183     AliMUONVCluster* cluster = fESDInterface->GetClusterFast(iTrack,iCluster);
184     
185     // re-clusterize current cluster
186     TIter next(fESDInterface->CreateDigitIterator(iTrack, iCluster));
187     fClusterServer->UseDigits(next);
188     Int_t nNewClusters = fClusterServer->Clusterize(cluster->GetChamberId(),*newClusterStore,AliMpArea());
189     
190     // check that re-clusterizing succeeded
191     if (nNewClusters == 0) {
192       AliWarning(Form("refit gave no cluster (chamber %d)",cluster->GetChamberId()));
193       AliInfo("initial ESD cluster:");
194       cluster->Print("FULL");
195       continue;
196     }
197     
198     // add the new cluster(s) to the tracks
199     AddClusterToTracks(*newClusterStore, *newTrackStore);
200     
201   }
202   
203   // refit the tracks and pick up the best one
204   AliMUONTrack *currentTrack, *bestTrack = 0x0;
205   Double_t currentChi2, bestChi2 = 1.e10;
206   Int_t currentNCluster, bestNClusters = 0;
207   TIter next(newTrackStore->CreateIterator());
208   while ((currentTrack = static_cast<AliMUONTrack*>(next()))) {
209     
210     // set the track parameters at first cluster if any (used as seed in original tracking)
211     AliMUONTrackParam* param = (AliMUONTrackParam*) currentTrack->GetTrackParamAtCluster()->First();
212     if (param) *param = *((AliMUONTrackParam*) track->GetTrackParamAtCluster()->First());
213     
214     // refit the track
215     if (!fTracker->RefitTrack(*currentTrack)) break;
216     
217     // find best track (the one with the higher number of cluster or the best chi2 in case of equality)
218     currentNCluster = currentTrack->GetNClusters();
219     currentChi2 = currentTrack->GetGlobalChi2();
220     if (currentNCluster > bestNClusters || (currentNCluster == bestNClusters && currentChi2 < bestChi2)) {
221       bestTrack = currentTrack;
222       bestNClusters = currentNCluster;
223       bestChi2 = currentChi2;
224     }
225     
226   }
227   
228   // copy best track and free memory
229   AliMUONTrack* newTrack = bestTrack ? new AliMUONTrack(*bestTrack) : 0x0;
230   delete newClusterStore;
231   delete newTrackStore;
232   
233   return newTrack;
234 }
235
236 //_____________________________________________________________________________
237 AliMUONTrack* AliMUONRefitter::RetrackFromClusters(Int_t iTrack)
238 {
239   /// refit track "iTrack" form the clusters (i.e. do not re-clusterize)
240   /// it is the responsability of the user to delete the returned track
241   
242   if (!fESDInterface) {
243     AliError("the refitter must be connected to an ESDInterface containing the ESD event to reconstruct");
244     return 0x0;
245   }
246   
247   // get the track to refit
248   AliMUONTrack* track = fESDInterface->GetTrack(iTrack);
249   if (!track) return 0x0;
250   
251   // refit the track (create a new one)
252   AliMUONTrack* newTrack = new AliMUONTrack(*track);
253   if (!fTracker->RefitTrack(*newTrack)) {
254     delete newTrack;
255     return 0x0;
256   }
257   
258   return newTrack;
259 }
260
261 //_____________________________________________________________________________
262 AliMUONVClusterStore* AliMUONRefitter::ReClusterize(Int_t iTrack, Int_t iCluster)
263 {
264   /// re-clusterize cluster numbered "iCluster" in track "iTrack"
265   /// several new clusters may be reconstructed
266   /// it is the responsability of the user to delete the returned store
267   
268   if (!fESDInterface) {
269     AliError("the refitter must be connected to an ESDInterface containing the ESD event to reconstruct");
270     return 0x0;
271   }
272   
273   // get the cluster to re-clusterize
274   AliMUONVCluster* cluster = fESDInterface->GetCluster(iTrack,iCluster);
275   if (!cluster) return 0x0;
276   
277   // check if digits exist
278   if (cluster->GetNDigits() == 0) {
279     AliError(Form("no digit attached to cluster #%d in track %d",iCluster,iTrack));
280     return 0x0;
281   }
282   
283   // create the cluster store
284   AliMUONVClusterStore* clusterStore = AliMUONESDInterface::NewClusterStore();
285   if (!clusterStore) return 0x0;
286   
287   // re-clusterize
288   TIter next(fESDInterface->CreateDigitIterator(iTrack, iCluster));
289   fClusterServer->UseDigits(next);
290   fClusterServer->Clusterize(cluster->GetChamberId(),*clusterStore,AliMpArea());
291   
292   return clusterStore;
293 }
294
295 //_____________________________________________________________________________
296 AliMUONVClusterStore* AliMUONRefitter::ReClusterize(UInt_t clusterId)
297 {
298   /// re-clusterize cluster "clusterId"
299   /// several new clusters may be reconstructed
300   /// it is the responsability of the user to delete the returned store
301   
302   if (!fESDInterface) {
303     AliError("the refitter must be connected to an ESDInterface containing the ESD event to reconstruct");
304     return 0x0;
305   }
306   
307   // get the cluster to re-clusterize
308   AliMUONVCluster* cluster = fESDInterface->FindCluster(clusterId);
309   if (!cluster) return 0x0;
310   
311   // check if digits exist
312   if (cluster->GetNDigits() == 0) {
313     AliError(Form("no digit attached to cluster %d",clusterId));
314     return 0x0;
315   }
316   
317   // create the cluster store
318   AliMUONVClusterStore* clusterStore = AliMUONESDInterface::NewClusterStore();
319   if (!clusterStore) return 0x0;
320   
321   // re-clusterize
322   TIter next(fESDInterface->CreateDigitIteratorInCluster(clusterId));
323   fClusterServer->UseDigits(next);
324   fClusterServer->Clusterize(cluster->GetChamberId(),*clusterStore,AliMpArea());
325   
326   return clusterStore;
327 }
328
329 //_____________________________________________________________________________
330 void AliMUONRefitter::CreateGeometryTransformer()
331 {
332   /// Create geometry transformer (local<->global)
333   /// and load geometry data
334   fGeometryTransformer = new AliMUONGeometryTransformer();
335   fGeometryTransformer->LoadGeometryData();
336 }
337
338 //_____________________________________________________________________________
339 void AliMUONRefitter::CreateClusterServer(AliMUONGeometryTransformer& transformer)
340 {
341   /// Create cluster server
342   AliMUONVClusterFinder* clusterFinder = AliMUONReconstructor::CreateClusterFinder(AliMUONReconstructor::GetRecoParam()->GetClusteringMode());
343   fClusterServer = clusterFinder ? new AliMUONSimpleClusterServer(clusterFinder,transformer) : 0x0;
344 }
345
346 //_____________________________________________________________________________
347 void AliMUONRefitter::AddClusterToTracks(const AliMUONVClusterStore &clusterStore, AliMUONVTrackStore &trackStore)
348 {
349   /// add clusters to each of the given tracks
350   /// duplicate the tracks if there are several clusters and add one cluster per copy
351   
352   // create new track store if there are more than 1 cluster to add per track
353   Int_t nClusters = clusterStore.GetSize();
354   if (nClusters < 1) return;
355   
356   AliMUONTrackParam dummyParam;
357   AliMUONTrack *currentTrack, *track;
358   AliMUONVCluster *newCluster;
359   Int_t nTracks = trackStore.GetSize();
360   Int_t iTrack = 0;
361   Int_t iCluster = 0;
362   
363   // loop over existing tracks to add the cluster(s)
364   TIter nextTrack(trackStore.CreateIterator());
365   while ((currentTrack = static_cast<AliMUONTrack*>(nextTrack())) && (iTrack < nTracks)) {
366     
367     iTrack++;
368     
369     // add the new cluster(s) to the tracks
370     // duplicate the tracks if there are several clusters
371     // the loop after loading the last cluster which is added to the current track
372     iCluster = 0;
373     TIter nextCluster(clusterStore.CreateIterator());
374     while ((newCluster = static_cast<AliMUONVCluster*>(nextCluster())) && (iCluster < nClusters - 1)) {
375       
376       iCluster++;
377       
378       // add a copy of the current track to the store
379       track = trackStore.Add(AliMUONTrack(*currentTrack));
380       
381       // only set Z parameter to avoid error in AddTrackParamAtCluster()
382       // the rest will be recomputed during refit
383       dummyParam.SetZ(newCluster->GetZ());
384       
385       // add new cluster to the new track
386       track->AddTrackParamAtCluster(dummyParam, *newCluster, kTRUE);
387       
388     }
389     
390     // only set Z parameter to avoid error in AddTrackParamAtCluster()
391     // the rest will be recomputed during refit
392     dummyParam.SetZ(newCluster->GetZ());
393     
394     // add new cluster to the current track
395     currentTrack->AddTrackParamAtCluster(dummyParam, *newCluster, kTRUE);
396     
397   }
398   
399 }
400