]>
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 | ||
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 | |
57 | ClassImp(AliMUONRefitter) | |
58 | /// \endcond | |
59 | ||
60 | //_____________________________________________________________________________ | |
61 | AliMUONRefitter::AliMUONRefitter() | |
62 | : TObject(), | |
63 | fGeometryTransformer(0x0), | |
64 | fClusterServer(0x0), | |
65 | fTracker(0x0), | |
66 | fESDInterface(0x0) | |
67 | { | |
68 | /// Default constructor | |
69 | CreateGeometryTransformer(); | |
70 | CreateClusterServer(*fGeometryTransformer); | |
00dc4f26 | 71 | if (fClusterServer) fTracker = AliMUONTracker::CreateTrackReconstructor(AliMUONReconstructor::GetRecoParam()->GetTrackingMode(),fClusterServer); |
7deb8eb0 | 72 | if (!fClusterServer || !fTracker) { |
73 | AliFatal("refitter initialization failed"); | |
74 | exit(-1); | |
75 | } | |
76 | } | |
77 | ||
78 | //_____________________________________________________________________________ | |
79 | AliMUONRefitter::~AliMUONRefitter() | |
80 | { | |
81 | /// Destructor | |
82 | delete fGeometryTransformer; | |
83 | delete fClusterServer; | |
84 | delete fTracker; | |
85 | } | |
86 | ||
87 | //_____________________________________________________________________________ | |
88 | AliMUONVTrackStore* 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 | //_____________________________________________________________________________ | |
114 | AliMUONVTrackStore* 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 | //_____________________________________________________________________________ | |
140 | AliMUONTrack* 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 | //_____________________________________________________________________________ | |
237 | AliMUONTrack* 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 | //_____________________________________________________________________________ | |
262 | AliMUONVClusterStore* 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 | //_____________________________________________________________________________ | |
296 | AliMUONVClusterStore* 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 | //_____________________________________________________________________________ | |
330 | void AliMUONRefitter::CreateGeometryTransformer() | |
331 | { | |
332 | /// Create geometry transformer (local<->global) | |
333 | /// and load geometry data | |
334 | fGeometryTransformer = new AliMUONGeometryTransformer(); | |
335 | fGeometryTransformer->LoadGeometryData(); | |
336 | } | |
337 | ||
338 | //_____________________________________________________________________________ | |
339 | void 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 | //_____________________________________________________________________________ | |
347 | void 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 |