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