]>
Commit | Line | Data |
---|---|---|
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 | |
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); | |
00dc4f26 | 72 | if (fClusterServer) fTracker = AliMUONTracker::CreateTrackReconstructor(AliMUONReconstructor::GetRecoParam()->GetTrackingMode(),fClusterServer); |
7deb8eb0 | 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 | Int_t nTracks = fESDInterface->GetNTracks(); | |
105 | for (Int_t iTrack = 0; iTrack < nTracks; iTrack++) { | |
106 | AliMUONTrack *track = RetrackFromDigits(iTrack); | |
107 | newTrackStore->Add(track); | |
108 | delete track; | |
109 | } | |
110 | ||
111 | return newTrackStore; | |
112 | } | |
113 | ||
114 | //_____________________________________________________________________________ | |
115 | AliMUONVTrackStore* AliMUONRefitter::ReconstructFromClusters() | |
116 | { | |
117 | /// refit all tracks from the attached clusters | |
118 | /// it is the responsability of the user to delete the returned store | |
119 | ||
120 | if (!fESDInterface) { | |
121 | AliError("the refitter must be connected to an ESDInterface containing the ESD event to reconstruct"); | |
122 | return 0x0; | |
123 | } | |
124 | ||
125 | // prepare new track(s) | |
126 | AliMUONVTrackStore* newTrackStore = AliMUONESDInterface::NewTrackStore(); | |
127 | if (!newTrackStore) return 0x0; | |
128 | ||
129 | // loop over tracks and refit them (create new tracks) | |
130 | AliMUONTrack *track; | |
131 | TIter next(fESDInterface->CreateTrackIterator()); | |
132 | while ((track = static_cast<AliMUONTrack*>(next()))) { | |
133 | AliMUONTrack* newTrack = newTrackStore->Add(*track); | |
134 | if (!fTracker->RefitTrack(*newTrack)) newTrackStore->Remove(*newTrack); | |
135 | } | |
136 | ||
137 | return newTrackStore; | |
138 | } | |
139 | ||
140 | //_____________________________________________________________________________ | |
141 | AliMUONTrack* AliMUONRefitter::RetrackFromDigits(Int_t iTrack) | |
142 | { | |
143 | /// refit track "iTrack" from the digits (i.e. re-clusterized the attached clusters): | |
144 | /// several new clusters may be reconstructed per initial ESD cluster: | |
145 | /// -> all the combinations of clusters are considered to build the new tracks | |
146 | /// -> return the best track (largest number of clusters or best chi2 in case of equality) | |
147 | /// it is the responsability of the user to delete the returned track | |
148 | ||
149 | if (!fESDInterface) { | |
150 | AliError("the refitter must be connected to an ESDInterface containing the ESD event to reconstruct"); | |
151 | return 0x0; | |
152 | } | |
153 | ||
154 | // get the track to refit | |
155 | AliMUONTrack* track = fESDInterface->GetTrack(iTrack); | |
156 | if (!track) return 0x0; | |
157 | ||
158 | // check if digits exist | |
159 | if (fESDInterface->GetNDigits(iTrack) == 0) { | |
160 | AliError(Form("no digit attached to track #%d",iTrack)); | |
161 | return 0x0; | |
162 | } | |
163 | ||
164 | // prepare new track(s) | |
165 | AliMUONVTrackStore* newTrackStore = AliMUONESDInterface::NewTrackStore(); | |
166 | if (!newTrackStore) return 0x0; | |
167 | newTrackStore->Add(*track)->Clear("C"); | |
168 | ||
169 | // prepare new cluster store | |
170 | AliMUONVClusterStore* newClusterStore = AliMUONESDInterface::NewClusterStore(); | |
171 | if (!newClusterStore) { | |
172 | delete newTrackStore; | |
173 | return 0x0; | |
174 | } | |
175 | ||
176 | // loop over clusters, re-clusterize and build new tracks | |
177 | Int_t nClusters = track->GetNClusters(); | |
178 | for (Int_t iCluster = 0; iCluster < nClusters; iCluster++) { | |
179 | ||
180 | // reset the new cluster store | |
181 | newClusterStore->Clear(); | |
182 | ||
183 | // get the current cluster | |
184 | AliMUONVCluster* cluster = fESDInterface->GetClusterFast(iTrack,iCluster); | |
185 | ||
186 | // re-clusterize current cluster | |
187 | TIter next(fESDInterface->CreateDigitIterator(iTrack, iCluster)); | |
188 | fClusterServer->UseDigits(next); | |
189 | Int_t nNewClusters = fClusterServer->Clusterize(cluster->GetChamberId(),*newClusterStore,AliMpArea()); | |
190 | ||
191 | // check that re-clusterizing succeeded | |
192 | if (nNewClusters == 0) { | |
193 | AliWarning(Form("refit gave no cluster (chamber %d)",cluster->GetChamberId())); | |
194 | AliInfo("initial ESD cluster:"); | |
195 | cluster->Print("FULL"); | |
196 | continue; | |
197 | } | |
198 | ||
199 | // add the new cluster(s) to the tracks | |
200 | AddClusterToTracks(*newClusterStore, *newTrackStore); | |
201 | ||
202 | } | |
203 | ||
204 | // refit the tracks and pick up the best one | |
205 | AliMUONTrack *currentTrack, *bestTrack = 0x0; | |
206 | Double_t currentChi2, bestChi2 = 1.e10; | |
207 | Int_t currentNCluster, bestNClusters = 0; | |
208 | TIter next(newTrackStore->CreateIterator()); | |
209 | while ((currentTrack = static_cast<AliMUONTrack*>(next()))) { | |
210 | ||
211 | // set the track parameters at first cluster if any (used as seed in original tracking) | |
212 | AliMUONTrackParam* param = (AliMUONTrackParam*) currentTrack->GetTrackParamAtCluster()->First(); | |
213 | if (param) *param = *((AliMUONTrackParam*) track->GetTrackParamAtCluster()->First()); | |
214 | ||
215 | // refit the track | |
216 | if (!fTracker->RefitTrack(*currentTrack)) break; | |
217 | ||
218 | // find best track (the one with the higher number of cluster or the best chi2 in case of equality) | |
219 | currentNCluster = currentTrack->GetNClusters(); | |
220 | currentChi2 = currentTrack->GetGlobalChi2(); | |
221 | if (currentNCluster > bestNClusters || (currentNCluster == bestNClusters && currentChi2 < bestChi2)) { | |
222 | bestTrack = currentTrack; | |
223 | bestNClusters = currentNCluster; | |
224 | bestChi2 = currentChi2; | |
225 | } | |
226 | ||
227 | } | |
228 | ||
229 | // copy best track and free memory | |
230 | AliMUONTrack* newTrack = bestTrack ? new AliMUONTrack(*bestTrack) : 0x0; | |
231 | delete newClusterStore; | |
232 | delete newTrackStore; | |
233 | ||
234 | return newTrack; | |
235 | } | |
236 | ||
237 | //_____________________________________________________________________________ | |
238 | AliMUONTrack* AliMUONRefitter::RetrackFromClusters(Int_t iTrack) | |
239 | { | |
240 | /// refit track "iTrack" form the clusters (i.e. do not re-clusterize) | |
241 | /// it is the responsability of the user to delete the returned track | |
242 | ||
243 | if (!fESDInterface) { | |
244 | AliError("the refitter must be connected to an ESDInterface containing the ESD event to reconstruct"); | |
245 | return 0x0; | |
246 | } | |
247 | ||
248 | // get the track to refit | |
249 | AliMUONTrack* track = fESDInterface->GetTrack(iTrack); | |
250 | if (!track) return 0x0; | |
251 | ||
252 | // refit the track (create a new one) | |
253 | AliMUONTrack* newTrack = new AliMUONTrack(*track); | |
254 | if (!fTracker->RefitTrack(*newTrack)) { | |
255 | delete newTrack; | |
256 | return 0x0; | |
257 | } | |
258 | ||
259 | return newTrack; | |
260 | } | |
261 | ||
262 | //_____________________________________________________________________________ | |
263 | AliMUONVClusterStore* AliMUONRefitter::ReClusterize(Int_t iTrack, Int_t iCluster) | |
264 | { | |
265 | /// re-clusterize cluster numbered "iCluster" in track "iTrack" | |
266 | /// several new clusters may be reconstructed | |
267 | /// it is the responsability of the user to delete the returned store | |
268 | ||
269 | if (!fESDInterface) { | |
270 | AliError("the refitter must be connected to an ESDInterface containing the ESD event to reconstruct"); | |
271 | return 0x0; | |
272 | } | |
273 | ||
274 | // get the cluster to re-clusterize | |
275 | AliMUONVCluster* cluster = fESDInterface->GetCluster(iTrack,iCluster); | |
276 | if (!cluster) return 0x0; | |
277 | ||
278 | // check if digits exist | |
279 | if (cluster->GetNDigits() == 0) { | |
280 | AliError(Form("no digit attached to cluster #%d in track %d",iCluster,iTrack)); | |
281 | return 0x0; | |
282 | } | |
283 | ||
284 | // create the cluster store | |
285 | AliMUONVClusterStore* clusterStore = AliMUONESDInterface::NewClusterStore(); | |
286 | if (!clusterStore) return 0x0; | |
287 | ||
288 | // re-clusterize | |
289 | TIter next(fESDInterface->CreateDigitIterator(iTrack, iCluster)); | |
290 | fClusterServer->UseDigits(next); | |
291 | fClusterServer->Clusterize(cluster->GetChamberId(),*clusterStore,AliMpArea()); | |
292 | ||
293 | return clusterStore; | |
294 | } | |
295 | ||
296 | //_____________________________________________________________________________ | |
297 | AliMUONVClusterStore* AliMUONRefitter::ReClusterize(UInt_t clusterId) | |
298 | { | |
299 | /// re-clusterize cluster "clusterId" | |
300 | /// several new clusters may be reconstructed | |
301 | /// it is the responsability of the user to delete the returned store | |
302 | ||
303 | if (!fESDInterface) { | |
304 | AliError("the refitter must be connected to an ESDInterface containing the ESD event to reconstruct"); | |
305 | return 0x0; | |
306 | } | |
307 | ||
308 | // get the cluster to re-clusterize | |
309 | AliMUONVCluster* cluster = fESDInterface->FindCluster(clusterId); | |
310 | if (!cluster) return 0x0; | |
311 | ||
312 | // check if digits exist | |
313 | if (cluster->GetNDigits() == 0) { | |
314 | AliError(Form("no digit attached to cluster %d",clusterId)); | |
315 | return 0x0; | |
316 | } | |
317 | ||
318 | // create the cluster store | |
319 | AliMUONVClusterStore* clusterStore = AliMUONESDInterface::NewClusterStore(); | |
320 | if (!clusterStore) return 0x0; | |
321 | ||
322 | // re-clusterize | |
323 | TIter next(fESDInterface->CreateDigitIteratorInCluster(clusterId)); | |
324 | fClusterServer->UseDigits(next); | |
325 | fClusterServer->Clusterize(cluster->GetChamberId(),*clusterStore,AliMpArea()); | |
326 | ||
327 | return clusterStore; | |
328 | } | |
329 | ||
330 | //_____________________________________________________________________________ | |
331 | void AliMUONRefitter::CreateGeometryTransformer() | |
332 | { | |
333 | /// Create geometry transformer (local<->global) | |
334 | /// and load geometry data | |
335 | fGeometryTransformer = new AliMUONGeometryTransformer(); | |
336 | fGeometryTransformer->LoadGeometryData(); | |
337 | } | |
338 | ||
339 | //_____________________________________________________________________________ | |
340 | void AliMUONRefitter::CreateClusterServer(AliMUONGeometryTransformer& transformer) | |
341 | { | |
342 | /// Create cluster server | |
9bf6860b | 343 | AliMUONVClusterFinder* clusterFinder = AliMUONReconstructor::CreateClusterFinder(AliMUONReconstructor::GetRecoParam()->GetClusteringMode()); |
344 | fClusterServer = clusterFinder ? new AliMUONSimpleClusterServer(clusterFinder,transformer) : 0x0; | |
7deb8eb0 | 345 | } |
346 | ||
347 | //_____________________________________________________________________________ | |
348 | void AliMUONRefitter::AddClusterToTracks(const AliMUONVClusterStore &clusterStore, AliMUONVTrackStore &trackStore) | |
349 | { | |
350 | /// add clusters to each of the given tracks | |
351 | /// duplicate the tracks if there are several clusters and add one cluster per copy | |
352 | ||
353 | // create new track store if there are more than 1 cluster to add per track | |
354 | Int_t nClusters = clusterStore.GetSize(); | |
355 | if (nClusters < 1) return; | |
356 | ||
357 | AliMUONTrackParam dummyParam; | |
358 | AliMUONTrack *currentTrack, *track; | |
359 | AliMUONVCluster *newCluster; | |
360 | Int_t nTracks = trackStore.GetSize(); | |
361 | Int_t iTrack = 0; | |
362 | Int_t iCluster = 0; | |
363 | ||
364 | // loop over existing tracks to add the cluster(s) | |
365 | TIter nextTrack(trackStore.CreateIterator()); | |
366 | while ((currentTrack = static_cast<AliMUONTrack*>(nextTrack())) && (iTrack < nTracks)) { | |
367 | ||
368 | iTrack++; | |
369 | ||
370 | // add the new cluster(s) to the tracks | |
371 | // duplicate the tracks if there are several clusters | |
372 | // the loop after loading the last cluster which is added to the current track | |
373 | iCluster = 0; | |
374 | TIter nextCluster(clusterStore.CreateIterator()); | |
375 | while ((newCluster = static_cast<AliMUONVCluster*>(nextCluster())) && (iCluster < nClusters - 1)) { | |
376 | ||
377 | iCluster++; | |
378 | ||
379 | // add a copy of the current track to the store | |
380 | track = trackStore.Add(AliMUONTrack(*currentTrack)); | |
381 | ||
382 | // only set Z parameter to avoid error in AddTrackParamAtCluster() | |
383 | // the rest will be recomputed during refit | |
384 | dummyParam.SetZ(newCluster->GetZ()); | |
385 | ||
386 | // add new cluster to the new track | |
387 | track->AddTrackParamAtCluster(dummyParam, *newCluster, kTRUE); | |
388 | ||
389 | } | |
390 | ||
391 | // only set Z parameter to avoid error in AddTrackParamAtCluster() | |
392 | // the rest will be recomputed during refit | |
393 | dummyParam.SetZ(newCluster->GetZ()); | |
394 | ||
395 | // add new cluster to the current track | |
396 | currentTrack->AddTrackParamAtCluster(dummyParam, *newCluster, kTRUE); | |
397 | ||
398 | } | |
399 | ||
400 | } | |
401 |