Line data Source code
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 : //-----------------------------------------------------------------------------
19 : /// \class AliMUONTracker
20 : ///
21 : /// Steering class for use in global tracking framework;
22 : /// reconstruct tracks from recpoints
23 : ///
24 : /// Actual tracking is performed by some AliMUONVTrackReconstructor children
25 : /// Tracking modes (ORIGINAL, KALMAN) and associated options and parameters can be changed
26 : /// through the AliMUONRecoParam object set in the reconstruction macro or read from the CDB
27 : /// (see methods in AliMUONRecoParam.h file for details)
28 : ///
29 : /// \author Christian Finck and Laurent Aphecetche, SUBATECH Nantes
30 : //-----------------------------------------------------------------------------
31 :
32 : #include "AliMUONTracker.h"
33 :
34 : #include "AliCodeTimer.h"
35 : #include "AliESDEvent.h"
36 : #include "AliESDMuonTrack.h"
37 : #include "AliESDVertex.h"
38 : #include "AliLog.h"
39 : #include "AliMUONClusterStoreV2.h"
40 : #include "AliMUONESDInterface.h"
41 : #include "AliMUONLegacyClusterServer.h"
42 : #include "AliMUONRecoParam.h"
43 : #include "AliMUONReconstructor.h"
44 : #include "AliMUONTrack.h"
45 : #include "AliMUONTrackExtrap.h"
46 : #include "AliMUONTrackHitPattern.h"
47 : #include "AliMUONTrackParam.h"
48 : #include "AliMUONTrackReconstructor.h"
49 : #include "AliMUONTrackReconstructorK.h"
50 : #include "AliMUONTrackStoreV1.h"
51 : #include "AliMUONTriggerTrackStoreV1.h"
52 : #include "AliMUONTriggerTrack.h"
53 : #include "AliMUONLocalTrigger.h"
54 : #include "AliMUONVClusterServer.h"
55 : #include "AliMUONVDigitStore.h"
56 : #include "AliMUONVTriggerStore.h"
57 : #include "AliMUONTriggerUtilities.h"
58 : #include <Riostream.h>
59 : #include <TRandom.h>
60 : #include <TTree.h>
61 : #include "AliLog.h"
62 :
63 : /// \cond CLASSIMP
64 18 : ClassImp(AliMUONTracker)
65 : /// \endcond
66 :
67 :
68 : //_____________________________________________________________________________
69 : AliMUONTracker::AliMUONTracker(const AliMUONRecoParam* recoParam,
70 : AliMUONVClusterServer* clusterServer,
71 : AliMUONVDigitStore& digitStore,
72 : const AliMUONGeometryTransformer* transformer,
73 : const AliMUONTriggerCircuit* triggerCircuit,
74 : const AliMUONTriggerUtilities* triggerUtilities)
75 2 : : AliTracker(),
76 2 : fkTransformer(transformer), // not owner
77 2 : fkTriggerCircuit(triggerCircuit), // not owner
78 2 : fTrackHitPatternMaker(0x0),
79 2 : fTrackReco(0x0),
80 2 : fClusterStore(0x0),
81 2 : fTriggerStore(0x0),
82 2 : fClusterServer(clusterServer),
83 2 : fIsOwnerOfClusterServer(kFALSE),
84 2 : fkDigitStore(digitStore), // not owner
85 2 : fInputClusterStore(0x0),
86 2 : fTriggerTrackStore(0x0),
87 2 : fkRecoParam(recoParam),
88 2 : fInternalTrackStore(0x0)
89 10 : {
90 : /// constructor
91 :
92 2 : if (fkTransformer)
93 6 : fTrackHitPatternMaker = new AliMUONTrackHitPattern(recoParam,*fkTransformer,fkDigitStore,triggerUtilities);
94 :
95 2 : if (!fClusterServer)
96 : {
97 10 : AliDebug(1,"No cluster server given. Will use AliMUONLegacyClusterServer");
98 2 : fIsOwnerOfClusterServer = kTRUE;
99 2 : }
100 : else
101 : {
102 0 : TIter next(fkDigitStore.CreateIterator());
103 0 : fClusterServer->UseDigits(next,&digitStore);
104 :
105 0 : SetupClusterServer(*fClusterServer);
106 0 : }
107 4 : }
108 :
109 : //_____________________________________________________________________________
110 : AliMUONTracker::~AliMUONTracker()
111 12 : {
112 : /// dtor
113 :
114 4 : delete fTrackReco;
115 4 : delete fTrackHitPatternMaker;
116 4 : delete fClusterStore;
117 4 : delete fTriggerStore;
118 6 : if ( fIsOwnerOfClusterServer ) delete fClusterServer;
119 4 : delete fInputClusterStore;
120 4 : delete fTriggerTrackStore;
121 4 : delete fInternalTrackStore;
122 6 : }
123 :
124 : //_____________________________________________________________________________
125 : AliMUONVClusterStore*
126 : AliMUONTracker::ClusterStore() const
127 : {
128 : /// Return (and create if necessary) the cluster container
129 48 : if (!fClusterStore)
130 : {
131 4 : fClusterStore = new AliMUONClusterStoreV2;
132 2 : }
133 24 : return fClusterStore;
134 0 : }
135 :
136 : //_____________________________________________________________________________
137 : AliMUONVTriggerTrackStore*
138 : AliMUONTracker::TriggerTrackStore() const
139 : {
140 : /// Return (and create if necessary) the trigger track container
141 64 : if (!fTriggerTrackStore)
142 : {
143 4 : fTriggerTrackStore = new AliMUONTriggerTrackStoreV1;
144 2 : }
145 32 : return fTriggerTrackStore;
146 0 : }
147 :
148 : //_____________________________________________________________________________
149 : Int_t AliMUONTracker::LoadClusters(TTree* clustersTree)
150 : {
151 : /// Load triggerStore from clustersTree
152 :
153 16 : if ( ! clustersTree ) {
154 0 : AliFatal("No clustersTree");
155 0 : return 1;
156 : }
157 :
158 8 : if ( !fTriggerStore )
159 : {
160 2 : fTriggerStore = AliMUONVTriggerStore::Create(*clustersTree);
161 2 : }
162 :
163 8 : if (!fTriggerStore)
164 : {
165 0 : AliError("Could not get triggerStore");
166 0 : return 2;
167 : }
168 :
169 8 : if (!fInputClusterStore)
170 : {
171 2 : fInputClusterStore = AliMUONVClusterStore::Create(*clustersTree);
172 2 : if (!fInputClusterStore)
173 : {
174 0 : AliError("Could not get clusterStore");
175 0 : return 3;
176 : }
177 6 : AliDebug(1,Form("Created %s from cluster tree",fInputClusterStore->ClassName()));
178 : }
179 :
180 10 : if ( !fClusterServer && fIsOwnerOfClusterServer )
181 : {
182 2 : if ( !fClusterServer )
183 : {
184 6 : fClusterServer = new AliMUONLegacyClusterServer(*fkTransformer,fInputClusterStore,
185 2 : GetRecoParam()->BypassSt4(),
186 2 : GetRecoParam()->BypassSt5());
187 2 : SetupClusterServer(*fClusterServer);
188 2 : }
189 :
190 : }
191 :
192 8 : fInputClusterStore->Clear();
193 8 : fInputClusterStore->Connect(*clustersTree,kFALSE);
194 8 : fTriggerStore->Clear();
195 8 : fTriggerStore->Connect(*clustersTree,kFALSE);
196 :
197 8 : clustersTree->GetEvent(0);
198 :
199 8 : return 0;
200 8 : }
201 :
202 : //_____________________________________________________________________________
203 : Int_t AliMUONTracker::Clusters2Tracks(AliESDEvent* esd)
204 : {
205 : /// Performs the tracking and store the resulting tracks in the ESD
206 : ///
207 : /// note that we're dealing with two cluster stores here : fInputClusterStore
208 : /// and ClusterStore().
209 : /// The first one is read from the TreeR and may be used by the cluster server
210 : /// (that's the case for the legacy cluster server) to fill the other one.
211 : /// The second one is more dynamic and might be created on the fly by the cluster
212 : /// server (used by the combined tracking, in which case the first one is not used
213 : /// at all).
214 :
215 16 : AliCodeTimerAuto("",0)
216 :
217 8 : if (!fTrackReco)
218 : {
219 4 : fTrackReco = CreateTrackReconstructor(GetRecoParam(),fClusterServer,fkTransformer);
220 6 : fInternalTrackStore = new AliMUONTrackStoreV1;
221 2 : }
222 :
223 : // if the required tracking mode does not exist
224 8 : if (!fTrackReco) return 1;
225 :
226 16 : if ( ! ClusterStore() )
227 : {
228 0 : AliError("ClusterStore is NULL");
229 0 : return 2;
230 : }
231 :
232 8 : if (!fTriggerStore) {
233 0 : AliError("TriggerStore is NULL");
234 0 : return 3;
235 : }
236 :
237 : // Make trigger tracks
238 8 : if ( fkTriggerCircuit )
239 : {
240 16 : TriggerTrackStore()->Clear();
241 16 : fTrackReco->EventReconstructTrigger(*fkTriggerCircuit,*fTriggerStore,*(TriggerTrackStore()));
242 : }
243 :
244 24 : if ( TriggerTrackStore()->GetSize() > GetRecoParam()->GetMaxTriggerTracks() )
245 : {
246 : // cut to reject shower events
247 :
248 0 : AliCodeTimerAuto("MUON Shower events",1);
249 :
250 0 : AliWarning(Form("Probably got a shower event (%d trigger tracks). Will not reconstruct tracks.",
251 : TriggerTrackStore()->GetSize()));
252 :
253 : return 0;
254 0 : }
255 :
256 16 : fTrackReco->EventReconstruct(*(ClusterStore()),*fInternalTrackStore);
257 :
258 : // Match tracker/trigger tracks
259 8 : if ( fTrackHitPatternMaker )
260 : {
261 16 : fTrackReco->ValidateTracksWithTrigger(*fInternalTrackStore,*(TriggerTrackStore()),*fTriggerStore,*fTrackHitPatternMaker);
262 : }
263 :
264 : // Fill ESD
265 8 : FillESD(*fInternalTrackStore,esd);
266 :
267 8 : fInternalTrackStore->Clear();
268 16 : ClusterStore()->Clear();
269 :
270 8 : return 0;
271 8 : }
272 :
273 : //_____________________________________________________________________________
274 : void AliMUONTracker::FillESD(const AliMUONVTrackStore& trackStore, AliESDEvent* esd) const
275 : {
276 : /// Fill the ESD from the trackStore
277 32 : AliDebug(1,"");
278 8 : AliCodeTimerAuto("",0)
279 :
280 : // get ITS vertex
281 8 : Double_t vertex[3] = {0., 0., 0.};
282 8 : const AliESDVertex* esdVert = esd->GetVertex();
283 16 : if (esdVert->GetNContributors() > 0 || !strcmp(esdVert->GetTitle(),"vertexer: smearMC")) {
284 8 : esdVert->GetXYZ(vertex);
285 40 : AliDebug(1,Form("found vertex (%e,%e,%e)",vertex[0],vertex[1],vertex[2]));
286 : }
287 :
288 : // fill ESD event including all info in ESD cluster if required and only for the given fraction of events
289 : AliMUONTrack* track;
290 : AliMUONLocalTrigger* locTrg;
291 16 : TIter next(trackStore.CreateIterator());
292 16 : if (GetRecoParam()->SaveFullClusterInESD() &&
293 16 : gRandom->Uniform(100.) <= GetRecoParam()->GetPercentOfFullClusterInESD()) {
294 :
295 0 : while ( ( track = static_cast<AliMUONTrack*>(next()) ) ) {
296 :
297 0 : if (track->GetMatchTrigger() > 0) {
298 0 : locTrg = static_cast<AliMUONLocalTrigger*>(fTriggerStore->FindLocal(track->LoCircuit()));
299 0 : AliMUONESDInterface::MUONToESD(*track, *esd, vertex, &fkDigitStore, locTrg);
300 0 : } else AliMUONESDInterface::MUONToESD(*track, *esd, vertex, &fkDigitStore);
301 :
302 : }
303 :
304 : } else {
305 :
306 48 : while ( ( track = static_cast<AliMUONTrack*>(next()) ) ) {
307 :
308 16 : if (track->GetMatchTrigger() > 0) {
309 12 : locTrg = static_cast<AliMUONLocalTrigger*>(fTriggerStore->FindLocal(track->LoCircuit()));
310 12 : AliMUONESDInterface::MUONToESD(*track, *esd, vertex, 0x0, locTrg);
311 4 : } else AliMUONESDInterface::MUONToESD(*track, *esd, vertex);
312 :
313 : }
314 :
315 : }
316 :
317 : // fill the local trigger decisions not matched with tracks (associate them to "ghost" tracks)
318 : UInt_t ghostId = 0xFFFFFFFF - 1;
319 : Bool_t matched = kFALSE;
320 : AliMUONTriggerTrack *triggerTrack;
321 16 : TIter itTriggerTrack(fTriggerTrackStore->CreateIterator());
322 44 : while ( ( triggerTrack = static_cast<AliMUONTriggerTrack*>(itTriggerTrack()) ) ) {
323 :
324 14 : locTrg = static_cast<AliMUONLocalTrigger*>(fTriggerStore->FindLocal(triggerTrack->GetLoTrgNum()));
325 :
326 : // check if this local trigger has already been matched
327 28 : TIter itTrack(trackStore.CreateIterator());
328 48 : while ( ( track = static_cast<AliMUONTrack*>(itTrack()) ) ) {
329 22 : matched = (track->LoCircuit() == locTrg->LoCircuit());
330 22 : if (matched) break;
331 : }
332 26 : if (matched) continue;
333 :
334 2 : AliMUONESDInterface::MUONToESD(*locTrg, *esd, ghostId, triggerTrack);
335 :
336 2 : ghostId -= 1;
337 16 : }
338 :
339 8 : }
340 :
341 : //_____________________________________________________________________________
342 : AliMUONVTrackReconstructor* AliMUONTracker::CreateTrackReconstructor(const AliMUONRecoParam* recoParam,
343 : AliMUONVClusterServer* clusterServer,
344 : const AliMUONGeometryTransformer* transformer)
345 : {
346 : /// Create track reconstructor, depending on tracking mode set in RecoParam
347 :
348 : AliMUONVTrackReconstructor* trackReco(0x0);
349 :
350 4 : TString opt(recoParam->GetTrackingMode());
351 2 : opt.ToUpper();
352 :
353 6 : if (strstr(opt,"ORIGINAL"))
354 : {
355 0 : trackReco = new AliMUONTrackReconstructor(recoParam,clusterServer,transformer);
356 0 : }
357 6 : else if (strstr(opt,"KALMAN"))
358 : {
359 6 : trackReco = new AliMUONTrackReconstructorK(recoParam,clusterServer,transformer);
360 : }
361 : else
362 : {
363 0 : AliErrorClass(Form("tracking mode \"%s\" does not exist",opt.Data()));
364 0 : return 0x0;
365 : }
366 :
367 12 : AliDebugClass(1,Form("Will use %s for tracking",trackReco->ClassName()));
368 :
369 2 : return trackReco;
370 2 : }
371 :
372 : //_____________________________________________________________________________
373 : void AliMUONTracker::UnloadClusters()
374 : {
375 : /// Clear internal clusterStore
376 :
377 16 : fInputClusterStore->Clear();
378 8 : }
379 :
380 :
381 : //_____________________________________________________________________________
382 : void
383 : AliMUONTracker::SetupClusterServer(AliMUONVClusterServer& clusterServer)
384 : {
385 : /// Setup the cluster server
386 :
387 6 : if ( GetRecoParam()->BypassSt4() ||
388 2 : GetRecoParam()->BypassSt5() )
389 : {
390 0 : Bool_t ok = clusterServer.UseTriggerTrackStore(TriggerTrackStore());
391 :
392 0 : TString msg1;
393 0 : TString msg2;
394 :
395 0 : if ( GetRecoParam()->BypassSt45() )
396 : {
397 0 : msg1 = "STATIONS 4 AND 5";
398 0 : msg2 = "THOSE TWO STATIONS";
399 : }
400 0 : else if ( GetRecoParam()->BypassSt4() )
401 : {
402 0 : msg1 = "STATION 4";
403 0 : msg2 = "THAT STATION";
404 : }
405 0 : else if ( GetRecoParam()->BypassSt5() )
406 : {
407 0 : msg1 = "STATION 5";
408 0 : msg2 = "THAT STATION";
409 : }
410 :
411 0 : if ( ok )
412 : {
413 0 : AliWarning(Form("WILL USE TRIGGER TRACKS TO GENERATE CLUSTERS IN %s, "
414 : "THUS BYPASSING REAL CLUSTERS IN %s!!!",msg1.Data(),msg2.Data()));
415 : }
416 : else
417 : {
418 0 : AliWarning("BYPASSING OF ST4 AND/OR 5 REQUESTED, BUT CLUSTERSERVER DOES NOT SEEM TO SUPPORT IT !!!");
419 : }
420 0 : }
421 2 : }
422 :
423 :
|