]> git.uio.no Git - u/mrichter/AliRoot.git/blame - MUON/AliMUONRefitter.cxx
Re-establishing creation of RecPoints in TreeR (Laurent)
[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
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"
9bf6860b 34#include "AliMUONTracker.h"
7deb8eb0 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
57ClassImp(AliMUONRefitter)
58/// \endcond
59
60//_____________________________________________________________________________
61AliMUONRefitter::AliMUONRefitter()
62: TObject(),
63 fGeometryTransformer(0x0),
64 fClusterServer(0x0),
65 fTracker(0x0),
66 fESDInterface(0x0)
67{
68 /// Default constructor
69 CreateGeometryTransformer();
70 CreateClusterServer(*fGeometryTransformer);
9bf6860b 71 if (fClusterServer) AliMUONTracker::CreateTrackReconstructor(AliMUONReconstructor::GetRecoParam()->GetTrackingMode(),fClusterServer);
7deb8eb0 72 if (!fClusterServer || !fTracker) {
73 AliFatal("refitter initialization failed");
74 exit(-1);
75 }
76}
77
78//_____________________________________________________________________________
79AliMUONRefitter::~AliMUONRefitter()
80{
81 /// Destructor
82 delete fGeometryTransformer;
83 delete fClusterServer;
84 delete fTracker;
85}
86
87//_____________________________________________________________________________
88AliMUONVTrackStore* 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//_____________________________________________________________________________
114AliMUONVTrackStore* 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//_____________________________________________________________________________
140AliMUONTrack* 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//_____________________________________________________________________________
237AliMUONTrack* 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//_____________________________________________________________________________
262AliMUONVClusterStore* 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//_____________________________________________________________________________
296AliMUONVClusterStore* 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//_____________________________________________________________________________
330void AliMUONRefitter::CreateGeometryTransformer()
331{
332 /// Create geometry transformer (local<->global)
333 /// and load geometry data
334 fGeometryTransformer = new AliMUONGeometryTransformer();
335 fGeometryTransformer->LoadGeometryData();
336}
337
338//_____________________________________________________________________________
339void AliMUONRefitter::CreateClusterServer(AliMUONGeometryTransformer& transformer)
340{
341 /// Create cluster server
9bf6860b 342 AliMUONVClusterFinder* clusterFinder = AliMUONReconstructor::CreateClusterFinder(AliMUONReconstructor::GetRecoParam()->GetClusteringMode());
343 fClusterServer = clusterFinder ? new AliMUONSimpleClusterServer(clusterFinder,transformer) : 0x0;
7deb8eb0 344}
345
346//_____________________________________________________________________________
347void 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