Load necessary data from OCDB if not already set
[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 "AliMUONTriggerTrack.h"
27 #include "AliMUONVTriggerStore.h"
28 #include "AliMUONVTriggerTrackStore.h"
29 #include "AliMUON2DMapIterator.h"
30 #include "AliMUONTrackParam.h"
31 #include "AliMUONTrackExtrap.h"
32 #include "AliMUONConstants.h"
33 #include "AliMUONTracker.h"
34 #include "AliMUONRecoParam.h"
35 #include "AliMUONVTrackReconstructor.h"
36 #include "AliMUONCDB.h"
37
38 #include "AliMpExMapIterator.h"
39 #include "AliMpVSegmentation.h"
40 #include "AliMpSegmentation.h"
41 #include "AliMpPad.h"
42
43 #include "AliESDEvent.h"
44 #include "AliESDMuonTrack.h"
45 #include "AliESDMuonCluster.h"
46 #include "AliESDMuonPad.h"
47 #include "AliLog.h"
48
49 #include <TROOT.h>
50 #include <TClass.h>
51 #include <TIterator.h>
52 #include <TMath.h>
53 #include <TMatrixD.h>
54 #include <Riostream.h>
55 #include <TGeoGlobalMagField.h>
56 #include <TVirtualMagField.h>
57
58 //-----------------------------------------------------------------------------
59 /// \class AliMUONESDInterface
60 ///
61 /// There are 2 way of using thid converter between MUON track/cluster/digit
62 /// and ESDMuon track/cluster/pad:
63 /// 
64 /// 1) using the static methods converting the objects one by one
65 ///
66 /// 2) loading a whole ESDEvent and using the finders and/or the iterators
67 ///    to access the corresponding MUON objects
68 ///
69 /// note: You can set the recoParam used to refit the MUON track with ResetTracker(...);
70 ///       By default we use Kalman filter + Smoother
71 ///
72 /// \author Philippe Pillot
73 //-----------------------------------------------------------------------------
74
75 /// \cond CLASSIMP
76 ClassImp(AliMUONESDInterface)
77 /// \endcond
78
79 AliMUONRecoParam* AliMUONESDInterface::fgRecoParam = 0x0;
80 AliMUONVTrackReconstructor* AliMUONESDInterface::fgTracker = 0x0;
81
82 TString AliMUONESDInterface::fgTrackStoreName = "AliMUONTrackStoreV1";
83 TString AliMUONESDInterface::fgClusterStoreName = "AliMUONClusterStoreV2";
84 TString AliMUONESDInterface::fgDigitStoreName = "AliMUONDigitStoreV2R";
85 TString AliMUONESDInterface::fgTriggerStoreName = "AliMUONTriggerStoreV1";
86 TString AliMUONESDInterface::fgTriggerTrackStoreName = "AliMUONTriggerTrackStoreV1";
87
88 //_____________________________________________________________________________
89 AliMUONESDInterface::AliMUONESDInterface()
90 : TObject(),
91 fTracks(0x0),
92 fDigits(0x0),
93 fTriggers(0x0),
94 fClusterMap(0x0),
95 fDigitMap(0x0)
96 {
97   /// Default constructor
98 }
99
100 //_____________________________________________________________________________
101 AliMUONESDInterface::~AliMUONESDInterface()
102 {
103   /// Destructor
104   delete fTracks;
105   delete fDigits;
106   delete fTriggers;
107   delete fClusterMap;
108   delete fDigitMap;
109 }
110
111 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
112 //                    methods to play with internal objects                    //
113 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
114
115 //_____________________________________________________________________________
116 void AliMUONESDInterface::Clear(Option_t*)
117 {
118   /// clear memory
119   delete fTracks; fTracks = 0x0;
120   delete fDigits; fDigits = 0x0;
121   delete fTriggers; fTriggers = 0x0;
122   delete fClusterMap; fClusterMap = 0x0;
123   delete fDigitMap; fDigitMap = 0x0;
124 }
125
126 //_____________________________________________________________________________
127 void AliMUONESDInterface::Reset()
128 {
129   /// reset stores and maps
130   
131   if (fTracks) fTracks->Clear("C");
132   else fTracks = NewTrackStore();
133   
134   if (fDigits) fDigits->Clear("C");
135   else fDigits = NewDigitStore();
136   
137   if (fTriggers) fTriggers->Clear("C");
138   else fTriggers = NewTriggerStore();
139   
140   if (fClusterMap) fClusterMap->Clear();
141   else fClusterMap = new AliMpExMap;
142   fClusterMap->SetOwner(kTRUE);
143   
144   if (fDigitMap) fDigitMap->Clear();
145   else fDigitMap = new AliMpExMap;
146   fDigitMap->SetOwner(kTRUE);
147 }
148
149 //_____________________________________________________________________________
150 void AliMUONESDInterface::LoadEvent(AliESDEvent& esdEvent, Bool_t refit)
151 {
152   /// Extract MUON data from the given ESD event
153   
154   // reset data members
155   Reset();
156   
157   // loop over ESD pads and fill the digit store
158   for (Int_t iPad = 0; iPad < esdEvent.GetNumberOfMuonPads(); iPad++)
159     Add(*(esdEvent.GetMuonPad(iPad)), *fDigits);
160   
161   // loop over ESD tracks and fill the stores
162   for (Int_t iTrack = 0; iTrack < esdEvent.GetNumberOfMuonTracks(); iTrack++) {
163     
164     // get ESD track
165     AliESDMuonTrack* esdTrack = esdEvent.GetMuonTrack(iTrack);
166     
167     // fill trigger store if related info are availables
168     if (esdTrack->ContainTriggerData()) Add(*esdTrack, *fTriggers);
169     
170     // fill tracker data if availables
171     if (!esdTrack->ContainTrackerData()) continue;
172     
173     // add it to track store
174     AliMUONTrack* track = Add(*esdTrack, *fTracks, refit);
175     
176     // prepare cluster map
177     AliMpExMap* cMap = new AliMpExMap;
178     cMap->SetOwner(kFALSE);
179     fClusterMap->Add(esdTrack->GetUniqueID(), cMap);
180     
181     // prepare digit maps
182     AliMpExMap* dMaps = new AliMpExMap;
183     dMaps->SetOwner(kTRUE);
184     fDigitMap->Add(esdTrack->GetUniqueID(), dMaps);
185     
186     // loop over clusters
187     for (Int_t iCluster = 0; iCluster < track->GetNClusters(); iCluster++) {
188       
189       // get cluster
190       AliMUONVCluster* cluster = ((AliMUONTrackParam*)track->GetTrackParamAtCluster()->UncheckedAt(iCluster))->GetClusterPtr();
191       
192       // fill cluster map
193       cMap->Add(cluster->GetUniqueID(), cluster);
194       
195       // prepare digit map
196       AliMpExMap* dMap =new AliMpExMap;
197       dMap->SetOwner(kFALSE);
198       dMaps->Add(cluster->GetUniqueID(), dMap);
199       
200       // loop over digits
201       for (Int_t iDigit = 0; iDigit < cluster->GetNDigits(); iDigit++) {
202         
203         // find the digit
204         AliMUONVDigit* digit = fDigits->FindObject(cluster->GetDigitId(iDigit));
205         
206         // fill digit map
207         if (digit) dMap->Add(digit->GetUniqueID(), digit);
208         else AliError("a digit is missing");
209         
210       } // end of loop over pads
211       
212     } // end of loop over clusters
213     
214   } // end of loop over tracks
215   
216 }
217
218 //___________________________________________________________________________
219 Int_t AliMUONESDInterface::GetNTracks() const
220 {
221   /// return the number of tracks
222   return fTracks ? fTracks->GetSize() : 0;
223 }
224
225 //___________________________________________________________________________
226 Int_t AliMUONESDInterface::GetNClusters() const
227 {
228   /// return the number of clusters
229   Int_t nClusters = 0;
230   AliMUONTrack *track;
231   TIter next(CreateTrackIterator());
232   while ((track = static_cast<AliMUONTrack*>(next()))) nClusters += track->GetNClusters();
233   return nClusters;
234 }
235
236 //___________________________________________________________________________
237 Int_t AliMUONESDInterface::GetNClusters(UInt_t trackId) const
238 {
239   /// return the number of clusters in track "trackId"
240   AliMUONTrack* track = FindTrack(trackId);
241   return track ? track->GetNClusters() : 0;
242 }
243
244 //___________________________________________________________________________
245 Int_t AliMUONESDInterface::GetNDigits() const
246 {
247   /// return the number of digits
248   return fDigits ? fDigits->GetSize() : 0;
249 }
250
251 //___________________________________________________________________________
252 Int_t AliMUONESDInterface::GetNDigits(UInt_t trackId) const
253 {
254   /// return the number of digits in all clusters of track "trackId"
255   Int_t nDigits = 0;
256   AliMUONVCluster *cluster;
257   TIter next(CreateClusterIterator(trackId));
258   while ((cluster = static_cast<AliMUONVCluster*>(next()))) nDigits += cluster->GetNDigits();
259   return nDigits;
260 }
261
262 //___________________________________________________________________________
263 Int_t AliMUONESDInterface::GetNDigits(UInt_t trackId, UInt_t clusterId) const
264 {
265   /// return the number of digits in cluster numbered "iCluster" of track "iTrack"
266   AliMUONVCluster* cluster = FindCluster(trackId, clusterId);
267   return cluster ? cluster->GetNDigits() : 0;
268 }
269
270 //___________________________________________________________________________
271 Int_t AliMUONESDInterface::GetNDigitsInCluster(UInt_t clusterId) const
272 {
273   /// return the number of digits in cluster "clusterId"
274   AliMUONVCluster* cluster = FindCluster(clusterId);
275   return cluster ? cluster->GetNDigits() : 0;
276 }
277
278 //___________________________________________________________________________
279 Int_t AliMUONESDInterface::GetNTriggers() const
280 {
281   /// return the number of triggers
282   return fTriggers ? fTriggers->GetSize() : 0;
283 }
284
285 //___________________________________________________________________________
286 Bool_t AliMUONESDInterface::DigitsStored(UInt_t trackId) const
287 {
288   /// return kTRUE if digits have been stored for all clusters of track "trackId"
289   AliMUONVCluster *cluster;
290   TIter next(CreateClusterIterator(trackId));
291   while ((cluster = static_cast<AliMUONVCluster*>(next())))
292     if (cluster->GetNDigits() == 0) return kFALSE;
293   return kTRUE;
294 }
295
296 //___________________________________________________________________________
297 AliMUONTrack* AliMUONESDInterface::FindTrack(UInt_t trackId) const
298 {
299   /// return track "trackId" (0x0 if not found)
300   AliMUONTrack *track = fTracks ? static_cast<AliMUONTrack*>(fTracks->FindObject(trackId)) : 0x0;
301   if (!track) AliWarning(Form("track %d does not exist",trackId));
302   return track;
303 }
304
305 //___________________________________________________________________________
306 AliMUONVCluster* AliMUONESDInterface::FindCluster(UInt_t clusterId) const
307 {
308   /// loop over tracks and return the first cluster "clusterId" found (0x0 if not found)
309   AliMpExMap *cMap;
310   AliMUONVCluster* cluster = 0x0;
311   
312   if (fClusterMap) {
313     
314     TIter next(fClusterMap->CreateIterator());
315     while ((cMap = static_cast<AliMpExMap*>(next()))) {
316       
317       cluster = static_cast<AliMUONVCluster*>(cMap->GetValue(clusterId));
318       if (cluster) return cluster;
319       
320     }
321     
322   }
323   
324   if (!cluster) AliWarning(Form("cluster %d does not exist",clusterId));
325   return 0x0;
326 }
327
328 //___________________________________________________________________________
329 AliMUONVCluster* AliMUONESDInterface::FindCluster(UInt_t trackId, UInt_t clusterId) const
330 {
331   /// return cluster "clusterId" in track "trackId" (0x0 if not found)
332   AliMpExMap *cMap = fClusterMap ? static_cast<AliMpExMap*>(fClusterMap->GetValue(trackId)) : 0x0;
333   AliMUONVCluster* cluster = cMap ? static_cast<AliMUONVCluster*>(cMap->GetValue(clusterId)) : 0x0;
334   if (!cluster) AliWarning(Form("cluster %d does not exist in track %d", clusterId, trackId));
335   return cluster;
336 }
337
338 //___________________________________________________________________________
339 AliMUONVDigit* AliMUONESDInterface::FindDigit(UInt_t digitId) const
340 {
341   /// return digit "digitId" (0x0 if not found)
342   AliMUONVDigit *digit = fDigits ? fDigits->FindObject(digitId) : 0x0;
343   if (!digit) AliWarning(Form("digit %d does not exist",digitId));
344   return digit;
345 }
346
347 //___________________________________________________________________________
348 AliMUONLocalTrigger* AliMUONESDInterface::FindLocalTrigger(Int_t boardNumber) const
349 {
350   /// return MUON local trigger "boardNumber"
351   return (fTriggers) ? fTriggers->FindLocal(boardNumber) : 0x0;
352 }
353
354 //___________________________________________________________________________
355 TIterator* AliMUONESDInterface::CreateTrackIterator() const
356 {
357   /// return iterator over all tracks
358   return fTracks ? fTracks->CreateIterator() : 0x0;
359 }
360
361 //___________________________________________________________________________
362 TIterator* AliMUONESDInterface::CreateClusterIterator() const
363 {
364   /// return iterator over all clusters
365   return fClusterMap ? new AliMUON2DMapIterator(*fClusterMap) : 0x0;
366 }
367
368 //___________________________________________________________________________
369 TIterator* AliMUONESDInterface::CreateClusterIterator(UInt_t trackId) const
370 {
371   /// return iterator over clusters of track "trackId"
372   AliMpExMap *cMap = fClusterMap ? static_cast<AliMpExMap*>(fClusterMap->GetValue(trackId)) : 0x0;
373   return cMap ? cMap->CreateIterator() : 0x0;
374 }
375
376 //___________________________________________________________________________
377 TIterator* AliMUONESDInterface::CreateDigitIterator() const
378 {
379   /// return iterator over all digits
380   return fDigits ? fDigits->CreateIterator() : 0x0;
381 }
382
383 //___________________________________________________________________________
384 TIterator* AliMUONESDInterface::CreateDigitIterator(UInt_t trackId) const
385 {
386   /// return iterator over all digits of track "trackId"
387   AliMpExMap* dMaps = fDigitMap ? static_cast<AliMpExMap*>(fDigitMap->GetValue(trackId)) : 0x0;
388   return dMaps ? new AliMUON2DMapIterator(*dMaps) : 0x0;
389 }
390
391 //___________________________________________________________________________
392 TIterator* AliMUONESDInterface::CreateDigitIterator(UInt_t trackId, UInt_t clusterId) const
393 {
394   /// return iterator over digits of cluster "clusterId" in track "trackId"
395   AliMpExMap* dMaps = fDigitMap ? static_cast<AliMpExMap*>(fDigitMap->GetValue(trackId)) : 0x0;
396   AliMpExMap* dMap = dMaps ? static_cast<AliMpExMap*>(dMaps->GetValue(clusterId)) : 0x0;
397   return dMap ? dMap->CreateIterator() : 0x0;
398 }
399
400 //___________________________________________________________________________
401 TIterator* AliMUONESDInterface::CreateDigitIteratorInCluster(UInt_t clusterId) const
402 {
403   /// return iterator over digits of the first cluster "clusterId" found by looping over all tracks
404   AliMpExMap *dMaps;
405   AliMpExMap* dMap = 0x0;
406   
407   if (fDigitMap) {
408     
409     TIter next(fDigitMap->CreateIterator());
410     while ((dMaps = static_cast<AliMpExMap*>(next()))) {
411       
412       dMap = static_cast<AliMpExMap*>(dMaps->GetValue(clusterId));
413       if (dMap) return dMap->CreateIterator();
414       
415     }
416     
417   }
418   
419   return 0x0;
420 }
421
422 //___________________________________________________________________________
423 TIterator* AliMUONESDInterface::CreateLocalTriggerIterator() const
424 {
425   /// return iterator over all local trigger
426   return fTriggers ? fTriggers->CreateLocalIterator() : 0x0;
427 }
428
429 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
430 //                                static methods                               //
431 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
432
433 //_____________________________________________________________________________
434 void AliMUONESDInterface::ResetTracker(const AliMUONRecoParam* recoParam, Bool_t info)
435 {
436   /// Reset the MUON tracker using "recoParam" if provided.
437   /// If not provided, will get them from OCDB.
438   /// Load the magnetic field from OCDB if not already set.
439   
440   delete fgTracker;
441   delete fgRecoParam;
442   
443   if (recoParam) {
444     
445     // use provided recoParam
446     fgRecoParam = new AliMUONRecoParam(*recoParam);
447     
448     if (info) AliInfoClass("will refit tracks with provided RecoParam:");
449     
450   } else {
451     
452     // or get them from OCDB
453     fgRecoParam = AliMUONCDB::LoadRecoParam();
454     
455     if (!fgRecoParam) AliFatalClass("RecoParam have not been set!");
456     
457   }
458   
459   // print useful parameters for refitting
460   if (info) {
461     cout<<"                                     --> Tracking mode = "<<fgRecoParam->GetTrackingMode()<<endl;
462     if (fgRecoParam->UseSmoother()) cout<<"                                     --> Use Smoother"<<endl;
463     else cout<<"                                     --> Do not use smoother"<<endl;
464     cout<<"                                     --> Vertex dispersion in bending direction = "
465     <<fgRecoParam->GetBendingVertexDispersion()<<" cm"<<endl;
466   }
467   
468   // load magnetic field for track extrapolation if not already set
469   if (!TGeoGlobalMagField::Instance()->GetField() && !AliMUONCDB::LoadField())
470     AliFatalClass("Magnetic field has not been set!");
471   
472   fgTracker = AliMUONTracker::CreateTrackReconstructor(fgRecoParam,0x0);
473   
474 }
475
476 //_____________________________________________________________________________
477 AliMUONVTrackStore* AliMUONESDInterface::NewTrackStore()
478 {
479   /// Create an empty track store of type fgTrackStoreName
480   TClass* classPtr = TClass::GetClass(fgTrackStoreName);
481   if (!classPtr || !classPtr->InheritsFrom("AliMUONVTrackStore")) {
482     AliErrorClass(Form("Unable to create store of type %s", fgTrackStoreName.Data()));
483     return 0x0;
484   }
485   return reinterpret_cast<AliMUONVTrackStore*>(gROOT->ProcessLineFast(Form("new %s()",fgTrackStoreName.Data())));
486 }
487
488 //_____________________________________________________________________________
489 AliMUONVClusterStore* AliMUONESDInterface::NewClusterStore()
490 {
491   /// Create an empty cluster store of type fgClusterStoreName
492   TClass* classPtr = TClass::GetClass(fgClusterStoreName);
493   if (!classPtr || !classPtr->InheritsFrom("AliMUONVClusterStore")) {
494     AliErrorClass(Form("Unable to create store of type %s", fgClusterStoreName.Data()));
495     return 0x0;
496   }
497   return reinterpret_cast<AliMUONVClusterStore*>(gROOT->ProcessLineFast(Form("new %s()",fgClusterStoreName.Data())));
498 }
499
500 //_____________________________________________________________________________
501 AliMUONVCluster* AliMUONESDInterface::NewCluster()
502 {
503   /// Create an empty cluster of type associated to the cluster store of type fgClusterStoreName
504   TClass* classPtr = TClass::GetClass(fgClusterStoreName);
505   if (!classPtr || !classPtr->InheritsFrom("AliMUONVClusterStore")) {
506     AliErrorClass(Form("Unable to create store of type %s", fgClusterStoreName.Data()));
507     return 0x0;
508   }
509   AliMUONVClusterStore* cStore = reinterpret_cast<AliMUONVClusterStore*>(classPtr->New());
510   AliMUONVCluster* cluster = cStore->CreateCluster(0,0,0);
511   delete cStore;
512   return cluster;
513 }
514
515 //_____________________________________________________________________________
516 AliMUONVDigitStore* AliMUONESDInterface::NewDigitStore()
517 {
518   /// Create an empty digit store of type fgDigitStoreName
519   TClass* classPtr = TClass::GetClass(fgDigitStoreName);
520   if (!classPtr || !classPtr->InheritsFrom("AliMUONVDigitStore")) {
521     AliErrorClass(Form("Unable to create store of type %s", fgDigitStoreName.Data()));
522     return 0x0;
523   }
524   return reinterpret_cast<AliMUONVDigitStore*>(gROOT->ProcessLineFast(Form("new %s()",fgDigitStoreName.Data())));
525 }
526
527 //_____________________________________________________________________________
528 AliMUONVDigit* AliMUONESDInterface::NewDigit()
529 {
530   /// Create an empty digit of type associated to the digit store of type fgDigitStoreName
531   TClass* classPtr = TClass::GetClass(fgDigitStoreName);
532   if (!classPtr || !classPtr->InheritsFrom("AliMUONVDigitStore")) {
533     AliErrorClass(Form("Unable to create store of type %s", fgDigitStoreName.Data()));
534     return 0x0;
535   }
536   AliMUONVDigitStore* dStore = reinterpret_cast<AliMUONVDigitStore*>(classPtr->New());
537   AliMUONVDigit* digit = dStore->CreateDigit(0,0,0,0);
538   delete dStore;
539   return digit;
540 }
541
542 //_____________________________________________________________________________
543 AliMUONVTriggerStore* AliMUONESDInterface::NewTriggerStore()
544 {
545   /// Create an empty trigger store of type fgTriggerStoreName
546   TClass* classPtr = TClass::GetClass(fgTriggerStoreName);
547   if (!classPtr || !classPtr->InheritsFrom("AliMUONVTriggerStore")) {
548     AliErrorClass(Form("Unable to create store of type %s", fgTriggerStoreName.Data()));
549     return 0x0;
550   }
551   return reinterpret_cast<AliMUONVTriggerStore*>(gROOT->ProcessLineFast(Form("new %s()",fgTriggerStoreName.Data())));
552 }
553
554 //_____________________________________________________________________________
555 AliMUONVTriggerTrackStore* AliMUONESDInterface::NewTriggerTrackStore()
556 {
557   /// Create an empty trigger track store of type fgTriggerTrackStoreName
558   TClass* classPtr = TClass::GetClass(fgTriggerTrackStoreName);
559   if (!classPtr || !classPtr->InheritsFrom("AliMUONVTriggerTrackStore")) {
560     AliErrorClass(Form("Unable to create store of type %s", fgTriggerTrackStoreName.Data()));
561     return 0x0;
562   }
563   return reinterpret_cast<AliMUONVTriggerTrackStore*>(gROOT->ProcessLineFast(Form("new %s()",fgTriggerTrackStoreName.Data())));
564 }
565
566 //_________________________________________________________________________
567 void AliMUONESDInterface::GetParamAtVertex(const AliESDMuonTrack& esdTrack, AliMUONTrackParam& trackParam)
568 {
569   /// Get parameters at vertex from ESDMuon track
570   trackParam.SetZ(esdTrack.GetZ());
571   trackParam.SetNonBendingCoor(esdTrack.GetNonBendingCoor());
572   trackParam.SetNonBendingSlope(TMath::Tan(esdTrack.GetThetaX()));
573   trackParam.SetBendingCoor(esdTrack.GetBendingCoor());
574   trackParam.SetBendingSlope(TMath::Tan(esdTrack.GetThetaY()));
575   trackParam.SetInverseBendingMomentum(esdTrack.GetInverseBendingMomentum());
576 }
577
578 //_________________________________________________________________________
579 void AliMUONESDInterface::GetParamAtDCA(const AliESDMuonTrack& esdTrack, AliMUONTrackParam& trackParam)
580 {
581   /// Get parameters at DCA from ESDMuon track
582   trackParam.SetZ(esdTrack.GetZ());
583   trackParam.SetNonBendingCoor(esdTrack.GetNonBendingCoorAtDCA());
584   trackParam.SetNonBendingSlope(TMath::Tan(esdTrack.GetThetaXAtDCA()));
585   trackParam.SetBendingCoor(esdTrack.GetBendingCoorAtDCA());
586   trackParam.SetBendingSlope(TMath::Tan(esdTrack.GetThetaYAtDCA()));
587   trackParam.SetInverseBendingMomentum(esdTrack.GetInverseBendingMomentumAtDCA());
588 }
589
590 //_________________________________________________________________________
591 void AliMUONESDInterface::GetParamAtFirstCluster(const AliESDMuonTrack& esdTrack, AliMUONTrackParam& trackParam)
592 {
593   /// Get parameters at first cluster from ESDMuon track
594   trackParam.SetZ(esdTrack.GetZUncorrected());
595   trackParam.SetNonBendingCoor(esdTrack.GetNonBendingCoorUncorrected());
596   trackParam.SetNonBendingSlope(TMath::Tan(esdTrack.GetThetaXUncorrected()));
597   trackParam.SetBendingCoor(esdTrack.GetBendingCoorUncorrected());
598   trackParam.SetBendingSlope(TMath::Tan(esdTrack.GetThetaYUncorrected()));
599   trackParam.SetInverseBendingMomentum(esdTrack.GetInverseBendingMomentumUncorrected());
600 }
601
602 //_________________________________________________________________________
603 void AliMUONESDInterface::GetParamCov(const AliESDMuonTrack& esdTrack, AliMUONTrackParam& trackParam)
604 {
605   /// Get parameters covariances from ESD track
606   
607   // get ESD covariance matrix
608   TMatrixD covariances(5,5);
609   esdTrack.GetCovariances(covariances);
610   
611   // compute Jacobian to change the coordinate system
612   // from (X,thetaX,Y,thetaY,c/pYZ) to (X,slopeX,Y,slopeY,c/pYZ)
613   Double_t cosThetaX = TMath::Cos(esdTrack.GetThetaXUncorrected());
614   Double_t cosThetaY = TMath::Cos(esdTrack.GetThetaYUncorrected());
615   TMatrixD jacob(5,5);
616   jacob.Zero();
617   jacob(0,0) = 1.;
618   jacob(1,1) = 1. / cosThetaX / cosThetaX;
619   jacob(2,2) = 1.;
620   jacob(3,3) = 1. / cosThetaY / cosThetaY;
621   jacob(4,4) = 1.;
622   
623   // compute covariance matrix in ESD coordinate system
624   TMatrixD tmp(covariances,TMatrixD::kMultTranspose,jacob);
625   trackParam.SetCovariances(TMatrixD(jacob,TMatrixD::kMult,tmp));
626   
627 }
628
629 //_________________________________________________________________________
630 void AliMUONESDInterface::SetParamAtVertex(const AliMUONTrackParam& trackParam, AliESDMuonTrack& esdTrack)
631 {
632   /// Set parameters in ESD track
633   esdTrack.SetZ(trackParam.GetZ());
634   esdTrack.SetNonBendingCoor(trackParam.GetNonBendingCoor());
635   esdTrack.SetThetaX(TMath::ATan(trackParam.GetNonBendingSlope()));
636   esdTrack.SetBendingCoor(trackParam.GetBendingCoor()); 
637   esdTrack.SetThetaY(TMath::ATan(trackParam.GetBendingSlope()));
638   esdTrack.SetInverseBendingMomentum(trackParam.GetInverseBendingMomentum());
639 }
640
641 //_________________________________________________________________________
642 void AliMUONESDInterface::SetParamAtDCA(const AliMUONTrackParam& trackParam, AliESDMuonTrack& esdTrack)
643 {
644   /// Set parameters in ESD track
645   esdTrack.SetNonBendingCoorAtDCA(trackParam.GetNonBendingCoor());
646   esdTrack.SetThetaXAtDCA(TMath::ATan(trackParam.GetNonBendingSlope()));
647   esdTrack.SetBendingCoorAtDCA(trackParam.GetBendingCoor()); 
648   esdTrack.SetThetaYAtDCA(TMath::ATan(trackParam.GetBendingSlope()));
649   esdTrack.SetInverseBendingMomentumAtDCA(trackParam.GetInverseBendingMomentum());
650 }
651
652 //_________________________________________________________________________
653 void AliMUONESDInterface::SetParamAtFirstCluster(const AliMUONTrackParam& trackParam, AliESDMuonTrack& esdTrack)
654 {
655   /// Set parameters in ESD track
656   esdTrack.SetZUncorrected(trackParam.GetZ());
657   esdTrack.SetNonBendingCoorUncorrected(trackParam.GetNonBendingCoor());
658   esdTrack.SetThetaXUncorrected(TMath::ATan(trackParam.GetNonBendingSlope()));
659   esdTrack.SetBendingCoorUncorrected(trackParam.GetBendingCoor()); 
660   esdTrack.SetThetaYUncorrected(TMath::ATan(trackParam.GetBendingSlope()));
661   esdTrack.SetInverseBendingMomentumUncorrected(trackParam.GetInverseBendingMomentum());
662 }
663
664 //_________________________________________________________________________
665 void AliMUONESDInterface::SetParamCov(const AliMUONTrackParam& trackParam, AliESDMuonTrack& esdTrack)
666 {
667   /// Set parameters covariances in ESD track
668   
669   // set null matrix if covariances does not exist
670   if (!trackParam.CovariancesExist()) {
671     TMatrixD tmp(5,5);
672     tmp.Zero();
673     esdTrack.SetCovariances(tmp);
674     return;
675   }
676   
677   // compute Jacobian to change the coordinate system
678   // from (X,slopeX,Y,slopeY,c/pYZ) to (X,thetaX,Y,thetaY,c/pYZ)
679   Double_t cosThetaX = TMath::Cos(TMath::ATan(trackParam.GetNonBendingSlope()));
680   Double_t cosThetaY = TMath::Cos(TMath::ATan(trackParam.GetBendingSlope()));
681   TMatrixD jacob(5,5);
682   jacob.Zero();
683   jacob(0,0) = 1.;
684   jacob(1,1) = cosThetaX * cosThetaX;
685   jacob(2,2) = 1.;
686   jacob(3,3) = cosThetaY * cosThetaY;
687   jacob(4,4) = 1.;
688   
689   // compute covariance matrix in ESD coordinate system
690   TMatrixD tmp(trackParam.GetCovariances(),TMatrixD::kMultTranspose,jacob);
691   esdTrack.SetCovariances(TMatrixD(jacob,TMatrixD::kMult,tmp));
692   
693 }
694
695 //_____________________________________________________________________________
696 void AliMUONESDInterface::ESDToMUON(const AliESDMuonTrack& esdTrack, AliMUONTrack& track, Bool_t refit)
697 {
698   /// Transfert data from ESDMuon track to MUON track.
699   /// ESDMuon track must hold the pointer to the ESD event otherwise we cannot recover the clusters.
700   /// If refit = kTRUE, the track parameters at each cluster are obtained by refitting the track
701   /// or by extrapolating the parameters at the first one if the refit failed.
702   /// If refit = kFALSE, only the track parameters at first cluster are valid.
703   /// note: You can set the recoParam used to refit the MUON track with ResetTracker(...);
704   ///       By default we use Kalman filter + Smoother
705   
706   // if the ESDMuon track is a ghost then return an empty MUON track
707   if (!esdTrack.ContainTrackerData()) {
708     track.Reset();
709     track.SetUniqueID(esdTrack.GetUniqueID());
710     return;
711   }
712   
713   track.Clear("C");
714   
715   // global info
716   track.SetUniqueID(esdTrack.GetUniqueID());
717   track.FitWithVertex(kFALSE);
718   track.FitWithMCS(kFALSE);
719   track.SetImproved(kFALSE);
720   track.SetVertexErrXY2(0.,0.);
721   track.SetGlobalChi2(esdTrack.GetChi2());
722   track.SetMatchTrigger(esdTrack.GetMatchTrigger());
723   track.SetChi2MatchTrigger(esdTrack.GetChi2MatchTrigger());
724   track.SetHitsPatternInTrigCh(esdTrack.GetHitsPatternInTrigCh());
725   track.SetHitsPatternInTrigChTrk(esdTrack.GetHitsPatternInTrigChTrk());
726   track.SetLocalTrigger(esdTrack.LoCircuit(), esdTrack.LoStripX(), esdTrack.LoStripY(),
727                         esdTrack.LoDev(), esdTrack.LoLpt(), esdTrack.LoHpt(),
728                         esdTrack.GetTriggerWithoutChamber());
729   track.Connected(esdTrack.IsConnected());
730   
731   // track parameters at vertex
732   AliMUONTrackParam paramAtVertex;
733   GetParamAtVertex(esdTrack, paramAtVertex);
734   track.SetTrackParamAtVertex(&paramAtVertex);
735     
736   // track parameters at first cluster
737   AliMUONTrackParam param;
738   GetParamAtFirstCluster(esdTrack, param);
739   GetParamCov(esdTrack, param);
740   
741   // create empty cluster
742   AliMUONVCluster* cluster = NewCluster();
743   
744   // fill TrackParamAtCluster with track parameters at each cluster if available
745   Bool_t clusterFound = kFALSE;
746   if(esdTrack.GetESDEvent()) {
747     
748     // loop over cluster Id
749     for (Int_t i = 0; i < esdTrack.GetNClusters(); i++) {
750       
751       // recover the ESDMuon cluster
752       AliESDMuonCluster *esdCluster = esdTrack.GetESDEvent()->FindMuonCluster(esdTrack.GetClusterId(i));
753       if (esdCluster) clusterFound = kTRUE;
754       else {
755         AliErrorClass("a cluster is missing in ESD");
756         continue;
757       }
758       
759       // copy cluster information
760       ESDToMUON(*esdCluster, *cluster);
761       
762       // only set the Z parameter to avoid error in the AddTrackParamAtCluster(...) method
763       param.SetZ(cluster->GetZ());
764       
765       // add common track parameters at current cluster
766       track.AddTrackParamAtCluster(param, *cluster, kTRUE);
767       
768     }
769     
770     // refit the track to get better parameters and covariances at each cluster (temporary disable track improvement)
771     if (clusterFound && refit) {
772       
773       AliMUONTrackParam *firstTrackParam = (AliMUONTrackParam*) track.GetTrackParamAtCluster()->First();
774       AliMUONTrackParam paramSave(*firstTrackParam);
775       
776       if (!fgTracker) ResetTracker();
777       
778       if (!fgTracker->RefitTrack(track, kFALSE) && track.GetGlobalChi2() < AliMUONTrack::MaxChi2()) {
779         *firstTrackParam = paramSave;
780         track.UpdateCovTrackParamAtCluster();
781       }
782       
783     }
784     
785   }
786   
787   // fill TrackParamAtCluster with only track parameters at first (fake) cluster if no cluster found in ESD
788   if (!clusterFound) {
789     
790     // get number of the first hit chamber according to the MUONClusterMap
791     Int_t firstCh = 0;
792     while (firstCh < 10 && !esdTrack.IsInMuonClusterMap(firstCh)) firstCh++;
793     
794     // produce fake cluster at this chamber
795     cluster->SetUniqueID(AliMUONVCluster::BuildUniqueID(firstCh, 0, 0));
796     cluster->SetXYZ(param.GetNonBendingCoor(), param.GetBendingCoor(), param.GetZ());
797     cluster->SetErrXY(0., 0.);
798     
799     // add track parameters at first (fake) cluster
800     track.AddTrackParamAtCluster(param, *cluster, kTRUE);
801     
802   }
803   
804   // set the MC label from ESD track
805   track.SetMCLabel(esdTrack.GetLabel());
806   
807   delete cluster;
808   
809 }
810
811 //_____________________________________________________________________________
812 void AliMUONESDInterface::ESDToMUON(const AliESDMuonTrack& esdTrack, AliMUONLocalTrigger& locTrg)
813 {
814   /// Transfert trigger data from ESDMuon track to the MUONLocalTtrigger object
815   
816   // if the ESDMuon track is a ghost then return an empty MUON track
817   if (!esdTrack.ContainTriggerData()) {
818     AliMUONLocalTrigger emptyLocTrg;
819     locTrg = emptyLocTrg;
820     return;
821   }
822   
823   locTrg.SetUniqueID(esdTrack.GetUniqueID());
824   locTrg.SetLoCircuit(esdTrack.LoCircuit());
825   locTrg.SetLoStripX(esdTrack.LoStripX());
826   locTrg.SetLoStripY(esdTrack.LoStripY());
827   locTrg.SetDeviation(esdTrack.LoDev());
828   locTrg.SetLoLpt(esdTrack.LoLpt());
829   locTrg.SetLoHpt(esdTrack.LoHpt());
830   locTrg.SetTriggerWithoutChamber(esdTrack.GetTriggerWithoutChamber());
831   locTrg.SetLoTrigY(1);
832   locTrg.SetX1Pattern(esdTrack.GetTriggerX1Pattern());
833   locTrg.SetX2Pattern(esdTrack.GetTriggerX2Pattern());
834   locTrg.SetX3Pattern(esdTrack.GetTriggerX3Pattern());
835   locTrg.SetX4Pattern(esdTrack.GetTriggerX4Pattern());
836   locTrg.SetY1Pattern(esdTrack.GetTriggerY1Pattern());
837   locTrg.SetY2Pattern(esdTrack.GetTriggerY2Pattern());
838   locTrg.SetY3Pattern(esdTrack.GetTriggerY3Pattern());
839   locTrg.SetY4Pattern(esdTrack.GetTriggerY4Pattern());
840   
841 }
842
843 //_____________________________________________________________________________
844 void AliMUONESDInterface::ESDToMUON(const AliESDMuonCluster& esdCluster, AliMUONVCluster& cluster)
845 {
846   /// Transfert data from ESDMuon cluster to MUON cluster
847   
848   cluster.Clear("C");
849   
850   cluster.SetUniqueID(esdCluster.GetUniqueID());
851   cluster.SetXYZ(esdCluster.GetX(), esdCluster.GetY(), esdCluster.GetZ());
852   cluster.SetErrXY(esdCluster.GetErrX(),esdCluster.GetErrY());
853   cluster.SetCharge(esdCluster.GetCharge());
854   cluster.SetChi2(esdCluster.GetChi2());
855   cluster.SetMCLabel(esdCluster.GetLabel());
856   
857   cluster.SetDigitsId(esdCluster.GetNPads(), esdCluster.GetPadsId());
858   
859 }
860
861 //___________________________________________________________________________
862 void AliMUONESDInterface::ESDToMUON(const AliESDMuonPad& esdPad, AliMUONVDigit& digit)
863 {
864   /// Transfert data from ESDMuon pad to MUON digit
865   /// Load mapping from OCDB if not already set
866   
867   if (!AliMpSegmentation::Instance(kFALSE) && !AliMUONCDB::LoadMapping(kTRUE))
868     AliFatalClass("mapping segmentation has not been set!");
869   
870   const AliMpVSegmentation* seg = AliMpSegmentation::Instance()->GetMpSegmentationByElectronics(esdPad.GetDetElemId(), esdPad.GetManuId());  
871   AliMpPad pad = seg->PadByLocation(esdPad.GetManuId(), esdPad.GetManuChannel(), kFALSE);
872   
873   digit.Saturated(esdPad.IsSaturated());
874   digit.Used(kFALSE);
875   digit.Calibrated(esdPad.IsCalibrated());
876   digit.SetUniqueID(esdPad.GetUniqueID());
877   digit.SetCharge(esdPad.GetCharge());
878   digit.SetADC(esdPad.GetADC());
879   digit.SetPadXY(pad.GetIx(), pad.GetIy());
880   
881 }
882
883 //_____________________________________________________________________________
884 void AliMUONESDInterface::MUONToESD(const AliMUONTrack& track, AliESDEvent& esd, const Double_t vertex[3],
885                                     const AliMUONVDigitStore* digits, const AliMUONLocalTrigger* locTrg)
886 {
887   /// Transfert data from MUON track to ESD event (ESDTrack + ESDClusters)
888   /// Incorporate the ESDPads if the digits are provided
889   /// Add trigger info if the MUON track is matched with a trigger track
890   
891   // transfert track info
892   AliESDMuonTrack *esdTrack = esd.NewMuonTrack();
893   MUONToESD(track, *esdTrack, vertex, locTrg);
894   
895   // transfert cluster info if any
896   for (Int_t i = 0; i < track.GetNClusters(); i++) {
897     AliMUONTrackParam *param = static_cast<AliMUONTrackParam*>(track.GetTrackParamAtCluster()->UncheckedAt(i));
898     MUONToESD(*(param->GetClusterPtr()), esd, digits);
899   }
900   
901 }
902
903 //_____________________________________________________________________________
904 void AliMUONESDInterface::MUONToESD(const AliMUONTrack& track, AliESDMuonTrack& esdTrack,
905                                     const Double_t vertex[3], const AliMUONLocalTrigger* locTrg)
906 {
907   /// Transfert data from MUON track to ESDMuon track (ESDMuon track only contains clusters'Id, not cluster themselves)
908   /// Add trigger info if the MUON track is matched with a trigger track
909   
910   // empty MUON track -> produce a ghost ESDMuon track if trigger info are available otherwise produce an empty track
911   if (track.GetNClusters() == 0) {
912     if (locTrg) MUONToESD(*locTrg, esdTrack, track.GetUniqueID());
913     else {
914       cout<<"W-AliMUONESDInterface::MUONToESD: will produce an empty ESDMuon track"<<endl;
915       esdTrack.Reset();
916       esdTrack.SetUniqueID(0xFFFFFFFF);
917     }
918     return;
919   }
920   
921   esdTrack.Clear("C");
922   
923   // set global info
924   esdTrack.SetUniqueID(track.GetUniqueID());
925   esdTrack.SetChi2(track.GetGlobalChi2());
926   esdTrack.SetLabel(track.GetMCLabel());
927   
928   // set param at first cluster
929   AliMUONTrackParam* trackParam = static_cast<AliMUONTrackParam*>((track.GetTrackParamAtCluster())->First());
930   SetParamAtFirstCluster(*trackParam, esdTrack);
931   SetParamCov(*trackParam, esdTrack);
932   
933   // set transverse position at the end of the absorber
934   AliMUONTrackParam trackParamAtAbsEnd(*trackParam);
935   AliMUONTrackExtrap::ExtrapToZ(&trackParamAtAbsEnd, AliMUONConstants::AbsZEnd());
936   Double_t xAbs = trackParamAtAbsEnd.GetNonBendingCoor();
937   Double_t yAbs = trackParamAtAbsEnd.GetBendingCoor();
938   esdTrack.SetRAtAbsorberEnd(TMath::Sqrt(xAbs*xAbs + yAbs*yAbs));
939   
940   // set param at vertex
941   AliMUONTrackParam trackParamAtVtx(*trackParam);
942   AliMUONTrackExtrap::ExtrapToVertex(&trackParamAtVtx, vertex[0], vertex[1], vertex[2], 0., 0.);
943   SetParamAtVertex(trackParamAtVtx, esdTrack);
944   
945   // set param at Distance of Closest Approach
946   AliMUONTrackParam trackParamAtDCA(*trackParam);
947   AliMUONTrackExtrap::ExtrapToVertexWithoutBranson(&trackParamAtDCA, vertex[2]);
948   SetParamAtDCA(trackParamAtDCA, esdTrack);
949   
950   // set muon cluster info
951   esdTrack.SetMuonClusterMap(0);
952   while (trackParam) {
953     AliMUONVCluster *cluster = trackParam->GetClusterPtr();
954     esdTrack.AddClusterId(cluster->GetUniqueID());
955     esdTrack.AddInMuonClusterMap(cluster->GetChamberId());
956     trackParam = static_cast<AliMUONTrackParam*>(track.GetTrackParamAtCluster()->After(trackParam));
957   }
958   
959   // set connected flag
960   esdTrack.Connected(track.IsConnected());
961   
962   // set trigger info
963   esdTrack.SetLocalTrigger(track.GetLocalTrigger());
964   esdTrack.SetChi2MatchTrigger(track.GetChi2MatchTrigger());
965   esdTrack.SetHitsPatternInTrigCh(track.GetHitsPatternInTrigCh());
966   esdTrack.SetHitsPatternInTrigChTrk(track.GetHitsPatternInTrigChTrk());
967   if (locTrg) {
968     esdTrack.SetTriggerX1Pattern(locTrg->GetX1Pattern());
969     esdTrack.SetTriggerY1Pattern(locTrg->GetY1Pattern());
970     esdTrack.SetTriggerX2Pattern(locTrg->GetX2Pattern());
971     esdTrack.SetTriggerY2Pattern(locTrg->GetY2Pattern());
972     esdTrack.SetTriggerX3Pattern(locTrg->GetX3Pattern());
973     esdTrack.SetTriggerY3Pattern(locTrg->GetY3Pattern());
974     esdTrack.SetTriggerX4Pattern(locTrg->GetX4Pattern());
975     esdTrack.SetTriggerY4Pattern(locTrg->GetY4Pattern());
976   } else {
977     esdTrack.SetTriggerX1Pattern(0);
978     esdTrack.SetTriggerY1Pattern(0);
979     esdTrack.SetTriggerX2Pattern(0);
980     esdTrack.SetTriggerY2Pattern(0);
981     esdTrack.SetTriggerX3Pattern(0);
982     esdTrack.SetTriggerY3Pattern(0);
983     esdTrack.SetTriggerX4Pattern(0);
984     esdTrack.SetTriggerY4Pattern(0);
985   }
986   
987 }
988
989 //_____________________________________________________________________________
990 void AliMUONESDInterface::MUONToESD(const AliMUONLocalTrigger& locTrg, AliESDEvent& esd,
991                                     UInt_t trackId, const AliMUONTriggerTrack* triggerTrack)
992 {
993   /// Add in ESD event a ghost ESDMuon track containing only informations about trigger track
994   AliESDMuonTrack *esdTrack = esd.NewMuonTrack();
995   MUONToESD(locTrg, *esdTrack, trackId, triggerTrack);
996 }
997
998 //_____________________________________________________________________________
999 void AliMUONESDInterface::MUONToESD(const AliMUONLocalTrigger& locTrg, AliESDMuonTrack& esdTrack,
1000                                     UInt_t trackId, const AliMUONTriggerTrack* triggerTrack)
1001 {
1002   /// Build ghost ESDMuon track containing only informations about trigger track
1003   
1004   esdTrack.Reset();
1005   esdTrack.SetUniqueID(trackId);
1006   
1007   // set trigger info
1008   AliMUONTrack muonTrack;
1009   muonTrack.SetLocalTrigger(locTrg.LoCircuit(),
1010                             locTrg.LoStripX(),
1011                             locTrg.LoStripY(),
1012                             locTrg.GetDeviation(),
1013                             locTrg.LoLpt(),
1014                             locTrg.LoHpt(),
1015                             locTrg.GetTriggerWithoutChamber());
1016   esdTrack.SetLocalTrigger(muonTrack.GetLocalTrigger());
1017   esdTrack.SetChi2MatchTrigger(0.);
1018   esdTrack.SetTriggerX1Pattern(locTrg.GetX1Pattern());
1019   esdTrack.SetTriggerY1Pattern(locTrg.GetY1Pattern());
1020   esdTrack.SetTriggerX2Pattern(locTrg.GetX2Pattern());
1021   esdTrack.SetTriggerY2Pattern(locTrg.GetY2Pattern());
1022   esdTrack.SetTriggerX3Pattern(locTrg.GetX3Pattern());
1023   esdTrack.SetTriggerY3Pattern(locTrg.GetY3Pattern());
1024   esdTrack.SetTriggerX4Pattern(locTrg.GetX4Pattern());
1025   esdTrack.SetTriggerY4Pattern(locTrg.GetY4Pattern());
1026   UShort_t hitPattern = 0;
1027   esdTrack.SetHitsPatternInTrigChTrk(hitPattern);
1028   if(triggerTrack){
1029     hitPattern = triggerTrack->GetHitsPatternInTrigCh();
1030     esdTrack.SetHitsPatternInTrigCh(hitPattern);
1031     esdTrack.SetThetaXUncorrected(triggerTrack->GetThetax());
1032     esdTrack.SetThetaYUncorrected(triggerTrack->GetThetay());
1033     esdTrack.SetNonBendingCoorUncorrected(triggerTrack->GetX11());
1034     esdTrack.SetBendingCoorUncorrected(triggerTrack->GetY11());
1035     esdTrack.SetZUncorrected(triggerTrack->GetZ11());
1036   }
1037 }
1038
1039 //_____________________________________________________________________________
1040 void AliMUONESDInterface::MUONToESD(const AliMUONVCluster& cluster, AliESDEvent& esd, const AliMUONVDigitStore* digits)
1041 {
1042   /// Transfert data from MUON cluster to ESD event if it does not already exist
1043   /// Also transfert digits'Id to cluster and digits to ESD if they are provided
1044   
1045   AliESDMuonCluster *esdCluster = esd.FindMuonCluster(cluster.GetUniqueID());
1046   if (!esdCluster) esdCluster = esd.NewMuonCluster();
1047   else if (!digits || esdCluster->GetNPads() > 0) return;
1048   
1049   if (digits) {
1050     
1051     MUONToESD(cluster, *esdCluster, kTRUE);
1052     
1053     for (Int_t i=0; i<cluster.GetNDigits(); i++) {
1054       AliMUONVDigit* digit = digits->FindObject(cluster.GetDigitId(i));
1055       if (!digit) {
1056         AliErrorClass(Form("digit %u not found", cluster.GetDigitId(i)));
1057         continue;
1058       }
1059       MUONToESD(*digit, esd);
1060     }
1061     
1062   } else {
1063     
1064     MUONToESD(cluster, *esdCluster, kFALSE);
1065     
1066   }
1067   
1068 }
1069
1070 //_____________________________________________________________________________
1071 void AliMUONESDInterface::MUONToESD(const AliMUONVCluster& cluster, AliESDMuonCluster& esdCluster, Bool_t copyPadsId)
1072 {
1073   /// Transfert data from MUON cluster to ESDMuon cluster
1074   /// Also transfert digits'Is if required
1075   
1076   esdCluster.Clear("C");
1077   
1078   esdCluster.SetUniqueID(cluster.GetUniqueID());
1079   esdCluster.SetXYZ(cluster.GetX(), cluster.GetY(), cluster.GetZ());
1080   esdCluster.SetErrXY(cluster.GetErrX(), cluster.GetErrY());
1081   esdCluster.SetCharge(cluster.GetCharge());
1082   esdCluster.SetChi2(cluster.GetChi2());
1083   esdCluster.SetLabel(cluster.GetMCLabel());
1084   
1085   if (copyPadsId) esdCluster.SetPadsId(cluster.GetNDigits(), cluster.GetDigitsId());
1086   
1087 }
1088
1089 //_____________________________________________________________________________
1090 void AliMUONESDInterface::MUONToESD(const AliMUONVDigit& digit, AliESDEvent& esd)
1091 {
1092   /// Transfert data from MUON digit to ESD event if it does not already exist
1093   if (esd.FindMuonPad(digit.GetUniqueID())) return;
1094   AliESDMuonPad *esdPad = esd.NewMuonPad();
1095   MUONToESD(digit, *esdPad);
1096 }
1097
1098 //_____________________________________________________________________________
1099 void AliMUONESDInterface::MUONToESD(const AliMUONVDigit& digit, AliESDMuonPad& esdPad)
1100 {
1101   /// Transfert data from MUON digit to ESDMuon pad
1102   esdPad.SetUniqueID(digit.GetUniqueID());
1103   esdPad.SetADC(digit.ADC());
1104   esdPad.SetCharge(digit.Charge());
1105   esdPad.SetCalibrated(digit.IsCalibrated());
1106   esdPad.SetSaturated(digit.IsSaturated());
1107 }
1108
1109 //___________________________________________________________________________
1110 AliMUONTrack* AliMUONESDInterface::Add(const AliESDMuonTrack& esdTrack, AliMUONVTrackStore& trackStore, Bool_t refit)
1111 {
1112   /// Create MUON track from ESDMuon track and add it to the store
1113   /// Track parameters at each clusters are recomputed or not depending on the flag "refit"
1114   /// return a pointer to the track into the store (0x0 if the track already exist)
1115   if(trackStore.FindObject(esdTrack.GetUniqueID())) return 0x0;
1116   AliMUONTrack* track = trackStore.Add(AliMUONTrack());
1117   ESDToMUON(esdTrack, *track, refit);
1118   return track;
1119 }
1120
1121 //___________________________________________________________________________
1122 void AliMUONESDInterface::Add(const AliESDMuonTrack& esdTrack, AliMUONVTriggerStore& triggerStore)
1123 {
1124   /// Create MUON local trigger from ESDMuon track and add it to the store if not already there
1125   if (!triggerStore.FindLocal(esdTrack.LoCircuit())->IsNull()) return;
1126   AliMUONLocalTrigger locTrg;
1127   ESDToMUON(esdTrack, locTrg);
1128   triggerStore.Add(locTrg);
1129 }
1130
1131 //___________________________________________________________________________
1132 AliMUONVCluster* AliMUONESDInterface::Add(const AliESDMuonCluster& esdCluster, AliMUONVClusterStore& clusterStore)
1133 {
1134   /// Create MUON cluster from ESDMuon cluster and add it to the store
1135   /// return a pointer to the cluster into the store (0x0 if the cluster already exist)
1136   AliMUONVCluster* cluster = clusterStore.Add(esdCluster.GetChamberId(), esdCluster.GetDetElemId(), esdCluster.GetClusterIndex());
1137   if (cluster) ESDToMUON(esdCluster, *cluster);
1138   return cluster;
1139 }
1140
1141 //___________________________________________________________________________
1142 AliMUONVDigit* AliMUONESDInterface::Add(const AliESDMuonPad& esdPad, AliMUONVDigitStore& digitStore)
1143 {
1144   /// Create MUON digit from ESDMuon digit and add it to the store
1145   /// return a pointer to the digit into the store (0x0 if the digit already exist)
1146   AliMUONVDigit* digit = digitStore.Add(esdPad.GetDetElemId(), esdPad.GetManuId(), esdPad.GetManuChannel(), esdPad.GetCathode(), AliMUONVDigitStore::kDeny);
1147   if (digit) ESDToMUON(esdPad, *digit);
1148   return digit;
1149 }
1150