]> git.uio.no Git - u/mrichter/AliRoot.git/blob - MUON/AliMUONRefitter.cxx
Histogram ranges changed to cut off saturation peak and noise
[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
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) CreateTrackReconstructor(*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 = CreateClusterFinder();
343   fClusterServer = clusterFinder ? new AliMUONSimpleClusterServer(*clusterFinder,transformer) : 0x0;
344 }
345
346 //_____________________________________________________________________________
347 AliMUONVClusterFinder* AliMUONRefitter::CreateClusterFinder()
348 {
349   /// Create a given cluster finder instance
350   AliMUONVClusterFinder* clusterFinder;
351   Option_t *opt = AliMUONReconstructor::GetRecoParam()->GetClusteringMode();
352   
353   if      (strstr(opt,"PRECLUSTERV2")) clusterFinder = new AliMUONPreClusterFinderV2;
354   else if (strstr(opt,"PRECLUSTERV3")) clusterFinder = new AliMUONPreClusterFinderV3;
355   else if (strstr(opt,"PRECLUSTER"))   clusterFinder = new AliMUONPreClusterFinder;
356   else if (strstr(opt,"COG"))          clusterFinder = new AliMUONClusterFinderCOG(new AliMUONPreClusterFinder);
357   else if (strstr(opt,"SIMPLEFITV3"))  clusterFinder = new AliMUONClusterFinderSimpleFit(new AliMUONClusterFinderCOG(new AliMUONPreClusterFinderV3));
358   else if (strstr(opt,"SIMPLEFIT"))    clusterFinder = new AliMUONClusterFinderSimpleFit(new AliMUONClusterFinderCOG(new AliMUONPreClusterFinder));
359   else if (strstr(opt,"MLEM:DRAW"))    clusterFinder = new AliMUONClusterFinderMLEM(kTRUE,new AliMUONPreClusterFinder);
360   else if (strstr(opt,"MLEMV3"))       clusterFinder = new AliMUONClusterFinderMLEM(kFALSE,new AliMUONPreClusterFinderV3);
361   else if (strstr(opt,"MLEMV2"))       clusterFinder = new AliMUONClusterFinderMLEM(kFALSE,new AliMUONPreClusterFinderV2);
362   else if (strstr(opt,"MLEM"))         clusterFinder = new AliMUONClusterFinderMLEM(kFALSE,new AliMUONPreClusterFinder);
363   else clusterFinder = 0x0;
364   
365   if (clusterFinder) {
366     AliInfo(Form("Will use %s for clusterizing",clusterFinder->ClassName()));
367   } else {
368     AliError(Form("clustering mode \"%s\" does not exist",opt));
369   }
370   
371   return clusterFinder;
372 }
373
374 //_____________________________________________________________________________
375 void AliMUONRefitter::CreateTrackReconstructor(AliMUONVClusterServer& clusterServer)
376 {
377   /// Create track reconstructor, depending on tracking mode set in RecoParam
378   Option_t *opt = AliMUONReconstructor::GetRecoParam()->GetTrackingMode();
379   
380   if      (strstr(opt,"ORIGINAL")) fTracker = new AliMUONTrackReconstructor(clusterServer);
381   else if (strstr(opt,"KALMAN"))   fTracker = new AliMUONTrackReconstructorK(clusterServer);
382   else fTracker = 0x0;
383   
384   if (fTracker) {
385     AliInfo(Form("Will use %s for tracking",fTracker->ClassName()));
386   } else {
387     AliError(Form("tracking mode \"%s\" does not exist",opt));
388   }
389 }
390
391 //_____________________________________________________________________________
392 void AliMUONRefitter::AddClusterToTracks(const AliMUONVClusterStore &clusterStore, AliMUONVTrackStore &trackStore)
393 {
394   /// add clusters to each of the given tracks
395   /// duplicate the tracks if there are several clusters and add one cluster per copy
396   
397   // create new track store if there are more than 1 cluster to add per track
398   Int_t nClusters = clusterStore.GetSize();
399   if (nClusters < 1) return;
400   
401   AliMUONTrackParam dummyParam;
402   AliMUONTrack *currentTrack, *track;
403   AliMUONVCluster *newCluster;
404   Int_t nTracks = trackStore.GetSize();
405   Int_t iTrack = 0;
406   Int_t iCluster = 0;
407   
408   // loop over existing tracks to add the cluster(s)
409   TIter nextTrack(trackStore.CreateIterator());
410   while ((currentTrack = static_cast<AliMUONTrack*>(nextTrack())) && (iTrack < nTracks)) {
411     
412     iTrack++;
413     
414     // add the new cluster(s) to the tracks
415     // duplicate the tracks if there are several clusters
416     // the loop after loading the last cluster which is added to the current track
417     iCluster = 0;
418     TIter nextCluster(clusterStore.CreateIterator());
419     while ((newCluster = static_cast<AliMUONVCluster*>(nextCluster())) && (iCluster < nClusters - 1)) {
420       
421       iCluster++;
422       
423       // add a copy of the current track to the store
424       track = trackStore.Add(AliMUONTrack(*currentTrack));
425       
426       // only set Z parameter to avoid error in AddTrackParamAtCluster()
427       // the rest will be recomputed during refit
428       dummyParam.SetZ(newCluster->GetZ());
429       
430       // add new cluster to the new track
431       track->AddTrackParamAtCluster(dummyParam, *newCluster, kTRUE);
432       
433     }
434     
435     // only set Z parameter to avoid error in AddTrackParamAtCluster()
436     // the rest will be recomputed during refit
437     dummyParam.SetZ(newCluster->GetZ());
438     
439     // add new cluster to the current track
440     currentTrack->AddTrackParamAtCluster(dummyParam, *newCluster, kTRUE);
441     
442   }
443   
444 }
445