]> git.uio.no Git - u/mrichter/AliRoot.git/blame - MUON/AliMUONRefitter.cxx
Updated documentation
[u/mrichter/AliRoot.git] / MUON / AliMUONRefitter.cxx
CommitLineData
7deb8eb0 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
b09247a2 18#include <cstdlib>
7deb8eb0 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"
9bf6860b 35#include "AliMUONTracker.h"
7deb8eb0 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
58ClassImp(AliMUONRefitter)
59/// \endcond
60
61//_____________________________________________________________________________
a0dc65b4 62AliMUONRefitter::AliMUONRefitter(const AliMUONRecoParam* recoParam)
7deb8eb0 63: TObject(),
64 fGeometryTransformer(0x0),
65 fClusterServer(0x0),
66 fTracker(0x0),
67 fESDInterface(0x0)
68{
69 /// Default constructor
70 CreateGeometryTransformer();
71 CreateClusterServer(*fGeometryTransformer);
a0dc65b4 72 if (fClusterServer) fTracker = AliMUONTracker::CreateTrackReconstructor(recoParam,fClusterServer);
7deb8eb0 73 if (!fClusterServer || !fTracker) {
74 AliFatal("refitter initialization failed");
75 exit(-1);
76 }
77}
78
79//_____________________________________________________________________________
80AliMUONRefitter::~AliMUONRefitter()
81{
82 /// Destructor
83 delete fGeometryTransformer;
84 delete fClusterServer;
85 delete fTracker;
86}
87
88//_____________________________________________________________________________
89AliMUONVTrackStore* 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)
630711ed 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;
7deb8eb0 110 }
111
112 return newTrackStore;
113}
114
115//_____________________________________________________________________________
116AliMUONVTrackStore* 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//_____________________________________________________________________________
630711ed 142AliMUONTrack* AliMUONRefitter::RetrackFromDigits(UInt_t trackId)
7deb8eb0 143{
630711ed 144 /// refit track "trackId" from the digits (i.e. re-clusterized the attached clusters)
7deb8eb0 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
630711ed 153 AliMUONTrack* track = fESDInterface->FindTrack(trackId);
7deb8eb0 154
630711ed 155 return track ? RetrackFromDigits(*track) : 0x0;
7deb8eb0 156}
157
158//_____________________________________________________________________________
630711ed 159AliMUONTrack* AliMUONRefitter::RetrackFromClusters(UInt_t trackId)
7deb8eb0 160{
630711ed 161 /// refit track "trackId" form the clusters (i.e. do not re-clusterize)
7deb8eb0 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
630711ed 170 AliMUONTrack* track = fESDInterface->FindTrack(trackId);
7deb8eb0 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//_____________________________________________________________________________
630711ed 184AliMUONVClusterStore* AliMUONRefitter::ReClusterize(UInt_t trackId, UInt_t clusterId)
7deb8eb0 185{
630711ed 186 /// re-clusterize cluster numbered "clusterId" in track "trackId"
7deb8eb0 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
630711ed 196 AliMUONVCluster* cluster = fESDInterface->FindCluster(trackId,clusterId);
7deb8eb0 197 if (!cluster) return 0x0;
198
199 // check if digits exist
200 if (cluster->GetNDigits() == 0) {
630711ed 201 AliError(Form("no digit attached to cluster #%d in track %d",clusterId,trackId));
7deb8eb0 202 return 0x0;
203 }
204
205 // create the cluster store
206 AliMUONVClusterStore* clusterStore = AliMUONESDInterface::NewClusterStore();
207 if (!clusterStore) return 0x0;
208
209 // re-clusterize
630711ed 210 TIter next(fESDInterface->CreateDigitIterator(trackId, clusterId));
7deb8eb0 211 fClusterServer->UseDigits(next);
212 fClusterServer->Clusterize(cluster->GetChamberId(),*clusterStore,AliMpArea());
213
214 return clusterStore;
215}
216
217//_____________________________________________________________________________
218AliMUONVClusterStore* 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//_____________________________________________________________________________
252void AliMUONRefitter::CreateGeometryTransformer()
253{
254 /// Create geometry transformer (local<->global)
255 /// and load geometry data
256 fGeometryTransformer = new AliMUONGeometryTransformer();
257 fGeometryTransformer->LoadGeometryData();
258}
259
260//_____________________________________________________________________________
261void AliMUONRefitter::CreateClusterServer(AliMUONGeometryTransformer& transformer)
262{
263 /// Create cluster server
a0dc65b4 264 AliMUONVClusterFinder* clusterFinder = AliMUONReconstructor::CreateClusterFinder(GetRecoParam()->GetClusteringMode());
9bf6860b 265 fClusterServer = clusterFinder ? new AliMUONSimpleClusterServer(clusterFinder,transformer) : 0x0;
7deb8eb0 266}
267
630711ed 268//_____________________________________________________________________________
269AliMUONTrack* 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
7deb8eb0 354//_____________________________________________________________________________
355void 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