]> git.uio.no Git - u/mrichter/AliRoot.git/blob - MUON/AliMUONESDInterface.cxx
Exec changed to UserExec.
[u/mrichter/AliRoot.git] / MUON / AliMUONESDInterface.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 #include "AliMUONESDInterface.h"
19 #include "AliMUONTrack.h"
20 #include "AliMUONVTrackStore.h"
21 #include "AliMUONVCluster.h"
22 #include "AliMUONVClusterStore.h"
23 #include "AliMUONVDigit.h"
24 #include "AliMUONVDigitStore.h"
25 #include "AliMUONLocalTrigger.h"
26 #include "AliMUONVTriggerStore.h"
27 #include "AliMUON2DMapIterator.h"
28 #include "AliMUONTrackParam.h"
29 #include "AliMUONTrackExtrap.h"
30 #include "AliMUONConstants.h"
31 #include "AliMUONTracker.h"
32 #include "AliMUONRecoParam.h"
33 #include "AliMUONVTrackReconstructor.h"
34
35 #include "AliMpExMapIterator.h"
36 #include "AliMpVSegmentation.h"
37 #include "AliMpSegmentation.h"
38 #include "AliMpIntPair.h"
39 #include "AliMpPad.h"
40
41 #include "AliESDEvent.h"
42 #include "AliESDMuonTrack.h"
43 #include "AliESDMuonCluster.h"
44 #include "AliESDMuonPad.h"
45 #include "AliLog.h"
46
47 #include <TClass.h>
48 #include <TIterator.h>
49 #include <TMath.h>
50 #include <TMatrixD.h>
51 #include <Riostream.h>
52
53 //-----------------------------------------------------------------------------
54 /// \class AliMUONESDInterface
55 ///
56 /// There are 2 way of using thid converter between MUON track/cluster/digit
57 /// and ESDMuon track/cluster/pad:
58 /// 
59 /// 1) using the static methods converting the objects one by one
60 ///
61 /// 2) loading a whole ESDEvent and using the finders and/or the iterators
62 ///    to access the corresponding MUON objects
63 ///
64 /// \author Philippe Pillot
65 //-----------------------------------------------------------------------------
66
67 /// \cond CLASSIMP
68 ClassImp(AliMUONESDInterface)
69 /// \endcond
70
71 AliMUONVTrackReconstructor* AliMUONESDInterface::fgTracker = 0x0;
72
73 TString AliMUONESDInterface::fgTrackStoreName = "AliMUONTrackStoreV1";
74 TString AliMUONESDInterface::fgClusterStoreName = "AliMUONClusterStoreV2";
75 TString AliMUONESDInterface::fgDigitStoreName = "AliMUONDigitStoreV2R";
76 TString AliMUONESDInterface::fgTriggerStoreName = "AliMUONTriggerStoreV1";
77
78 //_____________________________________________________________________________
79 AliMUONESDInterface::AliMUONESDInterface(AliMUONRecoParam* recoParam)
80 : TObject(),
81 fRecoParam(recoParam),
82 fTracks(0x0),
83 fDigits(0x0),
84 fTriggers(0x0),
85 fClusterMap(0x0),
86 fDigitMap(0x0)
87 {
88   /// Default constructor
89 }
90
91 //_____________________________________________________________________________
92 AliMUONESDInterface::~AliMUONESDInterface()
93 {
94   /// Destructor
95   delete fTracks;
96   delete fDigits;
97   delete fTriggers;
98   delete fClusterMap;
99   delete fDigitMap;
100 }
101
102 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
103 //                    methods to play with internal objects                    //
104 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
105
106 //_____________________________________________________________________________
107 void AliMUONESDInterface::Clear(Option_t*)
108 {
109   /// clear memory
110   delete fTracks; fTracks = 0x0;
111   delete fDigits; fDigits = 0x0;
112   delete fTriggers; fTriggers = 0x0;
113   delete fClusterMap; fClusterMap = 0x0;
114   delete fDigitMap; fDigitMap = 0x0;
115 }
116
117 //_____________________________________________________________________________
118 void AliMUONESDInterface::Reset()
119 {
120   /// reset stores and maps
121   
122   if (fTracks) fTracks->Clear("C");
123   else fTracks = NewTrackStore();
124   
125   if (fDigits) fDigits->Clear("C");
126   else fDigits = NewDigitStore();
127   
128   if (fTriggers) fTriggers->Clear("C");
129   else fTriggers = NewTriggerStore();
130   
131   if (fClusterMap) fClusterMap->Clear();
132   else fClusterMap = new AliMpExMap;
133   fClusterMap->SetOwner(kTRUE);
134   
135   if (fDigitMap) fDigitMap->Clear();
136   else fDigitMap = new AliMpExMap;
137   fDigitMap->SetOwner(kTRUE);
138 }
139
140 //_____________________________________________________________________________
141 void AliMUONESDInterface::LoadEvent(AliESDEvent& esdEvent)
142 {
143   /// Extract MUON data from the given ESD event
144   
145   // reset data members
146   Reset();
147   
148   // loop over ESD tracks and fill the stores
149   Int_t nTracks = (Int_t) esdEvent.GetNumberOfMuonTracks(); 
150   for (Int_t iTrack = 0; iTrack <  nTracks; iTrack++) {
151     
152     // get ESD track
153     AliESDMuonTrack* esdTrack = esdEvent.GetMuonTrack(iTrack);
154     
155     // fill trigger store if related info are availables
156     if (esdTrack->ContainTriggerData()) Add(*esdTrack, *fTriggers);
157     
158     // fill tracker data if availables
159     if (!esdTrack->ContainTrackerData()) continue;
160     
161     // add it to track store
162     AliMUONTrack* track = Add(GetRecoParam(),*esdTrack, *fTracks);
163     
164     // prepare cluster map
165     AliMpExMap* cMap = new AliMpExMap;
166     cMap->SetOwner(kFALSE);
167     fClusterMap->Add(esdTrack->GetUniqueID(), cMap);
168     
169     // prepare digit maps
170     AliMpExMap* dMaps = new AliMpExMap;
171     dMaps->SetOwner(kTRUE);
172     fDigitMap->Add(esdTrack->GetUniqueID(), dMaps);
173     
174     // loop over ESD clusters
175     Int_t nClusters = esdTrack->GetNClusters();
176     for (Int_t iCluster = 0; iCluster <  nClusters; iCluster++) {
177       
178       // get ESD cluster
179       AliESDMuonCluster *esdCluster = (AliESDMuonCluster*) esdTrack->GetClusters().UncheckedAt(iCluster);
180       
181       // get the corresponding MUON cluster
182       AliMUONVCluster* cluster = FindClusterInTrack(*track, esdCluster->GetUniqueID());
183       
184       // fill cluster map
185       cMap->Add(cluster->GetUniqueID(), cluster);
186       
187       // prepare digit map
188       AliMpExMap* dMap =new AliMpExMap;
189       dMap->SetOwner(kFALSE);
190       dMaps->Add(esdCluster->GetUniqueID(), dMap);
191       
192       // loop over ESD pads
193       Int_t nPads = esdCluster->GetNPads();
194       for (Int_t iPad = 0; iPad < nPads; iPad++) {
195         
196         // get ESD pad
197         AliESDMuonPad *esdPad = (AliESDMuonPad*) esdCluster->GetPads().UncheckedAt(iPad);
198         
199         // add it to digit store
200         AliMUONVDigit* digit = Add(*esdPad, *fDigits);
201         
202         // fill digit map
203         if (digit) dMap->Add(esdPad->GetUniqueID(), digit);
204         else dMap->Add(esdPad->GetUniqueID(), fDigits->FindObject(esdPad->GetUniqueID()));
205         
206       } // end of loop over pads
207       
208     } // end of loop over clusters
209     
210   } // end of loop over tracks
211   
212 }
213
214 //___________________________________________________________________________
215 Int_t AliMUONESDInterface::GetNTracks() const
216 {
217   /// return the number of tracks
218   return fTracks ? fTracks->GetSize() : 0;
219 }
220
221 //___________________________________________________________________________
222 Int_t AliMUONESDInterface::GetNClusters() const
223 {
224   /// return the number of clusters
225   Int_t nClusters = 0;
226   AliMUONTrack *track;
227   TIter next(CreateTrackIterator());
228   while ((track = static_cast<AliMUONTrack*>(next()))) nClusters += track->GetNClusters();
229   return nClusters;
230 }
231
232 //___________________________________________________________________________
233 Int_t AliMUONESDInterface::GetNClusters(UInt_t trackId) const
234 {
235   /// return the number of clusters in track "trackId"
236   AliMUONTrack* track = FindTrack(trackId);
237   return track ? track->GetNClusters() : 0;
238 }
239
240 //___________________________________________________________________________
241 Int_t AliMUONESDInterface::GetNDigits() const
242 {
243   /// return the number of digits
244   return fDigits ? fDigits->GetSize() : 0;
245 }
246
247 //___________________________________________________________________________
248 Int_t AliMUONESDInterface::GetNDigits(UInt_t trackId) const
249 {
250   /// return the number of digits in all clusters of track "trackId"
251   Int_t nDigits = 0;
252   AliMUONVCluster *cluster;
253   TIter next(CreateClusterIterator(trackId));
254   while ((cluster = static_cast<AliMUONVCluster*>(next()))) nDigits += cluster->GetNDigits();
255   return nDigits;
256 }
257
258 //___________________________________________________________________________
259 Int_t AliMUONESDInterface::GetNDigits(UInt_t trackId, UInt_t clusterId) const
260 {
261   /// return the number of digits in cluster numbered "iCluster" of track "iTrack"
262   AliMUONVCluster* cluster = FindCluster(trackId, clusterId);
263   return cluster ? cluster->GetNDigits() : 0;
264 }
265
266 //___________________________________________________________________________
267 Int_t AliMUONESDInterface::GetNDigitsInCluster(UInt_t clusterId) const
268 {
269   /// return the number of digits in cluster "clusterId"
270   AliMUONVCluster* cluster = FindCluster(clusterId);
271   return cluster ? cluster->GetNDigits() : 0;
272 }
273
274 //___________________________________________________________________________
275 Int_t AliMUONESDInterface::GetNTriggers() const
276 {
277   /// return the number of triggers
278   return fTriggers ? fTriggers->GetSize() : 0;
279 }
280
281 //___________________________________________________________________________
282 AliMUONTrack* AliMUONESDInterface::FindTrack(UInt_t trackId) const
283 {
284   /// return track "trackId" (0x0 if not found)
285   AliMUONTrack *track = fTracks ? static_cast<AliMUONTrack*>(fTracks->FindObject(trackId)) : 0x0;
286   if (!track) AliWarning(Form("track %d does not exist",trackId));
287   return track;
288 }
289
290 //___________________________________________________________________________
291 AliMUONVCluster* AliMUONESDInterface::FindCluster(UInt_t clusterId) const
292 {
293   /// loop over tracks and return the first cluster "clusterId" found (0x0 if not found)
294   AliMpExMap *cMap;
295   AliMUONVCluster* cluster = 0x0;
296   
297   if (fClusterMap) {
298     
299     TIter next(fClusterMap->CreateIterator());
300     while ((cMap = static_cast<AliMpExMap*>(next()))) {
301       
302       cluster = static_cast<AliMUONVCluster*>(cMap->GetValue(clusterId));
303       if (cluster) return cluster;
304       
305     }
306     
307   }
308   
309   if (!cluster) AliWarning(Form("cluster %d does not exist",clusterId));
310   return 0x0;
311 }
312
313 //___________________________________________________________________________
314 AliMUONVCluster* AliMUONESDInterface::FindCluster(UInt_t trackId, UInt_t clusterId) const
315 {
316   /// return cluster "clusterId" in track "trackId" (0x0 if not found)
317   AliMpExMap *cMap = fClusterMap ? static_cast<AliMpExMap*>(fClusterMap->GetValue(trackId)) : 0x0;
318   AliMUONVCluster* cluster = cMap ? static_cast<AliMUONVCluster*>(cMap->GetValue(clusterId)) : 0x0;
319   if (!cluster) AliWarning(Form("cluster %d does not exist in track %d", clusterId, trackId));
320   return cluster;
321 }
322
323 //___________________________________________________________________________
324 AliMUONVDigit* AliMUONESDInterface::FindDigit(UInt_t digitId) const
325 {
326   /// return digit "digitId" (0x0 if not found)
327   AliMUONVDigit *digit = fDigits ? fDigits->FindObject(digitId) : 0x0;
328   if (!digit) AliWarning(Form("digit %d does not exist",digitId));
329   return digit;
330 }
331
332 //___________________________________________________________________________
333 AliMUONLocalTrigger* AliMUONESDInterface::FindLocalTrigger(Int_t boardNumber) const
334 {
335   /// return MUON local trigger "boardNumber"
336   return (fTriggers) ? fTriggers->FindLocal(boardNumber) : 0x0;
337 }
338
339 //___________________________________________________________________________
340 TIterator* AliMUONESDInterface::CreateTrackIterator() const
341 {
342   /// return iterator over all tracks
343   return fTracks ? fTracks->CreateIterator() : 0x0;
344 }
345
346 //___________________________________________________________________________
347 TIterator* AliMUONESDInterface::CreateClusterIterator() const
348 {
349   /// return iterator over all clusters
350   return fClusterMap ? new AliMUON2DMapIterator(*fClusterMap) : 0x0;
351 }
352
353 //___________________________________________________________________________
354 TIterator* AliMUONESDInterface::CreateClusterIterator(UInt_t trackId) const
355 {
356   /// return iterator over clusters of track "trackId"
357   AliMpExMap *cMap = fClusterMap ? static_cast<AliMpExMap*>(fClusterMap->GetValue(trackId)) : 0x0;
358   return cMap ? cMap->CreateIterator() : 0x0;
359 }
360
361 //___________________________________________________________________________
362 TIterator* AliMUONESDInterface::CreateDigitIterator() const
363 {
364   /// return iterator over all digits
365   return fDigits ? fDigits->CreateIterator() : 0x0;
366 }
367
368 //___________________________________________________________________________
369 TIterator* AliMUONESDInterface::CreateDigitIterator(UInt_t trackId) const
370 {
371   /// return iterator over all digits of track "trackId"
372   AliMpExMap* dMaps = fDigitMap ? static_cast<AliMpExMap*>(fDigitMap->GetValue(trackId)) : 0x0;
373   return dMaps ? new AliMUON2DMapIterator(*dMaps) : 0x0;
374 }
375
376 //___________________________________________________________________________
377 TIterator* AliMUONESDInterface::CreateDigitIterator(UInt_t trackId, UInt_t clusterId) const
378 {
379   /// return iterator over digits of cluster "clusterId" in track "trackId"
380   AliMpExMap* dMaps = fDigitMap ? static_cast<AliMpExMap*>(fDigitMap->GetValue(trackId)) : 0x0;
381   AliMpExMap* dMap = dMaps ? static_cast<AliMpExMap*>(dMaps->GetValue(clusterId)) : 0x0;
382   return dMap ? dMap->CreateIterator() : 0x0;
383 }
384
385 //___________________________________________________________________________
386 TIterator* AliMUONESDInterface::CreateDigitIteratorInCluster(UInt_t clusterId) const
387 {
388   /// return iterator over digits of the first cluster "clusterId" found by looping over all tracks
389   AliMpExMap *dMaps;
390   AliMpExMap* dMap = 0x0;
391   
392   if (fDigitMap) {
393     
394     TIter next(fDigitMap->CreateIterator());
395     while ((dMaps = static_cast<AliMpExMap*>(next()))) {
396       
397       dMap = static_cast<AliMpExMap*>(dMaps->GetValue(clusterId));
398       if (dMap) return dMap->CreateIterator();
399       
400     }
401     
402   }
403   
404   return 0x0;
405 }
406
407 //___________________________________________________________________________
408 TIterator* AliMUONESDInterface::CreateLocalTriggerIterator() const
409 {
410   /// return iterator over all local trigger
411   return fTriggers ? fTriggers->CreateLocalIterator() : 0x0;
412 }
413
414 //___________________________________________________________________________
415 AliMUONVCluster* AliMUONESDInterface::FindClusterInTrack(const AliMUONTrack& track, UInt_t clusterId) const
416 {
417   /// find the cluster with the given Id into the track
418   
419   Int_t nClusters = track.GetNClusters();
420   for (Int_t iCluster = 0; iCluster < nClusters; iCluster++) {
421     
422     AliMUONVCluster* cluster = ((AliMUONTrackParam*) track.GetTrackParamAtCluster()->UncheckedAt(iCluster))->GetClusterPtr();
423     if (cluster->GetUniqueID() == clusterId) return cluster;
424     
425   }
426   
427   return 0x0;
428 }
429
430 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
431 //                                static methods                               //
432 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
433
434 //_____________________________________________________________________________
435 AliMUONVTrackStore* AliMUONESDInterface::NewTrackStore()
436 {
437   /// Create an empty track store of type fgTrackStoreName
438   TClass* classPtr = TClass::GetClass(fgTrackStoreName);
439   if (!classPtr || !classPtr->InheritsFrom("AliMUONVTrackStore")) {
440     cout<<"E-AliMUONESDInterface::NewTrackStore: Unable to create store of type "<<fgTrackStoreName.Data()<<endl;
441     return 0x0;
442   }
443   return reinterpret_cast<AliMUONVTrackStore*>(classPtr->New());
444 }
445
446 //_____________________________________________________________________________
447 AliMUONVClusterStore* AliMUONESDInterface::NewClusterStore()
448 {
449   /// Create an empty cluster store of type fgClusterStoreName
450   TClass* classPtr = TClass::GetClass(fgClusterStoreName);
451   if (!classPtr || !classPtr->InheritsFrom("AliMUONVClusterStore")) {
452     cout<<"E-AliMUONESDInterface::NewClusterStore: Unable to create store of type "<<fgClusterStoreName.Data()<<endl;
453     return 0x0;
454   }
455   return reinterpret_cast<AliMUONVClusterStore*>(classPtr->New());
456 }
457
458 //_____________________________________________________________________________
459 AliMUONVDigitStore* AliMUONESDInterface::NewDigitStore()
460 {
461   /// Create an empty digit store of type fgDigitStoreName
462   TClass* classPtr = TClass::GetClass(fgDigitStoreName);
463   if (!classPtr || !classPtr->InheritsFrom("AliMUONVDigitStore")) {
464     cout<<"E-AliMUONESDInterface::NewDigitStore: Unable to create store of type "<<fgDigitStoreName.Data()<<endl;
465     return 0x0;
466   }
467   return reinterpret_cast<AliMUONVDigitStore*>(classPtr->New());
468 }
469
470 //_____________________________________________________________________________
471 AliMUONVTriggerStore* AliMUONESDInterface::NewTriggerStore()
472 {
473   /// Create an empty trigger store of type fgTriggerStoreName
474   TClass* classPtr = TClass::GetClass(fgTriggerStoreName);
475   if (!classPtr || !classPtr->InheritsFrom("AliMUONVTriggerStore")) {
476     cout<<"E-AliMUONESDInterface::NewTriggerStore: Unable to create store of type "<<fgTriggerStoreName.Data()<<endl;
477     return 0x0;
478   }
479   return reinterpret_cast<AliMUONVTriggerStore*>(classPtr->New());
480 }
481
482 //_________________________________________________________________________
483 void AliMUONESDInterface::GetParamAtVertex(const AliESDMuonTrack& esdTrack, AliMUONTrackParam& trackParam)
484 {
485   /// Get parameters at vertex from ESDMuon track
486   trackParam.SetZ(esdTrack.GetZ());
487   trackParam.SetNonBendingCoor(esdTrack.GetNonBendingCoor());
488   trackParam.SetNonBendingSlope(TMath::Tan(esdTrack.GetThetaX()));
489   trackParam.SetBendingCoor(esdTrack.GetBendingCoor());
490   trackParam.SetBendingSlope(TMath::Tan(esdTrack.GetThetaY()));
491   trackParam.SetInverseBendingMomentum(esdTrack.GetInverseBendingMomentum());
492 }
493
494 //_________________________________________________________________________
495 void AliMUONESDInterface::GetParamAtDCA(const AliESDMuonTrack& esdTrack, AliMUONTrackParam& trackParam)
496 {
497   /// Get parameters at DCA from ESDMuon track
498   trackParam.SetZ(esdTrack.GetZ());
499   trackParam.SetNonBendingCoor(esdTrack.GetNonBendingCoorAtDCA());
500   trackParam.SetNonBendingSlope(TMath::Tan(esdTrack.GetThetaXAtDCA()));
501   trackParam.SetBendingCoor(esdTrack.GetBendingCoorAtDCA());
502   trackParam.SetBendingSlope(TMath::Tan(esdTrack.GetThetaYAtDCA()));
503   trackParam.SetInverseBendingMomentum(esdTrack.GetInverseBendingMomentumAtDCA());
504 }
505
506 //_________________________________________________________________________
507 void AliMUONESDInterface::GetParamAtFirstCluster(const AliESDMuonTrack& esdTrack, AliMUONTrackParam& trackParam)
508 {
509   /// Get parameters at first cluster from ESDMuon track
510   trackParam.SetZ(esdTrack.GetZUncorrected());
511   trackParam.SetNonBendingCoor(esdTrack.GetNonBendingCoorUncorrected());
512   trackParam.SetNonBendingSlope(TMath::Tan(esdTrack.GetThetaXUncorrected()));
513   trackParam.SetBendingCoor(esdTrack.GetBendingCoorUncorrected());
514   trackParam.SetBendingSlope(TMath::Tan(esdTrack.GetThetaYUncorrected()));
515   trackParam.SetInverseBendingMomentum(esdTrack.GetInverseBendingMomentumUncorrected());
516 }
517
518 //_________________________________________________________________________
519 void AliMUONESDInterface::GetParamCov(const AliESDMuonTrack& esdTrack, AliMUONTrackParam& trackParam)
520 {
521   /// Get parameters covariances from ESD track
522   
523   // get ESD covariance matrix
524   TMatrixD covariances(5,5);
525   esdTrack.GetCovariances(covariances);
526   
527   // compute Jacobian to change the coordinate system
528   // from (X,thetaX,Y,thetaY,c/pYZ) to (X,slopeX,Y,slopeY,c/pYZ)
529   Double_t cosThetaX = TMath::Cos(esdTrack.GetThetaXUncorrected());
530   Double_t cosThetaY = TMath::Cos(esdTrack.GetThetaYUncorrected());
531   TMatrixD jacob(5,5);
532   jacob.Zero();
533   jacob(0,0) = 1.;
534   jacob(1,1) = 1. / cosThetaX / cosThetaX;
535   jacob(2,2) = 1.;
536   jacob(3,3) = 1. / cosThetaY / cosThetaY;
537   jacob(4,4) = 1.;
538   
539   // compute covariance matrix in ESD coordinate system
540   TMatrixD tmp(covariances,TMatrixD::kMultTranspose,jacob);
541   trackParam.SetCovariances(TMatrixD(jacob,TMatrixD::kMult,tmp));
542   
543 }
544
545 //_________________________________________________________________________
546 void AliMUONESDInterface::SetParamAtVertex(const AliMUONTrackParam& trackParam, AliESDMuonTrack& esdTrack)
547 {
548   /// Set parameters in ESD track
549   esdTrack.SetZ(trackParam.GetZ());
550   esdTrack.SetNonBendingCoor(trackParam.GetNonBendingCoor());
551   esdTrack.SetThetaX(TMath::ATan(trackParam.GetNonBendingSlope()));
552   esdTrack.SetBendingCoor(trackParam.GetBendingCoor()); 
553   esdTrack.SetThetaY(TMath::ATan(trackParam.GetBendingSlope()));
554   esdTrack.SetInverseBendingMomentum(trackParam.GetInverseBendingMomentum());
555 }
556
557 //_________________________________________________________________________
558 void AliMUONESDInterface::SetParamAtDCA(const AliMUONTrackParam& trackParam, AliESDMuonTrack& esdTrack)
559 {
560   /// Set parameters in ESD track
561   esdTrack.SetNonBendingCoorAtDCA(trackParam.GetNonBendingCoor());
562   esdTrack.SetThetaXAtDCA(TMath::ATan(trackParam.GetNonBendingSlope()));
563   esdTrack.SetBendingCoorAtDCA(trackParam.GetBendingCoor()); 
564   esdTrack.SetThetaYAtDCA(TMath::ATan(trackParam.GetBendingSlope()));
565   esdTrack.SetInverseBendingMomentumAtDCA(trackParam.GetInverseBendingMomentum());
566 }
567
568 //_________________________________________________________________________
569 void AliMUONESDInterface::SetParamAtFirstCluster(const AliMUONTrackParam& trackParam, AliESDMuonTrack& esdTrack)
570 {
571   /// Set parameters in ESD track
572   esdTrack.SetZUncorrected(trackParam.GetZ());
573   esdTrack.SetNonBendingCoorUncorrected(trackParam.GetNonBendingCoor());
574   esdTrack.SetThetaXUncorrected(TMath::ATan(trackParam.GetNonBendingSlope()));
575   esdTrack.SetBendingCoorUncorrected(trackParam.GetBendingCoor()); 
576   esdTrack.SetThetaYUncorrected(TMath::ATan(trackParam.GetBendingSlope()));
577   esdTrack.SetInverseBendingMomentumUncorrected(trackParam.GetInverseBendingMomentum());
578 }
579
580 //_________________________________________________________________________
581 void AliMUONESDInterface::SetParamCov(const AliMUONTrackParam& trackParam, AliESDMuonTrack& esdTrack)
582 {
583   /// Set parameters covariances in ESD track
584   
585   // set null matrix if covariances does not exist
586   if (!trackParam.CovariancesExist()) {
587     TMatrixD tmp(5,5);
588     tmp.Zero();
589     esdTrack.SetCovariances(tmp);
590     return;
591   }
592   
593   // compute Jacobian to change the coordinate system
594   // from (X,slopeX,Y,slopeY,c/pYZ) to (X,thetaX,Y,thetaY,c/pYZ)
595   Double_t cosThetaX = TMath::Cos(TMath::ATan(trackParam.GetNonBendingSlope()));
596   Double_t cosThetaY = TMath::Cos(TMath::ATan(trackParam.GetBendingSlope()));
597   TMatrixD jacob(5,5);
598   jacob.Zero();
599   jacob(0,0) = 1.;
600   jacob(1,1) = cosThetaX * cosThetaX;
601   jacob(2,2) = 1.;
602   jacob(3,3) = cosThetaY * cosThetaY;
603   jacob(4,4) = 1.;
604   
605   // compute covariance matrix in ESD coordinate system
606   TMatrixD tmp(trackParam.GetCovariances(),TMatrixD::kMultTranspose,jacob);
607   esdTrack.SetCovariances(TMatrixD(jacob,TMatrixD::kMult,tmp));
608   
609 }
610
611 //_____________________________________________________________________________
612 void AliMUONESDInterface::ESDToMUON(const AliMUONRecoParam* recoParam, const AliESDMuonTrack& esdTrack, AliMUONTrack& track)
613 {
614   /// Transfert data from ESDMuon track to MUON track
615   
616   // if the ESDMuon track is a ghost then return an empty MUON track
617   if (!esdTrack.ContainTrackerData()) {
618     track.Reset();
619     track.SetUniqueID(esdTrack.GetUniqueID());
620     return;
621   }
622   
623   track.Clear("C");
624   
625   // global info
626   track.SetUniqueID(esdTrack.GetUniqueID());
627   track.FitWithVertex(kFALSE);
628   track.FitWithMCS(kFALSE);
629   track.SetImproved(kFALSE);
630   track.SetVertexErrXY2(0.,0.);
631   track.SetGlobalChi2(esdTrack.GetChi2());
632   track.SetMatchTrigger(esdTrack.GetMatchTrigger());
633   track.SetLoTrgNum(-1);
634   track.SetChi2MatchTrigger(esdTrack.GetChi2MatchTrigger());
635   track.SetTrackID(0);
636   track.SetHitsPatternInTrigCh(esdTrack.GetHitsPatternInTrigCh());
637   track.SetLocalTrigger(esdTrack.LoCircuit(), esdTrack.LoStripX(), esdTrack.LoStripY(),
638                         esdTrack.LoDev(), esdTrack.LoLpt(), esdTrack.LoHpt());
639   
640   // track parameters at vertex
641   AliMUONTrackParam paramAtVertex;
642   GetParamAtVertex(esdTrack, paramAtVertex);
643   track.SetTrackParamAtVertex(&paramAtVertex);
644     
645   // track parameters at first cluster
646   AliMUONTrackParam param;
647   GetParamAtFirstCluster(esdTrack, param);
648   GetParamCov(esdTrack, param);
649   
650   // create empty cluster
651   AliMUONVClusterStore* cStore = NewClusterStore();
652   if (!cStore) return;
653   AliMUONVCluster* cluster = cStore->CreateCluster(0,0,0);
654   
655   // fill TrackParamAtCluster with track parameters at each cluster if available
656   // or with only track parameters at first (fake) cluster if not
657   if(esdTrack.ClustersStored()) {
658     
659     // loop over ESD clusters
660     AliESDMuonCluster *esdCluster = (AliESDMuonCluster*) esdTrack.GetClusters().First();
661     while (esdCluster) {
662       
663       // copy cluster information
664       ESDToMUON(*esdCluster, *cluster);
665       
666       // only set the Z parameter to avoid error in the AddTrackParamAtCluster(...) method
667       param.SetZ(cluster->GetZ());
668       
669       // add common track parameters at current cluster
670       track.AddTrackParamAtCluster(param, *cluster, kTRUE);
671       
672       esdCluster = (AliESDMuonCluster*) esdTrack.GetClusters().After(esdCluster);
673     }
674     
675     // recompute parameters at first cluster in case of those stored
676     // in ESD are not related to the most upstream cluster
677     AliMUONTrackParam *firstTrackParam = (AliMUONTrackParam*) track.GetTrackParamAtCluster()->First();
678     firstTrackParam->SetZ(esdTrack.GetZUncorrected()); // reset the z to the one stored in ESD
679     AliMUONTrackExtrap::ExtrapToZCov(firstTrackParam,firstTrackParam->GetClusterPtr()->GetZ());
680     
681     // refit the track to get better parameters and covariances at each cluster (temporary disable track improvement)
682     if (!fgTracker) fgTracker = AliMUONTracker::CreateTrackReconstructor(recoParam,0x0);
683     if (!fgTracker->RefitTrack(track, kFALSE)) track.UpdateCovTrackParamAtCluster();
684     
685   } else {
686     
687     // get number of the first hit chamber (according to the MUONClusterMap if not empty)
688     Int_t firstCh = 0;
689     if (esdTrack.GetMuonClusterMap() != 0) while (!esdTrack.IsInMuonClusterMap(firstCh)) firstCh++;
690     else firstCh = AliMUONConstants::ChamberNumber(param.GetZ());
691     
692     // produce fake cluster at this chamber
693     cluster->SetUniqueID(AliMUONVCluster::BuildUniqueID(firstCh, 0, 0));
694     cluster->SetXYZ(param.GetNonBendingCoor(), param.GetBendingCoor(), param.GetZ());
695     cluster->SetErrXY(0., 0.);
696     
697     // add track parameters at first (fake) cluster
698     track.AddTrackParamAtCluster(param, *cluster, kTRUE);
699     
700   }
701   
702   delete cluster;
703   delete cStore;
704   
705 }
706
707 //_____________________________________________________________________________
708 void AliMUONESDInterface::ESDToMUON(const AliESDMuonTrack& esdTrack, AliMUONLocalTrigger& locTrg)
709 {
710   /// Transfert trigger data from ESDMuon track to the MUONLocalTtrigger object
711   
712   // if the ESDMuon track is a ghost then return an empty MUON track
713   if (!esdTrack.ContainTriggerData()) {
714     AliMUONLocalTrigger emptyLocTrg;
715     locTrg = emptyLocTrg;
716     return;
717   }
718   
719   locTrg.SetLoCircuit(esdTrack.LoCircuit());
720   locTrg.SetLoStripX(esdTrack.LoStripX());
721   locTrg.SetLoStripY(esdTrack.LoStripY());
722   locTrg.SetLoDev(esdTrack.LoDev());
723   locTrg.SetLoLpt(esdTrack.LoLpt());
724   locTrg.SetLoHpt(esdTrack.LoHpt());
725   locTrg.SetLoSdev(1);
726   locTrg.SetLoTrigY(1);
727   locTrg.SetX1Pattern(esdTrack.GetTriggerX1Pattern());
728   locTrg.SetX2Pattern(esdTrack.GetTriggerX2Pattern());
729   locTrg.SetX3Pattern(esdTrack.GetTriggerX3Pattern());
730   locTrg.SetX4Pattern(esdTrack.GetTriggerX4Pattern());
731   locTrg.SetY1Pattern(esdTrack.GetTriggerY1Pattern());
732   locTrg.SetY2Pattern(esdTrack.GetTriggerY2Pattern());
733   locTrg.SetY3Pattern(esdTrack.GetTriggerY3Pattern());
734   locTrg.SetY4Pattern(esdTrack.GetTriggerY4Pattern());
735   
736 }
737
738 //_____________________________________________________________________________
739 void AliMUONESDInterface::ESDToMUON(const AliESDMuonCluster& esdCluster, AliMUONVCluster& cluster)
740 {
741   /// Transfert data from ESDMuon cluster to MUON cluster
742   
743   cluster.Clear("C");
744   
745   cluster.SetUniqueID(esdCluster.GetUniqueID());
746   cluster.SetXYZ(esdCluster.GetX(), esdCluster.GetY(), esdCluster.GetZ());
747   cluster.SetErrXY(esdCluster.GetErrX(),esdCluster.GetErrY());
748   cluster.SetCharge(esdCluster.GetCharge());
749   cluster.SetChi2(esdCluster.GetChi2());
750   
751   if (esdCluster.PadsStored()) {
752     Int_t nPads = esdCluster.GetNPads();
753     for (Int_t iPad = 0; iPad < nPads; iPad++)
754       cluster.AddDigitId(((AliESDMuonPad*)esdCluster.GetPads().UncheckedAt(iPad))->GetUniqueID());
755   }
756   
757 }
758
759 //___________________________________________________________________________
760 void AliMUONESDInterface::ESDToMUON(const AliESDMuonPad& esdPad, AliMUONVDigit& digit)
761 {
762   /// Transfert data from ESDMuon pad to MUON digit
763   
764   const AliMpVSegmentation* seg = AliMpSegmentation::Instance()->GetMpSegmentationByElectronics(esdPad.GetDetElemId(), esdPad.GetManuId());  
765   AliMpPad pad = seg->PadByLocation(AliMpIntPair(esdPad.GetManuId(), esdPad.GetManuChannel()), kFALSE);
766   
767   digit.Saturated(esdPad.IsSaturated());
768   digit.Used(kFALSE);
769   digit.Calibrated(esdPad.IsCalibrated());
770   digit.SetUniqueID(esdPad.GetUniqueID());
771   digit.SetCharge(esdPad.GetCharge());
772   digit.SetADC(esdPad.GetADC());
773   digit.SetPadXY(pad.GetIndices().GetFirst(), pad.GetIndices().GetSecond());
774   
775 }
776
777 //_____________________________________________________________________________
778 void AliMUONESDInterface::MUONToESD(const AliMUONTrack& track, AliESDMuonTrack& esdTrack, const Double_t vertex[3],
779                                     const AliMUONVDigitStore* digits, const AliMUONLocalTrigger* locTrg)
780 {
781   /// Transfert data from MUON track to ESDMuon track
782   /// Incorporate the ESDPads if the digits are provided
783   /// Add trigger info if the MUON track is matched with a trigger track
784   
785   // empty MUON track -> produce a ghost ESDMuon track if trigger info are available otherwise produce an empty track
786   if (track.GetNClusters() == 0) {
787     if (locTrg) MUONToESD(*locTrg, esdTrack, track.GetUniqueID());
788     else {
789       cout<<"W-AliMUONESDInterface::MUONToESD: will produce an empty ESDMuon track"<<endl;
790       esdTrack.Reset();
791       esdTrack.SetUniqueID(0xFFFFFFFF);
792     }
793     return;
794   }
795   
796   esdTrack.Clear("C");
797   
798   // set global info
799   esdTrack.SetUniqueID(track.GetUniqueID());
800   esdTrack.SetChi2(track.GetGlobalChi2());
801   esdTrack.SetNHit(track.GetNClusters());
802   
803   // set param at first cluster
804   AliMUONTrackParam* trackParam = static_cast<AliMUONTrackParam*>((track.GetTrackParamAtCluster())->First());
805   SetParamAtFirstCluster(*trackParam, esdTrack);
806   SetParamCov(*trackParam, esdTrack);
807   
808   // set param at vertex
809   AliMUONTrackParam trackParamAtVtx(*trackParam);
810   AliMUONTrackExtrap::ExtrapToVertex(&trackParamAtVtx, vertex[0], vertex[1], vertex[2], 0., 0.);
811   SetParamAtVertex(trackParamAtVtx, esdTrack);
812   
813   // set param at Distance of Closest Approach
814   AliMUONTrackParam trackParamAtDCA(*trackParam);
815   AliMUONTrackExtrap::ExtrapToVertexWithoutBranson(&trackParamAtDCA, vertex[2]);
816   SetParamAtDCA(trackParamAtDCA, esdTrack);
817   
818   // set muon cluster info
819   AliESDMuonCluster esdCluster;
820   esdTrack.SetMuonClusterMap(0);
821   while (trackParam) {
822     MUONToESD(*(trackParam->GetClusterPtr()), esdCluster, digits);
823     esdTrack.AddCluster(esdCluster);
824     esdTrack.AddInMuonClusterMap(esdCluster.GetChamberId());
825     trackParam = static_cast<AliMUONTrackParam*>(track.GetTrackParamAtCluster()->After(trackParam));
826   }
827   
828   // set trigger info
829   esdTrack.SetLocalTrigger(track.GetLocalTrigger());
830   esdTrack.SetChi2MatchTrigger(track.GetChi2MatchTrigger());
831   esdTrack.SetHitsPatternInTrigCh(track.GetHitsPatternInTrigCh());
832   if (locTrg) {
833     esdTrack.SetTriggerX1Pattern(locTrg->GetX1Pattern());
834     esdTrack.SetTriggerY1Pattern(locTrg->GetY1Pattern());
835     esdTrack.SetTriggerX2Pattern(locTrg->GetX2Pattern());
836     esdTrack.SetTriggerY2Pattern(locTrg->GetY2Pattern());
837     esdTrack.SetTriggerX3Pattern(locTrg->GetX3Pattern());
838     esdTrack.SetTriggerY3Pattern(locTrg->GetY3Pattern());
839     esdTrack.SetTriggerX4Pattern(locTrg->GetX4Pattern());
840     esdTrack.SetTriggerY4Pattern(locTrg->GetY4Pattern());
841   } else {
842     esdTrack.SetTriggerX1Pattern(0);
843     esdTrack.SetTriggerY1Pattern(0);
844     esdTrack.SetTriggerX2Pattern(0);
845     esdTrack.SetTriggerY2Pattern(0);
846     esdTrack.SetTriggerX3Pattern(0);
847     esdTrack.SetTriggerY3Pattern(0);
848     esdTrack.SetTriggerX4Pattern(0);
849     esdTrack.SetTriggerY4Pattern(0);
850   }
851   
852 }
853
854 //_____________________________________________________________________________
855 void AliMUONESDInterface::MUONToESD(const AliMUONLocalTrigger& locTrg, AliESDMuonTrack& esdTrack, UInt_t trackId)
856 {
857   /// Build ghost ESDMuon track containing only informations about trigger track
858   
859   esdTrack.Reset();
860   esdTrack.SetUniqueID(trackId);
861   
862   // set trigger info
863   AliMUONTrack muonTrack;
864   muonTrack.SetLocalTrigger(locTrg.LoCircuit(),
865                             locTrg.LoStripX(),
866                             locTrg.LoStripY(),
867                             locTrg.LoDev(),
868                             locTrg.LoLpt(),
869                             locTrg.LoHpt());
870   esdTrack.SetLocalTrigger(muonTrack.GetLocalTrigger());
871   esdTrack.SetChi2MatchTrigger(0.);
872   esdTrack.SetHitsPatternInTrigCh(0);
873   esdTrack.SetTriggerX1Pattern(locTrg.GetX1Pattern());
874   esdTrack.SetTriggerY1Pattern(locTrg.GetY1Pattern());
875   esdTrack.SetTriggerX2Pattern(locTrg.GetX2Pattern());
876   esdTrack.SetTriggerY2Pattern(locTrg.GetY2Pattern());
877   esdTrack.SetTriggerX3Pattern(locTrg.GetX3Pattern());
878   esdTrack.SetTriggerY3Pattern(locTrg.GetY3Pattern());
879   esdTrack.SetTriggerX4Pattern(locTrg.GetX4Pattern());
880   esdTrack.SetTriggerY4Pattern(locTrg.GetY4Pattern());
881   
882 }
883
884 //_____________________________________________________________________________
885 void AliMUONESDInterface::MUONToESD(const AliMUONVCluster& cluster, AliESDMuonCluster& esdCluster, const AliMUONVDigitStore* digits)
886 {
887   /// Transfert data from MUON cluster to ESDMuon cluster
888   /// Incorporate the ESDPads if the digits are provided
889   
890   esdCluster.Clear("C");
891   
892   esdCluster.SetUniqueID(cluster.GetUniqueID());
893   esdCluster.SetXYZ(cluster.GetX(), cluster.GetY(), cluster.GetZ());
894   esdCluster.SetErrXY(cluster.GetErrX(), cluster.GetErrY());
895   esdCluster.SetCharge(cluster.GetCharge());
896   esdCluster.SetChi2(cluster.GetChi2());
897   
898   if (digits) { // transfert all data if required
899     
900     AliESDMuonPad esdPad;
901     for (Int_t i=0; i<cluster.GetNDigits(); i++) {
902       AliMUONVDigit* digit = digits->FindObject(cluster.GetDigitId(i));
903       if (!digit) {
904         cout<<"E-AliMUONESDInterface::MUONToESD: digit "<<cluster.GetDigitId(i)<<" not found"<<endl;
905         continue;
906       }
907       MUONToESD(*digit, esdPad);
908       esdCluster.AddPad(esdPad);
909     }
910     
911   }
912   
913 }
914
915 //_____________________________________________________________________________
916 void AliMUONESDInterface::MUONToESD(const AliMUONVDigit& digit, AliESDMuonPad& esdPad)
917 {
918   /// Transfert data from MUON digit to ESDMuon pad
919   esdPad.SetUniqueID(digit.GetUniqueID());
920   esdPad.SetADC(digit.ADC());
921   esdPad.SetCharge(digit.Charge());
922   esdPad.SetCalibrated(digit.IsCalibrated());
923   esdPad.SetSaturated(digit.IsSaturated());
924 }
925
926 //___________________________________________________________________________
927 AliMUONTrack* 
928 AliMUONESDInterface::Add(const AliMUONRecoParam* recoParam, const AliESDMuonTrack& esdTrack, AliMUONVTrackStore& trackStore)
929 {
930   /// Create MUON track from ESDMuon track and add it to the store
931   /// return a pointer to the track into the store (0x0 if the track already exist)
932   if(trackStore.FindObject(esdTrack.GetUniqueID())) return 0x0;
933   AliMUONTrack* track = trackStore.Add(AliMUONTrack());
934   ESDToMUON(recoParam,esdTrack, *track);
935   return track;
936 }
937
938 //___________________________________________________________________________
939 void AliMUONESDInterface::Add(const AliESDMuonTrack& esdTrack, AliMUONVTriggerStore& triggerStore)
940 {
941   /// Create MUON local trigger from ESDMuon track and add it to the store if not already there
942   if (triggerStore.FindLocal(esdTrack.LoCircuit())) return;
943   AliMUONLocalTrigger locTrg;
944   ESDToMUON(esdTrack, locTrg);
945   triggerStore.Add(locTrg);
946 }
947
948 //___________________________________________________________________________
949 AliMUONVCluster* AliMUONESDInterface::Add(const AliESDMuonCluster& esdCluster, AliMUONVClusterStore& clusterStore)
950 {
951   /// Create MUON cluster from ESDMuon cluster and add it to the store
952   /// return a pointer to the cluster into the store (0x0 if the cluster already exist)
953   AliMUONVCluster* cluster = clusterStore.Add(esdCluster.GetChamberId(), esdCluster.GetDetElemId(), esdCluster.GetClusterIndex());
954   if (cluster) ESDToMUON(esdCluster, *cluster);
955   return cluster;
956 }
957
958 //___________________________________________________________________________
959 AliMUONVDigit* AliMUONESDInterface::Add(const AliESDMuonPad& esdPad, AliMUONVDigitStore& digitStore)
960 {
961   /// Create MUON digit from ESDMuon digit and add it to the store
962   /// return a pointer to the digit into the store (0x0 if the digit already exist)
963   AliMUONVDigit* digit = digitStore.Add(esdPad.GetDetElemId(), esdPad.GetManuId(), esdPad.GetManuChannel(), esdPad.GetCathode(), AliMUONVDigitStore::kDeny);
964   if (digit) ESDToMUON(esdPad, *digit);
965   return digit;
966 }
967