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