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