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