Changes for #90436: Misuse of TClonesArray containing AliESDMuonCluster
authorhristov <hristov@f7af4fe6-9843-0410-8265-dc069ae4e863>
Fri, 30 Mar 2012 13:45:08 +0000 (13:45 +0000)
committerhristov <hristov@f7af4fe6-9843-0410-8265-dc069ae4e863>
Fri, 30 Mar 2012 13:45:08 +0000 (13:45 +0000)
37 files changed:
EVE/EveDet/AliEveMUONData.cxx
HLT/CMakelibAliHLTEve.pkg
HLT/EVE/AliHLTEveMuon.cxx
HLT/EVE/AliHLTEveMuon.h
HLT/MUON/OfflineInterface/AliHLTMUONESDMaker.cxx
HLT/MUON/OfflineInterface/AliHLTMUONESDMaker.h
HLT/global/AliHLTGlobalEsdConverterComponent.cxx
HLT/trigger/macros/testGeomTrigger.C
MUON/AliMUONAlignmentTask.cxx
MUON/AliMUONESDInterface.cxx
MUON/AliMUONESDInterface.h
MUON/AliMUONRawClusterV2.h
MUON/AliMUONReAlignTask.cxx
MUON/AliMUONRecoCheck.cxx
MUON/AliMUONRefitter.cxx
MUON/AliMUONRefitter.h
MUON/AliMUONSimpleClusterServer.h
MUON/AliMUONTracker.cxx
MUON/AliMUONVCluster.h
MUON/MUONAlignment.C
MUON/MUONRefit.C
MUON/READMErec.txt
PWG/muon/AliAnalysisMuMuFromESD.cxx
PWG/muon/AliAnalysisMuMuFromESD.h
PWG/muon/AliAnalysisTaskLinkToMC.cxx
PWG/muondep/AliAnalysisTaskMuonRefit.cxx
PWGPP/CMakelibPWGPPMUONlite.pkg
PWGPP/MUON/dep/MuonResolution.C
PWGPP/MUON/dep/RunMuonResolution.C
PWGPP/MUON/lite/AliAnalysisTaskMuonQA.cxx
PWGPP/MUON/lite/RunMuonQA.C
STEER/ESD/AliESDEvent.cxx
STEER/ESD/AliESDEvent.h
STEER/ESD/AliESDMuonCluster.cxx
STEER/ESD/AliESDMuonCluster.h
STEER/ESD/AliESDMuonTrack.cxx
STEER/ESD/AliESDMuonTrack.h

index d490b8a..0403722 100644 (file)
@@ -280,7 +280,7 @@ void AliEveMUONData::LoadRecPointsFromESD(const Char_t *fileName)
   Int_t nTracks = Int_t(esdEvent->GetNumberOfMuonTracks());
   for (Int_t iTrack = 0; iTrack < nTracks; iTrack++) {
     esdTrack = esdEvent->GetMuonTrack(iTrack);
-    if (!esdTrack->ClustersStored()) continue;
+    if (!esdTrack->ContainTrackerData()) continue;
     AliMUONESDInterface::ESDToMUON(*esdTrack,muonTrack);
     nTrackParam = muonTrack.GetTrackParamAtCluster()->GetEntries();
     for(Int_t iCluster = 0; iCluster < nTrackParam; iCluster++) {
index 56e1d11..d648d6a 100644 (file)
@@ -53,7 +53,7 @@ set ( MODULE_DHDR )
 
 set ( EINCLUDE  HLT/BASE HLT/shuttle HLT/EVE EVE/EveHLT EVE/EveBase EVE/EveDet HLT/BASE/util HLT/BASE/HOMER  HLT/TPCLib ITS PHOS TRIGGER VZERO EMCAL TRD HLT/TRD HLT/MUON MUON HLT/rec STEER/ESD STEER/STEERBase)
 
-set ( ELIBS  "HLTbase CDB STEERBase AliHLTTPC MUONbase AliHLTMUON EveDet")
+set ( ELIBS  "HLTbase CDB STEERBase AliHLTTPC MUONbase MUONrec AliHLTMUON EveDet")
 
 include ("CMakehlteve.conf")
 
index 05625e2..84a9f6d 100644 (file)
 \r
 #include "TEveVSDStructs.h"\r
 #include "TGeoGlobalMagField.h"\r
-#include "AliESDMuonTrack.h"\r
-#include "AliESDMuonCluster.h"\r
+#include "AliMUONTrack.h"\r
+#include "AliMUONTrackParam.h"\r
+#include "AliMUONESDInterface.h"\r
+#include "AliMUONVTrackReconstructor.h"\r
 #include "AliEveMUONTrack.h"\r
 #include "AliHLTMUONConstants.h"\r
 #include "AliHLTMUONUtils.h"\r
 #include "AliMUONVCluster.h"\r
+#include "AliMUONVClusterStore.h"\r
 #include "AliMUONConstants.h"\r
 #include "TEveTrackPropagator.h"\r
 \r
@@ -250,7 +253,7 @@ void AliHLTEveMuon::ProcessTracks(AliHLTHOMERBlockDesc * block, TEveStraightLine
   }\r
 }\r
 \r
-int AliHLTEveMuon::MakeMUONESDTrack(AliESDMuonTrack *muonESDTrack, const AliHLTMUONTrackStruct *muonHLTTrack)\r
+int AliHLTEveMuon::MakeMUONTrack(AliMUONTrack *muonTrack, const AliHLTMUONTrackStruct *muonHLTTrack)\r
 {\r
   // See header for documentation\r
   AliHLTUInt32_t clusterIndex = 0;  // for the cluster unique ID.                      \r
@@ -259,23 +262,29 @@ int AliHLTEveMuon::MakeMUONESDTrack(AliESDMuonTrack *muonESDTrack, const AliHLTM
   AliHLTMUONUtils::UnpackTrackFlags(\r
                                    muonHLTTrack->fFlags, sign, hitset\r
                                    );\r
-                       \r
+  \r
+  // add track parameters at vertex\r
   TVector3 mom(muonHLTTrack->fPx, muonHLTTrack->fPy, muonHLTTrack->fPz);\r
+  AliMUONTrackParam paramAtVtx;\r
   if (mom.Mag() != 0)\r
-    muonESDTrack->SetInverseBendingMomentum(muonHLTTrack->fInverseBendingMomentum);\r
+    paramAtVtx.SetInverseBendingMomentum(muonHLTTrack->fInverseBendingMomentum);\r
   else\r
-    muonESDTrack->SetInverseBendingMomentum(0.);\r
-  muonESDTrack->SetThetaX(muonHLTTrack->fThetaX);\r
-  muonESDTrack->SetThetaY(muonHLTTrack->fThetaY);\r
-  muonESDTrack->SetZ(muonHLTTrack->fZ);\r
-  muonESDTrack->SetBendingCoor(muonHLTTrack->fY);\r
-  muonESDTrack->SetNonBendingCoor(muonHLTTrack->fX);\r
+    paramAtVtx.SetInverseBendingMomentum(0.);\r
+  paramAtVtx.SetNonBendingSlope(TMath::Tan(muonHLTTrack->fThetaX));\r
+  paramAtVtx.SetBendingSlope(TMath::Tan(muonHLTTrack->fThetaY));\r
+  paramAtVtx.SetZ(muonHLTTrack->fZ);\r
+  paramAtVtx.SetBendingCoor(muonHLTTrack->fY);\r
+  paramAtVtx.SetNonBendingCoor(muonHLTTrack->fX);\r
+  muonTrack->SetTrackParamAtVertex(&paramAtVtx);\r
 \r
   //printf("(X,Y,Z) : (%8.3f,%8.3f,%8.3f)\n",muonHLTTrack->fX,muonHLTTrack->fY,muonHLTTrack->fZ);\r
 \r
-  muonESDTrack->SetChi2(muonHLTTrack->fChi2);\r
-\r
+  // add clusters\r
   Int_t nHits = 0;\r
+  AliMUONVClusterStore* cStore = AliMUONESDInterface::NewClusterStore();\r
+  if (!cStore) return -1;\r
+  AliMUONVCluster* cluster = cStore->CreateCluster(0,0,0);\r
+  AliMUONTrackParam trackParam;\r
   for (int i = 0; i < 16; i++)\r
     {\r
       if (not hitset[i]) continue;\r
@@ -284,22 +293,33 @@ int AliHLTEveMuon::MakeMUONESDTrack(AliESDMuonTrack *muonESDTrack, const AliHLTM
       AliHLTUInt16_t detElemId;\r
       AliHLTMUONUtils::UnpackRecHitFlags((muonHLTTrack->fHit[i]).fFlags, chamber, detElemId);\r
       \r
-      AliESDMuonCluster cluster;\r
-      cluster.SetUniqueID(AliMUONVCluster::BuildUniqueID(chamber, detElemId, clusterIndex++));\r
-      cluster.SetXYZ((muonHLTTrack->fHit[i]).fX, (muonHLTTrack->fHit[i]).fY, (muonHLTTrack->fHit[i]).fZ);\r
-      cluster.SetErrXY(    // Use nominal values.\r
-                      AliHLTMUONConstants::DefaultNonBendingReso(),\r
-                      AliHLTMUONConstants::DefaultBendingReso()\r
-                          );\r
-      cluster.SetCharge(-1.);   // Indicate no total charge calculated.\r
-      cluster.SetChi2(-1.);   // Indicate no fit made.\r
-      muonESDTrack->AddCluster(cluster);\r
+      cluster->SetUniqueID(AliMUONVCluster::BuildUniqueID(chamber, detElemId, clusterIndex++));\r
+      cluster->SetXYZ((muonHLTTrack->fHit[i]).fX, (muonHLTTrack->fHit[i]).fY, (muonHLTTrack->fHit[i]).fZ);\r
+      cluster->SetErrXY(    // Use nominal values.\r
+                       AliHLTMUONConstants::DefaultNonBendingReso(),\r
+                       AliHLTMUONConstants::DefaultBendingReso()\r
+                       );\r
+      cluster->SetCharge(-1.);   // Indicate no total charge calculated.\r
+      cluster->SetChi2(-1.);   // Indicate no fit made.\r
+      trackParam.SetZ(cluster->GetZ());\r
+      muonTrack->AddTrackParamAtCluster(trackParam, *cluster, kTRUE);\r
       nHits++;\r
-      muonESDTrack->AddInMuonClusterMap(chamber);\r
     }\r
   \r
-  muonESDTrack->SetNHit(nHits);\r
+  // compute track parameters at each cluster\r
+  if (nHits > 0) {\r
+    AliMUONTrackParam *firstTrackParam = (AliMUONTrackParam*) muonTrack->GetTrackParamAtCluster()->First();\r
+    trackParam = (*firstTrackParam);\r
+    if (!AliMUONESDInterface::GetTracker()) AliMUONESDInterface::ResetTracker();\r
+    if (!AliMUONESDInterface::GetTracker()->RefitTrack(*muonTrack, kFALSE) &&\r
+       muonTrack->GetGlobalChi2() < AliMUONTrack::MaxChi2()) {\r
+      *firstTrackParam = trackParam;\r
+      muonTrack->UpdateCovTrackParamAtCluster();\r
+    }\r
+  }\r
 \r
+  muonTrack->SetGlobalChi2(muonHLTTrack->fChi2);\r
+  \r
   return 0;\r
 }\r
 \r
@@ -333,16 +353,16 @@ Int_t AliHLTEveMuon::ProcessFullTracks(AliHLTHOMERBlockDesc * block, TEveTrackLi
   //cout<<"NofTracks : "<<muontrackblock.Nentries()<<endl;\r
   for(AliHLTUInt32_t ientry = 0; ientry < muontrackblock.Nentries(); ientry++){\r
     \r
-    AliESDMuonTrack *muonESDTrack = new AliESDMuonTrack();\r
-    MakeMUONESDTrack(muonESDTrack,mtrack);\r
-    if(muonESDTrack->GetNHit()==0){\r
-      muonESDTrack->Delete();\r
+    AliMUONTrack *muonTrack = new AliMUONTrack();\r
+    MakeMUONTrack(muonTrack,mtrack);\r
+    if(muonTrack->GetNClusters()==0){\r
+      delete muonTrack;\r
       continue;\r
     }\r
     \r
     rt.fLabel = ientry;\r
     AliEveMUONTrack* track = new AliEveMUONTrack(&rt, fullTracks->GetPropagator());\r
-    track->MakeESDTrack(muonESDTrack);\r
+    track->MakeMUONTrack(muonTrack);\r
     //track->SetTitle(Form("HLT Track : %d, pt : %lf",ientry,TMath::Sqrt(((mtrack->fPx * mtrack->fPx) + (mtrack->fPy * mtrack->fPy)))));\r
     track->SetName(Form("HLT Track : %d, pt : %lf",ientry,TMath::Sqrt(((mtrack->fPx * mtrack->fPx) + (mtrack->fPy * mtrack->fPy)))));\r
     fullTracks->AddElement(track);\r
index f9335aa..3368c0f 100644 (file)
@@ -15,7 +15,7 @@ class AliHLTHOMERBlockDesc;
 class TEveStraightLineSet;\r
 class TEvePointSet;\r
 class TEveTrackList;\r
-class AliESDMuonTrack;\r
+class AliMUONTrack;\r
 class AliHLTMUONTrackStruct;\r
 \r
 class AliHLTEveMuon : public AliHLTEveBase {\r
@@ -54,8 +54,8 @@ private:
   /** Process block containing Full Tracks **/\r
   Int_t ProcessFullTracks(AliHLTHOMERBlockDesc * block, TEveTrackList * tracks);\r
   \r
-  /** Convert muon Full Tracks block to Muon ESD tracks **/\r
-  int MakeMUONESDTrack(AliESDMuonTrack *muonESDTrack, const AliHLTMUONTrackStruct *muonHLTTrack);\r
+  /** Convert muon Full Tracks block to Muon tracks **/\r
+  int MakeMUONTrack(AliMUONTrack *muonTrack, const AliHLTMUONTrackStruct *muonHLTTrack);\r
 \r
   /** create the cluster pointset**/\r
   TEvePointSet * CreateClusters();\r
index 5911c6f..2dda8b8 100644 (file)
@@ -230,6 +230,9 @@ int AliHLTMUONESDMaker::DoEvent(
                TClonesArray* muonTracks = new TClonesArray("AliESDMuonTrack",2);
                muonTracks->SetName("MuonTracks");
                event.AddObject(muonTracks);
+               TClonesArray* muonClusters = new TClonesArray("AliESDMuonCluster",0);
+               muonClusters->SetName("MuonClusters");
+               event.AddObject(muonClusters);
                event.GetStdContent();
        }
        else
@@ -324,7 +327,7 @@ int AliHLTMUONESDMaker::DoEvent(
                for (AliHLTUInt32_t n = 0; n < inblock.Nentries(); n++)
                {
                        const AliHLTMUONMansoTrackStruct& t = inblock[n];
-                       AliESDMuonTrack muTrack;
+                       AliESDMuonTrack *muTrack = event.NewMuonTrack();
                        
                        AliHLTMUONParticleSign sign;
                        bool hitset[4];
@@ -342,41 +345,40 @@ int AliHLTMUONESDMaker::DoEvent(
                        
                        TVector3 mom(t.fPx, t.fPy, t.fPz);
                        if (mom.Mag() != 0)
-                               muTrack.SetInverseBendingMomentum(signVal/mom.Mag());
+                               muTrack->SetInverseBendingMomentum(signVal/mom.Mag());
                        else
-                               muTrack.SetInverseBendingMomentum(0.);
-                       muTrack.SetThetaX(atan2(t.fPx, t.fPz));
-                       muTrack.SetThetaY(atan2(t.fPy, t.fPz));
-                       muTrack.SetZ(0.);
-                       muTrack.SetBendingCoor(0.);
-                       muTrack.SetNonBendingCoor(0.);
+                               muTrack->SetInverseBendingMomentum(0.);
+                       muTrack->SetThetaX(atan2(t.fPx, t.fPz));
+                       muTrack->SetThetaY(atan2(t.fPy, t.fPz));
+                       muTrack->SetZ(0.);
+                       muTrack->SetBendingCoor(0.);
+                       muTrack->SetNonBendingCoor(0.);
                        
                        // The Manso algorithm assumes the information at the
                        // Distance of Closest Approach and chamber 1 is the same
                        // as the vertex.
                        if (mom.Mag() != 0)
-                               muTrack.SetInverseBendingMomentumAtDCA(1./mom.Mag());
+                               muTrack->SetInverseBendingMomentumAtDCA(1./mom.Mag());
                        else
-                               muTrack.SetInverseBendingMomentumAtDCA(0.);
-                       muTrack.SetThetaXAtDCA(atan2(t.fPx, t.fPz));
-                       muTrack.SetThetaYAtDCA(atan2(t.fPy, t.fPz));
-                       muTrack.SetBendingCoorAtDCA(0.);
-                       muTrack.SetNonBendingCoorAtDCA(0.);
+                               muTrack->SetInverseBendingMomentumAtDCA(0.);
+                       muTrack->SetThetaXAtDCA(atan2(t.fPx, t.fPz));
+                       muTrack->SetThetaYAtDCA(atan2(t.fPy, t.fPz));
+                       muTrack->SetBendingCoorAtDCA(0.);
+                       muTrack->SetNonBendingCoorAtDCA(0.);
                        
                        if (mom.Mag() != 0)
-                               muTrack.SetInverseBendingMomentumUncorrected(1./mom.Mag());
+                               muTrack->SetInverseBendingMomentumUncorrected(1./mom.Mag());
                        else
-                               muTrack.SetInverseBendingMomentumUncorrected(0.);
-                       muTrack.SetThetaXUncorrected(atan2(t.fPx, t.fPz));
-                       muTrack.SetThetaYUncorrected(atan2(t.fPy, t.fPz));
-                       muTrack.SetZUncorrected(0.);
-                       muTrack.SetBendingCoorUncorrected(0.);
-                       muTrack.SetNonBendingCoorUncorrected(0.);
+                               muTrack->SetInverseBendingMomentumUncorrected(0.);
+                       muTrack->SetThetaXUncorrected(atan2(t.fPx, t.fPz));
+                       muTrack->SetThetaYUncorrected(atan2(t.fPy, t.fPz));
+                       muTrack->SetZUncorrected(0.);
+                       muTrack->SetBendingCoorUncorrected(0.);
+                       muTrack->SetNonBendingCoorUncorrected(0.);
                        
-                       muTrack.SetChi2(t.fChi2);
+                       muTrack->SetChi2(t.fChi2);
                        
                        // Fill in the track hit points.
-                       Int_t nHits = 0;
                        for (int i = 0; i < 4; i++)
                        {
                                if (not hitset[i]) continue;
@@ -385,23 +387,20 @@ int AliHLTMUONESDMaker::DoEvent(
                                AliHLTUInt16_t detElemId;
                                AliHLTMUONUtils::UnpackRecHitFlags(t.fHit[i].fFlags, chamber, detElemId);
                                
-                               AliESDMuonCluster cluster;
-                               cluster.SetUniqueID(AliMUONVCluster::BuildUniqueID(chamber, detElemId, fClusterIndex++));
-                               cluster.SetXYZ(t.fHit[i].fX, t.fHit[i].fY, t.fHit[i].fZ);
-                               cluster.SetErrXY(    // Use nominal values.
-                                               AliHLTMUONConstants::DefaultNonBendingReso(),
-                                               AliHLTMUONConstants::DefaultBendingReso()
-                                       );
-                               cluster.SetCharge(-1.);   // Indicate no total charge calculated.
-                               cluster.SetChi2(-1.);   // Indicate no fit made.
-                               muTrack.AddCluster(cluster);
-                               nHits++;
-                               muTrack.AddInMuonClusterMap(i+6);
+                               AliESDMuonCluster *cluster = event.NewMuonCluster();
+                               cluster->SetUniqueID(AliMUONVCluster::BuildUniqueID(chamber, detElemId, fClusterIndex++));
+                               cluster->SetXYZ(t.fHit[i].fX, t.fHit[i].fY, t.fHit[i].fZ);
+                               cluster->SetErrXY(    // Use nominal values.
+                                                 AliHLTMUONConstants::DefaultNonBendingReso(),
+                                                 AliHLTMUONConstants::DefaultBendingReso()
+                                                 );
+                               cluster->SetCharge(-1.);   // Indicate no total charge calculated.
+                               cluster->SetChi2(-1.);   // Indicate no fit made.
+                               muTrack->AddClusterId(cluster->GetUniqueID());
+                               muTrack->AddInMuonClusterMap(i+6);
                        }
                        
-                       FillTriggerInfo(triggerRecords, t.fTrigRec, t.fId, muTrack, nHits);
-                       muTrack.SetNHit(nHits);
-                       event.AddMuonTrack(&muTrack);
+                       FillTriggerInfo(triggerRecords, t.fTrigRec, t.fId, *muTrack, event);
                }
        }
 
@@ -421,39 +420,38 @@ int AliHLTMUONESDMaker::DoEvent(
                for (AliHLTUInt32_t n = 0; n < inblock.Nentries(); n++)
                {
                        const AliHLTMUONTrackStruct& t = inblock[n];
-                       AliESDMuonTrack muTrack;
+                       AliESDMuonTrack *muTrack = event.NewMuonTrack();
                        
                        AliHLTMUONParticleSign sign;
                        bool hitset[16];
                        AliHLTMUONUtils::UnpackTrackFlags(t.fFlags, sign, hitset);
                        
-                       muTrack.SetInverseBendingMomentum(t.fInverseBendingMomentum);
-                       muTrack.SetThetaX(t.fThetaX);
-                       muTrack.SetThetaY(t.fThetaY);
-                       muTrack.SetZ(t.fZ);
-                       muTrack.SetBendingCoor(t.fY);
-                       muTrack.SetNonBendingCoor(t.fX);
+                       muTrack->SetInverseBendingMomentum(t.fInverseBendingMomentum);
+                       muTrack->SetThetaX(t.fThetaX);
+                       muTrack->SetThetaY(t.fThetaY);
+                       muTrack->SetZ(t.fZ);
+                       muTrack->SetBendingCoor(t.fY);
+                       muTrack->SetNonBendingCoor(t.fX);
                        
                        // The full tracker assumes the information at the
                        // Distance of Closest Approach and chamber 1 is the same
                        // as the vertex.
-                       muTrack.SetInverseBendingMomentumAtDCA(t.fInverseBendingMomentum);
-                       muTrack.SetThetaXAtDCA(t.fThetaX);
-                       muTrack.SetThetaYAtDCA(t.fThetaY);
-                       muTrack.SetBendingCoorAtDCA(t.fY);
-                       muTrack.SetNonBendingCoorAtDCA(t.fX);
+                       muTrack->SetInverseBendingMomentumAtDCA(t.fInverseBendingMomentum);
+                       muTrack->SetThetaXAtDCA(t.fThetaX);
+                       muTrack->SetThetaYAtDCA(t.fThetaY);
+                       muTrack->SetBendingCoorAtDCA(t.fY);
+                       muTrack->SetNonBendingCoorAtDCA(t.fX);
                                
-                       muTrack.SetInverseBendingMomentumUncorrected(t.fInverseBendingMomentum);
-                       muTrack.SetThetaXUncorrected(t.fThetaX);
-                       muTrack.SetThetaYUncorrected(t.fThetaY);
-                       muTrack.SetZUncorrected(t.fZ);
-                       muTrack.SetBendingCoorUncorrected(t.fY);
-                       muTrack.SetNonBendingCoorUncorrected(t.fX);
+                       muTrack->SetInverseBendingMomentumUncorrected(t.fInverseBendingMomentum);
+                       muTrack->SetThetaXUncorrected(t.fThetaX);
+                       muTrack->SetThetaYUncorrected(t.fThetaY);
+                       muTrack->SetZUncorrected(t.fZ);
+                       muTrack->SetBendingCoorUncorrected(t.fY);
+                       muTrack->SetNonBendingCoorUncorrected(t.fX);
                                
-                       muTrack.SetChi2(t.fChi2);
+                       muTrack->SetChi2(t.fChi2);
                        
                        // Fill in the track hit points.
-                       Int_t nHits = 0;
                        for (int i = 0; i < 16; i++)
                        {
                                if (not hitset[i]) continue;
@@ -462,23 +460,20 @@ int AliHLTMUONESDMaker::DoEvent(
                                AliHLTUInt16_t detElemId;
                                AliHLTMUONUtils::UnpackRecHitFlags(t.fHit[i].fFlags, chamber, detElemId);
                                
-                               AliESDMuonCluster cluster;
-                               cluster.SetUniqueID(AliMUONVCluster::BuildUniqueID(chamber, detElemId, fClusterIndex++));
-                               cluster.SetXYZ(t.fHit[i].fX, t.fHit[i].fY, t.fHit[i].fZ);
-                               cluster.SetErrXY(    // Use nominal values.
-                                               AliHLTMUONConstants::DefaultNonBendingReso(),
-                                               AliHLTMUONConstants::DefaultBendingReso()
-                                       );
-                               cluster.SetCharge(-1.);   // Indicate no total charge calculated.
-                               cluster.SetChi2(-1.);   // Indicate no fit made.
-                               muTrack.AddCluster(cluster);
-                               nHits++;
-                               muTrack.AddInMuonClusterMap(chamber);
+                               AliESDMuonCluster *cluster = event.NewMuonCluster();
+                               cluster->SetUniqueID(AliMUONVCluster::BuildUniqueID(chamber, detElemId, fClusterIndex++));
+                               cluster->SetXYZ(t.fHit[i].fX, t.fHit[i].fY, t.fHit[i].fZ);
+                               cluster->SetErrXY(    // Use nominal values.
+                                                 AliHLTMUONConstants::DefaultNonBendingReso(),
+                                                 AliHLTMUONConstants::DefaultBendingReso()
+                                                 );
+                               cluster->SetCharge(-1.);   // Indicate no total charge calculated.
+                               cluster->SetChi2(-1.);   // Indicate no fit made.
+                               muTrack->AddClusterId(cluster->GetUniqueID());
+                               muTrack->AddInMuonClusterMap(chamber);
                        }
                        
-                       FillTriggerInfo(triggerRecords, t.fTrigRec, t.fId, muTrack, nHits);
-                       muTrack.SetNHit(nHits);
-                       event.AddMuonTrack(&muTrack);
+                       FillTriggerInfo(triggerRecords, t.fTrigRec, t.fId, *muTrack, event);
                }
        }
 
@@ -489,6 +484,11 @@ int AliHLTMUONESDMaker::DoEvent(
                        kAliHLTDataTypeTObject | kAliHLTDataOriginMUON,
                        specification
                );
+               PushBack(
+                        event.GetList()->FindObject("MuonClusters"),
+                        kAliHLTDataTypeTObject | kAliHLTDataOriginMUON,
+                        specification
+                        );
        }
        if (fMakeESDDataBlock)
        {
@@ -501,7 +501,7 @@ int AliHLTMUONESDMaker::DoEvent(
 void AliHLTMUONESDMaker::FillTriggerInfo(
                const AliTriggerRecordList& triggerRecords,
                AliHLTInt32_t trigRecId, AliHLTInt32_t trackId,
-               AliESDMuonTrack& muTrack, Int_t& nHits
+               AliESDMuonTrack& muTrack, AliESDEvent& event
        )
 {
        /// Finds the trigger record with ID = 'id' and fills the output ESD track structure.
@@ -533,21 +533,20 @@ void AliHLTMUONESDMaker::FillTriggerInfo(
                        AliHLTUInt16_t detElemId;
                        AliHLTMUONUtils::UnpackRecHitFlags(trigrec->fHit[i].fFlags, chamber, detElemId);
                
-                       AliESDMuonCluster cluster;
-                       cluster.SetUniqueID(AliMUONVCluster::BuildUniqueID(chamber, detElemId, fClusterIndex++));
-                       cluster.SetXYZ(
+                       AliESDMuonCluster *cluster = event.NewMuonCluster();
+                       cluster->SetUniqueID(AliMUONVCluster::BuildUniqueID(chamber, detElemId, fClusterIndex++));
+                       cluster->SetXYZ(
                                        trigrec->fHit[i].fX,
                                        trigrec->fHit[i].fY,
                                        trigrec->fHit[i].fZ
-                               );
-                       cluster.SetErrXY(    // Use nominal values.
-                                       AliMUONConstants::TriggerNonBendingReso(),
-                                       AliMUONConstants::TriggerBendingReso()
-                               );
-                       cluster.SetCharge(-1.);   // Indicate no total charge calculated.
-                       cluster.SetChi2(-1.);   // Indicate no fit made.
-                       muTrack.AddCluster(cluster);
-                       nHits++;
+                                       );
+                       cluster->SetErrXY(    // Use nominal values.
+                                         AliMUONConstants::TriggerNonBendingReso(),
+                                         AliMUONConstants::TriggerBendingReso()
+                                         );
+                       cluster->SetCharge(-1.);   // Indicate no total charge calculated.
+                       cluster->SetChi2(-1.);   // Indicate no fit made.
+                       muTrack.AddClusterId(cluster->GetUniqueID());
                        muTrack.AddInMuonClusterMap(i+10);
                }
        }
index d8c2265..6df4f64 100644 (file)
@@ -18,6 +18,7 @@
 
 extern "C" struct AliHLTMUONTriggerRecordStruct;
 class AliESDMuonTrack;
+class AliESDEvent;
 
 /**
  * @class AliHLTMUONESDMaker
@@ -99,13 +100,12 @@ private:
         * \param [in] trackId  The track ID of the track structure where the trigger
         *                     record ID comes from.
         * \param [out] muTrack  The track structure to fill.
-        * \param [in,out] nHits  The number of hits added. Will increment this value
-        *                        for every new hit added.
+        * \param [in,out] event  The ESD event to store the new hits
         */
        void FillTriggerInfo(
                        const AliTriggerRecordList& triggerRecords,
                        AliHLTInt32_t trigRecId, AliHLTInt32_t trackId,
-                       AliESDMuonTrack& muTrack, Int_t& nHits
+                       AliESDMuonTrack& muTrack, AliESDEvent& event
                );
        
        bool fWarnForUnexpecedBlock;  /// Flag indicating if we should log a warning if we got a block of an unexpected type.
index 1adddb2..fc5cb03 100644 (file)
@@ -38,6 +38,7 @@
 #include "AliESDEvent.h"
 #include "AliESDtrack.h"
 #include "AliESDMuonTrack.h"
+#include "AliESDMuonCluster.h"
 #include "AliCDBEntry.h"
 #include "AliCDBManager.h"
 #include "AliPID.h"
@@ -775,7 +776,7 @@ int AliHLTGlobalEsdConverterComponent::ProcessBlocks(TTree* pTree, AliESDEvent*
     }
   }
 
-  // Add tracks from MUON.
+  // Add tracks and clusters from MUON.
   for( const AliHLTComponentBlockData *i= GetFirstInputBlock(kAliHLTAnyDataType | kAliHLTDataOriginMUON); i!=NULL; i=GetNextInputBlock() ){
     fBenchmark.AddInput(i->fSize);
   }
@@ -786,6 +787,7 @@ int AliHLTGlobalEsdConverterComponent::ProcessBlocks(TTree* pTree, AliESDEvent*
       )
   {
     const TClonesArray* tracklist = NULL;
+    const TClonesArray* clusterlist = NULL;
     if (obj->IsA() == AliESDEvent::Class())
     {
       const AliESDEvent* event = static_cast<const AliESDEvent*>(obj);
@@ -793,31 +795,59 @@ int AliHLTGlobalEsdConverterComponent::ProcessBlocks(TTree* pTree, AliESDEvent*
       if (event->GetList() == NULL) continue;
       tracklist = dynamic_cast<const TClonesArray*>(event->GetList()->FindObject("MuonTracks"));
       if (tracklist == NULL) continue;
+      clusterlist = dynamic_cast<const TClonesArray*>(event->GetList()->FindObject("MuonClusters"));
+      if (clusterlist == NULL) continue;
     }
     else if (obj->IsA() == TClonesArray::Class())
     {
-      tracklist = static_cast<const TClonesArray*>(obj);
-      HLTDebug("Received a MUON TClonesArray of tracks with specification: 0x%X", GetSpecification(obj));
+      if (!strcmp(obj->GetName(), "MuonTracks")) {
+       tracklist = static_cast<const TClonesArray*>(obj);
+       HLTDebug("Received a MUON TClonesArray of tracks with specification: 0x%X", GetSpecification(obj));
+      } else {
+       clusterlist = static_cast<const TClonesArray*>(obj);
+       HLTDebug("Received a MUON TClonesArray of clusters with specification: 0x%X", GetSpecification(obj));
+      }
     }
     else
     {
       // Cannot handle this object type.
       continue;
     }
-    HLTDebug("Received %d MUON tracks.", tracklist->GetEntriesFast());
-    if (tracklist->GetEntriesFast() > 0)
-    {
-      const AliESDMuonTrack* track = dynamic_cast<const AliESDMuonTrack*>(tracklist->UncheckedAt(0));
-      if (track == NULL)
+    // copy tracks
+    if (tracklist) {
+      HLTDebug("Received %d MUON tracks.", tracklist->GetEntriesFast());
+      if (tracklist->GetEntriesFast() > 0)
+      {
+       const AliESDMuonTrack* track = dynamic_cast<const AliESDMuonTrack*>(tracklist->UncheckedAt(0));
+       if (track == NULL)
+       {
+         HLTError(Form("%s from MUON does not contain AliESDMuonTrack objects.", obj->ClassName()));
+         continue;
+       }
+      }
+      for (Int_t i = 0; i < tracklist->GetEntriesFast(); ++i)
       {
-        HLTError(Form("%s from MUON does not contain AliESDMuonTrack objects.", obj->ClassName()));
-        continue;
+       AliESDMuonTrack* track = pESD->NewMuonTrack();
+       *track = *(static_cast<const AliESDMuonTrack*>(tracklist->UncheckedAt(i)));
       }
     }
-    for (Int_t i = 0; i < tracklist->GetEntriesFast(); ++i)
-    {
-      const AliESDMuonTrack* track = static_cast<const AliESDMuonTrack*>(tracklist->UncheckedAt(i));
-      pESD->AddMuonTrack(track);
+    // copy clusters
+    if (clusterlist) {
+      HLTDebug("Received %d MUON clusters.", clusterlist->GetEntriesFast());
+      if (clusterlist->GetEntriesFast() > 0)
+      {
+       const AliESDMuonCluster* cluster = dynamic_cast<const AliESDMuonCluster*>(clusterlist->UncheckedAt(0));
+       if (cluster == NULL)
+       {
+         HLTError(Form("%s from MUON does not contain AliESDMuonCluster objects.", obj->ClassName()));
+         continue;
+       }
+      }
+      for (Int_t i = 0; i < clusterlist->GetEntriesFast(); ++i)
+      {
+       AliESDMuonCluster* cluster = pESD->NewMuonCluster();
+       *cluster = *(static_cast<const AliESDMuonCluster*>(clusterlist->UncheckedAt(i)));
+      }
     }
   }
   
index 0823aa9..ac7f4ff 100644 (file)
@@ -56,9 +56,8 @@ void CreateInput(
   }
   for (int i = 0; i < numOfMuonTracks; i++)
   {
-    AliESDMuonTrack mutrack;
-    CreateTrack(mutrack, minMuonPt, maxMuonPt, (i%2==0) ? -1 : 1);
-    event.AddMuonTrack(&mutrack);
+    AliESDMuonTrack *mutrack = event.NewMuonTrack();
+    CreateTrack(*mutrack, minMuonPt, maxMuonPt, (i%2==0) ? -1 : 1);
   }
   event.Write();
   delete file;
index 3fbbd6c..80de748 100644 (file)
@@ -429,7 +429,7 @@ void AliMUONAlignmentTask::UserExec(Option_t *)
     {
 
       AliESDMuonTrack* esdTrack = lESD->GetMuonTrack(iTrack);
-      if (!esdTrack->ClustersStored()) continue;
+      if (!esdTrack->ContainTrackerData()) continue;
       if (!esdTrack->ContainTriggerData()) continue;
 
       Double_t invBenMom = esdTrack->GetInverseBendingMomentum();
index 63c73b9..87bd127 100644 (file)
@@ -45,6 +45,7 @@
 #include "AliESDMuonPad.h"
 #include "AliLog.h"
 
+#include <TROOT.h>
 #include <TClass.h>
 #include <TIterator.h>
 #include <TMath.h>
@@ -152,9 +153,12 @@ void AliMUONESDInterface::LoadEvent(AliESDEvent& esdEvent, Bool_t refit)
   // reset data members
   Reset();
   
+  // loop over ESD pads and fill the digit store
+  for (Int_t iPad = 0; iPad < esdEvent.GetNumberOfMuonPads(); iPad++)
+    Add(*(esdEvent.GetMuonPad(iPad)), *fDigits);
+  
   // loop over ESD tracks and fill the stores
-  Int_t nTracks = (Int_t) esdEvent.GetNumberOfMuonTracks(); 
-  for (Int_t iTrack = 0; iTrack <  nTracks; iTrack++) {
+  for (Int_t iTrack = 0; iTrack < esdEvent.GetNumberOfMuonTracks(); iTrack++) {
     
     // get ESD track
     AliESDMuonTrack* esdTrack = esdEvent.GetMuonTrack(iTrack);
@@ -178,15 +182,11 @@ void AliMUONESDInterface::LoadEvent(AliESDEvent& esdEvent, Bool_t refit)
     dMaps->SetOwner(kTRUE);
     fDigitMap->Add(esdTrack->GetUniqueID(), dMaps);
     
-    // loop over ESD clusters
-    Int_t nClusters = esdTrack->GetNClusters();
-    for (Int_t iCluster = 0; iCluster <  nClusters; iCluster++) {
-      
-      // get ESD cluster
-      AliESDMuonCluster *esdCluster = (AliESDMuonCluster*) esdTrack->GetClusters().UncheckedAt(iCluster);
+    // loop over clusters
+    for (Int_t iCluster = 0; iCluster < track->GetNClusters(); iCluster++) {
       
-      // get the corresponding MUON cluster
-      AliMUONVCluster* cluster = FindClusterInTrack(*track, esdCluster->GetUniqueID());
+      // get cluster
+      AliMUONVCluster* cluster = ((AliMUONTrackParam*)track->GetTrackParamAtCluster()->UncheckedAt(iCluster))->GetClusterPtr();
       
       // fill cluster map
       cMap->Add(cluster->GetUniqueID(), cluster);
@@ -194,21 +194,17 @@ void AliMUONESDInterface::LoadEvent(AliESDEvent& esdEvent, Bool_t refit)
       // prepare digit map
       AliMpExMap* dMap =new AliMpExMap;
       dMap->SetOwner(kFALSE);
-      dMaps->Add(esdCluster->GetUniqueID(), dMap);
+      dMaps->Add(cluster->GetUniqueID(), dMap);
       
-      // loop over ESD pads
-      Int_t nPads = esdCluster->GetNPads();
-      for (Int_t iPad = 0; iPad < nPads; iPad++) {
+      // loop over digits
+      for (Int_t iDigit = 0; iDigit < cluster->GetNDigits(); iDigit++) {
        
-       // get ESD pad
-       AliESDMuonPad *esdPad = (AliESDMuonPad*) esdCluster->GetPads().UncheckedAt(iPad);
-       
-       // add it to digit store
-       AliMUONVDigit* digit = Add(*esdPad, *fDigits);
+       // find the digit
+       AliMUONVDigit* digit = fDigits->FindObject(cluster->GetDigitId(iDigit));
        
        // fill digit map
-       if (digit) dMap->Add(esdPad->GetUniqueID(), digit);
-       else dMap->Add(esdPad->GetUniqueID(), fDigits->FindObject(esdPad->GetUniqueID()));
+       if (digit) dMap->Add(digit->GetUniqueID(), digit);
+       else AliError("a digit is missing");
        
       } // end of loop over pads
       
@@ -286,6 +282,17 @@ Int_t AliMUONESDInterface::GetNTriggers() const
 }
 
 //___________________________________________________________________________
+Bool_t AliMUONESDInterface::DigitsStored(UInt_t trackId) const
+{
+  /// return kTRUE if digits have been stored for all clusters of track "trackId"
+  AliMUONVCluster *cluster;
+  TIter next(CreateClusterIterator(trackId));
+  while ((cluster = static_cast<AliMUONVCluster*>(next())))
+    if (cluster->GetNDigits() == 0) return kFALSE;
+  return kTRUE;
+}
+
+//___________________________________________________________________________
 AliMUONTrack* AliMUONESDInterface::FindTrack(UInt_t trackId) const
 {
   /// return track "trackId" (0x0 if not found)
@@ -418,22 +425,6 @@ TIterator* AliMUONESDInterface::CreateLocalTriggerIterator() const
   return fTriggers ? fTriggers->CreateLocalIterator() : 0x0;
 }
 
-//___________________________________________________________________________
-AliMUONVCluster* AliMUONESDInterface::FindClusterInTrack(const AliMUONTrack& track, UInt_t clusterId) const
-{
-  /// find the cluster with the given Id into the track
-  
-  Int_t nClusters = track.GetNClusters();
-  for (Int_t iCluster = 0; iCluster < nClusters; iCluster++) {
-    
-    AliMUONVCluster* cluster = ((AliMUONTrackParam*) track.GetTrackParamAtCluster()->UncheckedAt(iCluster))->GetClusterPtr();
-    if (cluster->GetUniqueID() == clusterId) return cluster;
-    
-  }
-  
-  return 0x0;
-}
-
 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
 //                                static methods                               //
 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
@@ -486,7 +477,7 @@ AliMUONVTrackStore* AliMUONESDInterface::NewTrackStore()
     cout<<"E-AliMUONESDInterface::NewTrackStore: Unable to create store of type "<<fgTrackStoreName.Data()<<endl;
     return 0x0;
   }
-  return reinterpret_cast<AliMUONVTrackStore*>(classPtr->New());
+  return reinterpret_cast<AliMUONVTrackStore*>(gROOT->ProcessLineFast(Form("new %s()",fgTrackStoreName.Data())));
 }
 
 //_____________________________________________________________________________
@@ -498,7 +489,22 @@ AliMUONVClusterStore* AliMUONESDInterface::NewClusterStore()
     cout<<"E-AliMUONESDInterface::NewClusterStore: Unable to create store of type "<<fgClusterStoreName.Data()<<endl;
     return 0x0;
   }
-  return reinterpret_cast<AliMUONVClusterStore*>(classPtr->New());
+  return reinterpret_cast<AliMUONVClusterStore*>(gROOT->ProcessLineFast(Form("new %s()",fgClusterStoreName.Data())));
+}
+
+//_____________________________________________________________________________
+AliMUONVCluster* AliMUONESDInterface::NewCluster()
+{
+  /// Create an empty cluster of type associated to the cluster store of type fgClusterStoreName
+  TClass* classPtr = TClass::GetClass(fgClusterStoreName);
+  if (!classPtr || !classPtr->InheritsFrom("AliMUONVClusterStore")) {
+    cout<<"E-AliMUONESDInterface::NewCluster: Unable to create store of type "<<fgClusterStoreName.Data()<<endl;
+    return 0x0;
+  }
+  AliMUONVClusterStore* cStore = reinterpret_cast<AliMUONVClusterStore*>(classPtr->New());
+  AliMUONVCluster* cluster = cStore->CreateCluster(0,0,0);
+  delete cStore;
+  return cluster;
 }
 
 //_____________________________________________________________________________
@@ -510,7 +516,22 @@ AliMUONVDigitStore* AliMUONESDInterface::NewDigitStore()
     cout<<"E-AliMUONESDInterface::NewDigitStore: Unable to create store of type "<<fgDigitStoreName.Data()<<endl;
     return 0x0;
   }
-  return reinterpret_cast<AliMUONVDigitStore*>(classPtr->New());
+  return reinterpret_cast<AliMUONVDigitStore*>(gROOT->ProcessLineFast(Form("new %s()",fgDigitStoreName.Data())));
+}
+
+//_____________________________________________________________________________
+AliMUONVDigit* AliMUONESDInterface::NewDigit()
+{
+  /// Create an empty digit of type associated to the digit store of type fgDigitStoreName
+  TClass* classPtr = TClass::GetClass(fgDigitStoreName);
+  if (!classPtr || !classPtr->InheritsFrom("AliMUONVDigitStore")) {
+    cout<<"E-AliMUONESDInterface::NewDigitStore: Unable to create store of type "<<fgDigitStoreName.Data()<<endl;
+    return 0x0;
+  }
+  AliMUONVDigitStore* dStore = reinterpret_cast<AliMUONVDigitStore*>(classPtr->New());
+  AliMUONVDigit* digit = dStore->CreateDigit(0,0,0,0);
+  delete dStore;
+  return digit;
 }
 
 //_____________________________________________________________________________
@@ -522,7 +543,7 @@ AliMUONVTriggerStore* AliMUONESDInterface::NewTriggerStore()
     cout<<"E-AliMUONESDInterface::NewTriggerStore: Unable to create store of type "<<fgTriggerStoreName.Data()<<endl;
     return 0x0;
   }
-  return reinterpret_cast<AliMUONVTriggerStore*>(classPtr->New());
+  return reinterpret_cast<AliMUONVTriggerStore*>(gROOT->ProcessLineFast(Form("new %s()",fgTriggerStoreName.Data())));
 }
 
 //_____________________________________________________________________________
@@ -534,7 +555,7 @@ AliMUONVTriggerTrackStore* AliMUONESDInterface::NewTriggerTrackStore()
     cout<<"E-AliMUONESDInterface::NewTriggerTrackStore: Unable to create store of type "<<fgTriggerTrackStoreName.Data()<<endl;
     return 0x0;
   }
-  return reinterpret_cast<AliMUONVTriggerTrackStore*>(classPtr->New());
+  return reinterpret_cast<AliMUONVTriggerTrackStore*>(gROOT->ProcessLineFast(Form("new %s()",fgTriggerTrackStoreName.Data())));
 }
 
 //_________________________________________________________________________
@@ -670,6 +691,7 @@ void AliMUONESDInterface::SetParamCov(const AliMUONTrackParam& trackParam, AliES
 void AliMUONESDInterface::ESDToMUON(const AliESDMuonTrack& esdTrack, AliMUONTrack& track, Bool_t refit)
 {
   /// Transfert data from ESDMuon track to MUON track.
+  /// ESDMuon track must hold the pointer to the ESD event otherwise we cannot recover the clusters.
   /// If refit = kTRUE, the track parameters at each cluster are obtained by refitting the track
   /// or by extrapolating the parameters at the first one if the refit failed.
   /// If refit = kFALSE, only the track parameters at first cluster are valid.
@@ -711,17 +733,22 @@ void AliMUONESDInterface::ESDToMUON(const AliESDMuonTrack& esdTrack, AliMUONTrac
   GetParamCov(esdTrack, param);
   
   // create empty cluster
-  AliMUONVClusterStore* cStore = NewClusterStore();
-  if (!cStore) return;
-  AliMUONVCluster* cluster = cStore->CreateCluster(0,0,0);
+  AliMUONVCluster* cluster = NewCluster();
   
   // fill TrackParamAtCluster with track parameters at each cluster if available
-  // or with only track parameters at first (fake) cluster if not
-  if(esdTrack.ClustersStored()) {
+  Bool_t clusterFound = kFALSE;
+  if(esdTrack.GetESDEvent()) {
     
-    // loop over ESD clusters
-    AliESDMuonCluster *esdCluster = (AliESDMuonCluster*) esdTrack.GetClusters().First();
-    while (esdCluster) {
+    // loop over cluster Id
+    for (Int_t i = 0; i < esdTrack.GetNClusters(); i++) {
+      
+      // recover the ESDMuon cluster
+      AliESDMuonCluster *esdCluster = esdTrack.GetESDEvent()->FindMuonCluster(esdTrack.GetClusterId(i));
+      if (esdCluster) clusterFound = kTRUE;
+      else {
+       cout<<"E-AliMUONESDInterface::ESDToMUON: a cluster is missing in ESD"<<endl;
+       continue;
+      }
       
       // copy cluster information
       ESDToMUON(*esdCluster, *cluster);
@@ -732,11 +759,10 @@ void AliMUONESDInterface::ESDToMUON(const AliESDMuonTrack& esdTrack, AliMUONTrac
       // add common track parameters at current cluster
       track.AddTrackParamAtCluster(param, *cluster, kTRUE);
       
-      esdCluster = (AliESDMuonCluster*) esdTrack.GetClusters().After(esdCluster);
     }
     
     // refit the track to get better parameters and covariances at each cluster (temporary disable track improvement)
-    if (refit) {
+    if (clusterFound && refit) {
       
       AliMUONTrackParam *firstTrackParam = (AliMUONTrackParam*) track.GetTrackParamAtCluster()->First();
       AliMUONTrackParam paramSave(*firstTrackParam);
@@ -750,7 +776,10 @@ void AliMUONESDInterface::ESDToMUON(const AliESDMuonTrack& esdTrack, AliMUONTrac
       
     }
     
-  } else {
+  }
+  
+  // fill TrackParamAtCluster with only track parameters at first (fake) cluster if no cluster found in ESD
+  if (!clusterFound) {
     
     // get number of the first hit chamber according to the MUONClusterMap
     Int_t firstCh = 0;
@@ -770,7 +799,6 @@ void AliMUONESDInterface::ESDToMUON(const AliESDMuonTrack& esdTrack, AliMUONTrac
   track.SetMCLabel(esdTrack.GetLabel());
   
   delete cluster;
-  delete cStore;
   
 }
 
@@ -820,11 +848,7 @@ void AliMUONESDInterface::ESDToMUON(const AliESDMuonCluster& esdCluster, AliMUON
   cluster.SetChi2(esdCluster.GetChi2());
   cluster.SetMCLabel(esdCluster.GetLabel());
   
-  if (esdCluster.PadsStored()) {
-    Int_t nPads = esdCluster.GetNPads();
-    for (Int_t iPad = 0; iPad < nPads; iPad++)
-      cluster.AddDigitId(((AliESDMuonPad*)esdCluster.GetPads().UncheckedAt(iPad))->GetUniqueID());
-  }
+  cluster.SetDigitsId(esdCluster.GetNPads(), esdCluster.GetPadsId());
   
 }
 
@@ -852,13 +876,32 @@ void AliMUONESDInterface::ESDToMUON(const AliESDMuonPad& esdPad, AliMUONVDigit&
 }
 
 //_____________________________________________________________________________
-void AliMUONESDInterface::MUONToESD(const AliMUONTrack& track, AliESDMuonTrack& esdTrack, const Double_t vertex[3],
+void AliMUONESDInterface::MUONToESD(const AliMUONTrack& track, AliESDEvent& esd, const Double_t vertex[3],
                                    const AliMUONVDigitStore* digits, const AliMUONLocalTrigger* locTrg)
 {
-  /// Transfert data from MUON track to ESDMuon track
+  /// Transfert data from MUON track to ESD event (ESDTrack + ESDClusters)
   /// Incorporate the ESDPads if the digits are provided
   /// Add trigger info if the MUON track is matched with a trigger track
   
+  // transfert track info
+  AliESDMuonTrack *esdTrack = esd.NewMuonTrack();
+  MUONToESD(track, *esdTrack, vertex, locTrg);
+  
+  // transfert cluster info if any
+  for (Int_t i = 0; i < track.GetNClusters(); i++) {
+    AliMUONTrackParam *param = static_cast<AliMUONTrackParam*>(track.GetTrackParamAtCluster()->UncheckedAt(i));
+    MUONToESD(*(param->GetClusterPtr()), esd, digits);
+  }
+  
+}
+
+//_____________________________________________________________________________
+void AliMUONESDInterface::MUONToESD(const AliMUONTrack& track, AliESDMuonTrack& esdTrack,
+                                   const Double_t vertex[3], const AliMUONLocalTrigger* locTrg)
+{
+  /// Transfert data from MUON track to ESDMuon track (ESDMuon track only contains clusters'Id, not cluster themselves)
+  /// Add trigger info if the MUON track is matched with a trigger track
+  
   // empty MUON track -> produce a ghost ESDMuon track if trigger info are available otherwise produce an empty track
   if (track.GetNClusters() == 0) {
     if (locTrg) MUONToESD(*locTrg, esdTrack, track.GetUniqueID());
@@ -875,7 +918,6 @@ void AliMUONESDInterface::MUONToESD(const AliMUONTrack& track, AliESDMuonTrack&
   // set global info
   esdTrack.SetUniqueID(track.GetUniqueID());
   esdTrack.SetChi2(track.GetGlobalChi2());
-  esdTrack.SetNHit(track.GetNClusters());
   esdTrack.SetLabel(track.GetMCLabel());
   
   // set param at first cluster
@@ -901,12 +943,11 @@ void AliMUONESDInterface::MUONToESD(const AliMUONTrack& track, AliESDMuonTrack&
   SetParamAtDCA(trackParamAtDCA, esdTrack);
   
   // set muon cluster info
-  AliESDMuonCluster esdCluster;
   esdTrack.SetMuonClusterMap(0);
   while (trackParam) {
-    MUONToESD(*(trackParam->GetClusterPtr()), esdCluster, digits);
-    esdTrack.AddCluster(esdCluster);
-    esdTrack.AddInMuonClusterMap(esdCluster.GetChamberId());
+    AliMUONVCluster *cluster = trackParam->GetClusterPtr();
+    esdTrack.AddClusterId(cluster->GetUniqueID());
+    esdTrack.AddInMuonClusterMap(cluster->GetChamberId());
     trackParam = static_cast<AliMUONTrackParam*>(track.GetTrackParamAtCluster()->After(trackParam));
   }
   
@@ -940,6 +981,15 @@ void AliMUONESDInterface::MUONToESD(const AliMUONTrack& track, AliESDMuonTrack&
 }
 
 //_____________________________________________________________________________
+void AliMUONESDInterface::MUONToESD(const AliMUONLocalTrigger& locTrg, AliESDEvent& esd,
+                                   UInt_t trackId, const AliMUONTriggerTrack* triggerTrack)
+{
+  /// Add in ESD event a ghost ESDMuon track containing only informations about trigger track
+  AliESDMuonTrack *esdTrack = esd.NewMuonTrack();
+  MUONToESD(locTrg, *esdTrack, trackId, triggerTrack);
+}
+
+//_____________________________________________________________________________
 void AliMUONESDInterface::MUONToESD(const AliMUONLocalTrigger& locTrg, AliESDMuonTrack& esdTrack,
                                    UInt_t trackId, const AliMUONTriggerTrack* triggerTrack)
 {
@@ -980,38 +1030,65 @@ void AliMUONESDInterface::MUONToESD(const AliMUONLocalTrigger& locTrg, AliESDMuo
 }
 
 //_____________________________________________________________________________
-void AliMUONESDInterface::MUONToESD(const AliMUONVCluster& cluster, AliESDMuonCluster& esdCluster, const AliMUONVDigitStore* digits)
+void AliMUONESDInterface::MUONToESD(const AliMUONVCluster& cluster, AliESDEvent& esd, const AliMUONVDigitStore* digits)
 {
-  /// Transfert data from MUON cluster to ESDMuon cluster
-  /// Incorporate the ESDPads if the digits are provided
-  
-  esdCluster.Clear("C");
+  /// Transfert data from MUON cluster to ESD event if it does not already exist
+  /// Also transfert digits'Id to cluster and digits to ESD if they are provided
   
-  esdCluster.SetUniqueID(cluster.GetUniqueID());
-  esdCluster.SetXYZ(cluster.GetX(), cluster.GetY(), cluster.GetZ());
-  esdCluster.SetErrXY(cluster.GetErrX(), cluster.GetErrY());
-  esdCluster.SetCharge(cluster.GetCharge());
-  esdCluster.SetChi2(cluster.GetChi2());
-  esdCluster.SetLabel(cluster.GetMCLabel());
+  AliESDMuonCluster *esdCluster = esd.FindMuonCluster(cluster.GetUniqueID());
+  if (!esdCluster) esdCluster = esd.NewMuonCluster();
+  else if (!digits || esdCluster->GetNPads() > 0) return;
   
-  if (digits) { // transfert all data if required
+  if (digits) {
+    
+    MUONToESD(cluster, *esdCluster, kTRUE);
     
-    AliESDMuonPad esdPad;
     for (Int_t i=0; i<cluster.GetNDigits(); i++) {
       AliMUONVDigit* digit = digits->FindObject(cluster.GetDigitId(i));
       if (!digit) {
        cout<<"E-AliMUONESDInterface::MUONToESD: digit "<<cluster.GetDigitId(i)<<" not found"<<endl;
        continue;
       }
-      MUONToESD(*digit, esdPad);
-      esdCluster.AddPad(esdPad);
+      MUONToESD(*digit, esd);
     }
     
+  } else {
+    
+    MUONToESD(cluster, *esdCluster, kFALSE);
+    
   }
   
 }
 
 //_____________________________________________________________________________
+void AliMUONESDInterface::MUONToESD(const AliMUONVCluster& cluster, AliESDMuonCluster& esdCluster, Bool_t copyPadsId)
+{
+  /// Transfert data from MUON cluster to ESDMuon cluster
+  /// Also transfert digits'Is if required
+  
+  esdCluster.Clear("C");
+  
+  esdCluster.SetUniqueID(cluster.GetUniqueID());
+  esdCluster.SetXYZ(cluster.GetX(), cluster.GetY(), cluster.GetZ());
+  esdCluster.SetErrXY(cluster.GetErrX(), cluster.GetErrY());
+  esdCluster.SetCharge(cluster.GetCharge());
+  esdCluster.SetChi2(cluster.GetChi2());
+  esdCluster.SetLabel(cluster.GetMCLabel());
+  
+  if (copyPadsId) esdCluster.SetPadsId(cluster.GetNDigits(), cluster.GetDigitsId());
+  
+}
+
+//_____________________________________________________________________________
+void AliMUONESDInterface::MUONToESD(const AliMUONVDigit& digit, AliESDEvent& esd)
+{
+  /// Transfert data from MUON digit to ESD event if it does not already exist
+  if (esd.FindMuonPad(digit.GetUniqueID())) return;
+  AliESDMuonPad *esdPad = esd.NewMuonPad();
+  MUONToESD(digit, *esdPad);
+}
+
+//_____________________________________________________________________________
 void AliMUONESDInterface::MUONToESD(const AliMUONVDigit& digit, AliESDMuonPad& esdPad)
 {
   /// Transfert data from MUON digit to ESDMuon pad
index c848406..43d7024 100644 (file)
@@ -64,6 +64,9 @@ public: // methods to play with internal objects
   Int_t GetNDigitsInCluster(UInt_t clusterId) const;
   Int_t GetNTriggers() const;
   
+  // Check that all digits have been stored for a given track
+  Bool_t DigitsStored(UInt_t trackId) const;
+  
   // Find internal MUON objects
   AliMUONTrack*        FindTrack(UInt_t trackId) const;
   AliMUONVCluster*     FindCluster(UInt_t clusterId) const;
@@ -101,7 +104,9 @@ public: // static methods
   // Create empty stores (use the version defined in this interface)
   static AliMUONVTrackStore* NewTrackStore();
   static AliMUONVClusterStore* NewClusterStore();
+  static AliMUONVCluster* NewCluster();
   static AliMUONVDigitStore* NewDigitStore();
+  static AliMUONVDigit* NewDigit();
   static AliMUONVTriggerStore* NewTriggerStore();
   static AliMUONVTriggerTrackStore* NewTriggerTrackStore();
   
@@ -124,11 +129,17 @@ public: // static methods
   static void ESDToMUON(const AliESDMuonPad& esdPad, AliMUONVDigit& digit);
   
   // MUON objects --> ESDMuon objects conversion
-  static void MUONToESD(const AliMUONTrack& track, AliESDMuonTrack& esdTrack, const Double_t vertex[3],
+  static void MUONToESD(const AliMUONTrack& track, AliESDEvent& esd, const Double_t vertex[3],
                        const AliMUONVDigitStore* digits = 0x0, const AliMUONLocalTrigger* locTrg = 0x0);
+  static void MUONToESD(const AliMUONTrack& track, AliESDMuonTrack& esdTrack, const Double_t vertex[3],
+                       const AliMUONLocalTrigger* locTrg = 0x0);
+  static void MUONToESD(const AliMUONLocalTrigger& locTrg, AliESDEvent& esd, UInt_t trackId,
+                       const AliMUONTriggerTrack* triggerTrack = 0x0);
   static void MUONToESD(const AliMUONLocalTrigger& locTrg, AliESDMuonTrack& esdTrack, UInt_t trackId,
                        const AliMUONTriggerTrack* triggerTrack = 0x0);
-  static void MUONToESD(const AliMUONVCluster& cluster, AliESDMuonCluster& esdCluster, const AliMUONVDigitStore* digits = 0x0);
+  static void MUONToESD(const AliMUONVCluster& cluster, AliESDEvent& esd, const AliMUONVDigitStore* digits = 0x0);
+  static void MUONToESD(const AliMUONVCluster& cluster, AliESDMuonCluster& esdCluster, Bool_t copyPadsId = kFALSE);
+  static void MUONToESD(const AliMUONVDigit& digit, AliESDEvent& esd);
   static void MUONToESD(const AliMUONVDigit& digit, AliESDMuonPad& esdPad);
   
   // Add ESD object into the corresponding MUON store
@@ -148,7 +159,6 @@ protected:
 private:
   
   void Reset();
-  AliMUONVCluster* FindClusterInTrack(const AliMUONTrack& track, UInt_t clusterId) const;
   
   
 private:
index aca1be5..3afe04d 100644 (file)
@@ -67,6 +67,8 @@ class AliMUONRawClusterV2 : public AliMUONVCluster {
   virtual Int_t    GetNDigits() const {return fNDigits;}
            /// Return Id of digits i
   virtual UInt_t   GetDigitId(Int_t i) const {return (i < fNDigits && fDigitsId) ? fDigitsId[i] : 0;}
+           /// Return the array of digits'id
+  virtual const UInt_t* GetDigitsId() const {return fDigitsId;}
   
            /// Set chi2 of cluster
   virtual void     SetChi2( Double_t chi2) {fChi2 = chi2;}
index f9a8210..36c6fc6 100644 (file)
@@ -310,14 +310,6 @@ void AliMUONReAlignTask::Exec(Option_t *)
     // Find the corresponding re-fitted MUON track
     AliMUONTrack* newTrack = (AliMUONTrack*) newTrackStore->FindObject(esdTrack->GetUniqueID());
     
-//     // replace the content of the current ESD track or remove it if the refitting has failed
-//     if (newTrack) {
-//       Double_t vertex[3] = {esdTrack->GetNonBendingCoor(), esdTrack->GetBendingCoor(), esdTrack->GetZ()};
-//       AliMUONESDInterface::MUONToESD(*newTrack, *esdTrack, vertex, esdInterface.GetDigits());
-//       } else {
-//       esdTracks->Remove(esdTrack);
-//       }
-      
     // print initial and re-fitted track parameters at first cluster if any
     if (fPrintLevel>0) {
       cout<<"            ----------------track #"<<iTrack+1<<"----------------"<<endl;
index aa8e2dc..405a88a 100644 (file)
@@ -429,9 +429,7 @@ void AliMUONRecoCheck::MakeTrackRefs()
   TParticle* particle;
   TClonesArray* trackRefs;
   Int_t nTrackRef = fMCEventHandler->MCEvent()->GetNumberOfTracks();
-  AliMUONVClusterStore* cStore = AliMUONESDInterface::NewClusterStore();
-  if (!cStore) return;
-  AliMUONVCluster* hit = cStore->CreateCluster(0,0,0);
+  AliMUONVCluster* hit = AliMUONESDInterface::NewCluster();
   
   // loop over simulated tracks
   for (Int_t iTrackRef  = 0; iTrackRef < nTrackRef; ++iTrackRef) {
@@ -539,7 +537,6 @@ void AliMUONRecoCheck::MakeTrackRefs()
   CleanMuonTrackRef(tmpTrackRefStore);
   
   delete hit;
-  delete cStore;
   delete tmpTrackRefStore;
 }
 
@@ -669,9 +666,7 @@ void AliMUONRecoCheck::CleanMuonTrackRef(const AliMUONVTrackStore *tmpTrackRefSt
   Double_t maxGasGap = 1.; // cm 
   Double_t x, y, z, pX, pY, pZ, x1, y1, z1, pX1, pY1, pZ1, z2;
   Double_t bendingSlope,nonBendingSlope,inverseBendingMomentum;
-  AliMUONVClusterStore* cStore = AliMUONESDInterface::NewClusterStore();
-  if (!cStore) return;
-  AliMUONVCluster* hit = cStore->CreateCluster(0,0,0);
+  AliMUONVCluster* hit = AliMUONESDInterface::NewCluster();
   
   // create iterator
   TIter next(tmpTrackRefStore->CreateIterator());
@@ -771,7 +766,6 @@ void AliMUONRecoCheck::CleanMuonTrackRef(const AliMUONVTrackStore *tmpTrackRefSt
   }
   
   delete hit;
-  delete cStore;
 }
 
 //_____________________________________________________________________________
index 035f1d1..79a4aa3 100644 (file)
@@ -69,7 +69,8 @@ AliMUONRefitter::AliMUONRefitter(const AliMUONRecoParam* recoParam)
   fkESDInterface(0x0),
   fGeometryTransformer(0x0),
   fClusterServer(0x0),
-  fTracker(0x0)
+  fTracker(0x0),
+  nextClusterIndex(0)
 {
   /// Default constructor
   CreateGeometryTransformer();
@@ -216,6 +217,12 @@ AliMUONVClusterStore* AliMUONRefitter::ReClusterize(UInt_t trackId, UInt_t clust
   fClusterServer->UseDigits(next,fkESDInterface->GetDigits());
   fClusterServer->Clusterize(cluster->GetChamberId(),*clusterStore,AliMpArea(),fkRecoParam);
   
+  // set the uniqueID of the new clusters
+  TIter nextCl(clusterStore->CreateIterator());
+  AliMUONVCluster* newCluster = 0x0;
+  while ((newCluster = static_cast<AliMUONVCluster*>(nextCl())))
+    newCluster->SetUniqueID(AliMUONVCluster::BuildUniqueID(cluster->GetChamberId(), cluster->GetDetElemId(), nextClusterIndex++));
+  
   return clusterStore;
 }
 
@@ -250,6 +257,12 @@ AliMUONVClusterStore* AliMUONRefitter::ReClusterize(UInt_t clusterId)
   fClusterServer->UseDigits(next,fkESDInterface->GetDigits());
   fClusterServer->Clusterize(cluster->GetChamberId(),*clusterStore,AliMpArea(),fkRecoParam);
   
+  // set the uniqueID of the new clusters
+  TIter nextCl(clusterStore->CreateIterator());
+  AliMUONVCluster* newCluster = 0x0;
+  while ((newCluster = static_cast<AliMUONVCluster*>(nextCl())))
+    newCluster->SetUniqueID(AliMUONVCluster::BuildUniqueID(cluster->GetChamberId(), cluster->GetDetElemId(), nextClusterIndex++));
+  
   return clusterStore;
 }
 
@@ -280,7 +293,7 @@ AliMUONTrack* AliMUONRefitter::RetrackFromDigits(const AliMUONTrack& track)
   
   // check if digits exist
   UInt_t trackId = track.GetUniqueID();
-  if (fkESDInterface->GetNDigits(trackId) == 0) {
+  if (!fkESDInterface->DigitsStored(trackId)) {
     AliError(Form("no digit attached to track #%d",trackId));
     return 0x0;
   }
@@ -318,6 +331,12 @@ AliMUONTrack* AliMUONRefitter::RetrackFromDigits(const AliMUONTrack& track)
       continue;
     }
     
+    // set the uniqueID of the new clusters
+    TIter nextCl(newClusterStore->CreateIterator());
+    AliMUONVCluster* newCluster = 0x0;
+    while ((newCluster = static_cast<AliMUONVCluster*>(nextCl())))
+      newCluster->SetUniqueID(AliMUONVCluster::BuildUniqueID(cluster->GetChamberId(), cluster->GetDetElemId(), nextClusterIndex++));
+    
     // add the new cluster(s) to the tracks
     if (!AddClusterToTracks(*newClusterStore, *newTrackStore)) {
       delete newClusterStore;
index 2cbab77..0498937 100644 (file)
@@ -46,6 +46,8 @@ public:
   AliMUONVClusterStore* ReClusterize(UInt_t trackId, UInt_t clusterId);
   AliMUONVClusterStore* ReClusterize(UInt_t clusterId);
   
+  // set the first index of clusters produced by this refitter (to build its uniqueID)
+  void SetFirstClusterIndex(Int_t index) {nextClusterIndex = (index >= 0) ? index : 0;}
   
 protected:
   
@@ -70,6 +72,7 @@ private:
   AliMUONVClusterServer*      fClusterServer;       ///< clusterizer (owner)
   AliMUONVTrackReconstructor* fTracker;             ///< tracker (owner)
   
+  Int_t nextClusterIndex; ///< Index of the next cluster produced by this refitter (to build its uniqueID)
   
   ClassDef(AliMUONRefitter,0)
 };
index d88820b..a94261e 100644 (file)
@@ -16,7 +16,6 @@
 #  include "AliMUONVClusterServer.h"
 #endif
 
-class AliESDMuonPad;
 class AliMUONGeometryTransformer;
 class AliMUONTriggerTrackToTrackerClusters;
 class AliMUONVClusterFinder;
index 462d4e3..7af6083 100644 (file)
@@ -288,7 +288,6 @@ void AliMUONTracker::FillESD(const AliMUONVTrackStore& trackStore, AliESDEvent*
   // fill ESD event including all info in ESD cluster if required and only for the given fraction of events
   AliMUONTrack* track;
   AliMUONLocalTrigger* locTrg;
-  AliESDMuonTrack esdTrack;
   TIter next(trackStore.CreateIterator());
   if (GetRecoParam()->SaveFullClusterInESD() && 
       gRandom->Uniform(100.) <= GetRecoParam()->GetPercentOfFullClusterInESD()) {
@@ -297,10 +296,9 @@ void AliMUONTracker::FillESD(const AliMUONVTrackStore& trackStore, AliESDEvent*
       
       if (track->GetMatchTrigger() > 0) {
        locTrg = static_cast<AliMUONLocalTrigger*>(fTriggerStore->FindLocal(track->LoCircuit()));
-       AliMUONESDInterface::MUONToESD(*track, esdTrack, vertex, &fkDigitStore, locTrg);
-      } else AliMUONESDInterface::MUONToESD(*track, esdTrack, vertex, &fkDigitStore);
+       AliMUONESDInterface::MUONToESD(*track, *esd, vertex, &fkDigitStore, locTrg);
+      } else AliMUONESDInterface::MUONToESD(*track, *esd, vertex, &fkDigitStore);
       
-      esd->AddMuonTrack(&esdTrack);
     }
     
   } else {
@@ -309,10 +307,9 @@ void AliMUONTracker::FillESD(const AliMUONVTrackStore& trackStore, AliESDEvent*
       
       if (track->GetMatchTrigger() > 0) {
        locTrg = static_cast<AliMUONLocalTrigger*>(fTriggerStore->FindLocal(track->LoCircuit()));
-       AliMUONESDInterface::MUONToESD(*track, esdTrack, vertex, 0x0, locTrg);
-      } else AliMUONESDInterface::MUONToESD(*track, esdTrack, vertex);
+       AliMUONESDInterface::MUONToESD(*track, *esd, vertex, 0x0, locTrg);
+      } else AliMUONESDInterface::MUONToESD(*track, *esd, vertex);
       
-      esd->AddMuonTrack(&esdTrack);
     }
     
   }
@@ -334,9 +331,8 @@ void AliMUONTracker::FillESD(const AliMUONVTrackStore& trackStore, AliESDEvent*
     }
     if (matched) continue;
 
-    AliMUONESDInterface::MUONToESD(*locTrg, esdTrack, ghostId, triggerTrack);
+    AliMUONESDInterface::MUONToESD(*locTrg, *esd, ghostId, triggerTrack);
     
-    esd->AddMuonTrack(&esdTrack);
     ghostId -= 1;
   }
   
index b86a5af..6107810 100644 (file)
@@ -71,6 +71,8 @@ class AliMUONVCluster : public TObject {
   virtual Int_t    GetNDigits() const = 0;
            /// Return Id of digits i
   virtual UInt_t   GetDigitId(Int_t i) const = 0;
+           /// Return the array of digits'id
+  virtual const UInt_t* GetDigitsId() const {return 0x0;}
   
            /// Set chi2 of cluster
   virtual void     SetChi2(Double_t chi2) = 0;
index 862b4f7..025907f 100644 (file)
@@ -216,7 +216,7 @@ void MUONAlignment(Int_t nEvents = 100000, char* geoFilename = "geometry.root",
       if (!event%100) cout << " there are " << nTracks << " tracks in event " << event << endl;
       for (Int_t iTrack = 0; iTrack < nTracks; iTrack++) {
        AliESDMuonTrack* esdTrack = esdEvent->GetMuonTrack(iTrack);
-       if (!esdTrack->ClustersStored()) continue;
+       if (!esdTrack->ContainTrackerData()) continue;
        Double_t invBenMom = esdTrack->GetInverseBendingMomentum();
        fInvBenMom->Fill(invBenMom);
        fBenMom->Fill(1./invBenMom);
index 69d299d..7b94be6 100644 (file)
@@ -66,14 +66,19 @@ void MUONRefit(Int_t nevents = -1, const char* esdFileNameIn = "AliESDs.root", c
   TFile* esdFile = TFile::Open(esdFileNameIn);
   TTree* esdTree = GetESDTree(esdFile);
   
+  // connect ESD event to the ESD tree
+  AliESDEvent* esd = new AliESDEvent();
+  esd->ReadFromTree(esdTree);
+  
   // create the ESD output file and tree
   TFile* newESDFile = TFile::Open(esdFileNameOut, "RECREATE");
   newESDFile->SetCompressionLevel(2);
-  TTree* newESDTree = esdTree->CloneTree(0);
   
-  // connect ESD event to the ESD tree
-  AliESDEvent* esd = new AliESDEvent();
-  esd->ReadFromTree(esdTree);
+  // connect ESD event to the ESD tree (recreate track branch for backward compatibility)
+  esdTree->SetBranchStatus("*MuonTracks*",0);
+  TTree* newESDTree = esdTree->CloneTree(0);
+  esdTree->SetBranchStatus("*MuonTracks*",1);
+  esd->WriteToTree(newESDTree);
   
   // get run number
   if (esdTree->GetEvent(0) <= 0) {
@@ -131,7 +136,11 @@ void MUONRefit(Int_t nevents = -1, const char* esdFileNameIn = "AliESDs.root", c
     // load the current event
     esdInterface.LoadEvent(*esd, kFALSE);
     
-    // loop over digit to modify their charge
+    // remove digits and clusters from ESD
+    esd->FindListObject("MuonClusters")->Clear("C");
+    esd->FindListObject("MuonPads")->Clear("C");
+    
+    // loop over digits to modify their charge
     AliMUONVDigit *digit;
     TIter next(esdInterface.CreateDigitIterator());
     while ((digit = static_cast<AliMUONVDigit*>(next()))) {
@@ -140,6 +149,7 @@ void MUONRefit(Int_t nevents = -1, const char* esdFileNameIn = "AliESDs.root", c
     }
     
     // refit the tracks from digits
+    refitter.SetFirstClusterIndex(0);
     AliMUONVTrackStore* newTrackStore = refitter.ReconstructFromDigits();
     
     //----------------------------------------------//
@@ -162,12 +172,19 @@ void MUONRefit(Int_t nevents = -1, const char* esdFileNameIn = "AliESDs.root", c
       AliMUONTrack* newTrack = (AliMUONTrack*) newTrackStore->FindObject(esdTrack->GetUniqueID());
       
       // replace the content of the current ESD track or remove it if the refitting has failed
-      if (newTrack) {
+      if (newTrack && (!recoParam->ImproveTracks() || newTrack->IsImproved())) {
+       
+       // fill the track info
        Double_t vertex[3] = {esdTrack->GetNonBendingCoor(), esdTrack->GetBendingCoor(), esdTrack->GetZ()};
-       AliMUONESDInterface::MUONToESD(*newTrack, *esdTrack, vertex, esdInterface.GetDigits());
-      } else {
-       esdTracks->Remove(esdTrack);
-      }
+       AliMUONESDInterface::MUONToESD(*newTrack, *esdTrack, vertex);
+       
+       // add the clusters (and the digits if previously there)
+       for (Int_t i = 0; i < newTrack->GetNClusters(); i++) {
+         AliMUONTrackParam *param = static_cast<AliMUONTrackParam*>(newTrack->GetTrackParamAtCluster()->UncheckedAt(i));
+         AliMUONESDInterface::MUONToESD(*(param->GetClusterPtr()), *esd, esdInterface.GetDigits());
+       }
+       
+      } else esdTracks->Remove(esdTrack);
       
       // print initial and re-fitted track parameters at first cluster if any
       if (printLevel>0) {
index 60686a5..9379090 100644 (file)
@@ -224,7 +224,7 @@ The AliESDMuonTrack objects contain:
 - Tracker track parameters at first cluster
 - Tracker track parameter covariances at first cluster
 - Tracker track global informations (track ID, chi2, number of clusters, cluster map, MC label if any)
-- TClonesArray of associated clusters stored in AliESDMuonCluster objects
+- Array of Ids of associated clusters (clusters are stored in a separate TClonesArray in ESD)
 - Trigger track informations (local trigger decision, strip pattern, hit pattern, ...)
 - Chi2 of tracker/trigger track matching
 
@@ -235,7 +235,7 @@ The AliESDMuonCluster objects contain:
 - Charge
 - Chi2
 - MC label if any
-- TClonesArray of associated pads stored in AliESDMuonPad objects for a given fraction of events
+- Array of IDs of associated pads for a given fraction of events (pads are stored in a separate TClonesArray in ESD)
 
 The AliESDMuonPad objects contain:
 - Digit ID providing information about the location of the digit (DE ID, Manu ID, Manu channel and cathode)
index 51ba240..ce4a92c 100644 (file)
@@ -436,7 +436,7 @@ void AliAnalysisMuMuFromESD::FillHistosForTrack(const char* physics,
 void AliAnalysisMuMuFromESD::FillHistos(const char* physics, 
                                         const char* triggerClassName, 
                                         const char* centrality,
-                                        const AliESDEvent& esd)
+                                        AliESDEvent& esd)
 {
   /// Fill histograms for /physics/triggerClassName/centrality
   
index 56910f3..2bfee09 100644 (file)
@@ -47,7 +47,7 @@ private:
   
   void FillHistosForTrack(const char* physics, const char* triggerClassName, const char* centrality, const AliESDMuonTrack& track, const char* runNumber);
   
-  void FillHistos(const char* physics, const char* triggerClassName, const char* centrality, const AliESDEvent& esd);
+  void FillHistos(const char* physics, const char* triggerClassName, const char* centrality, AliESDEvent& esd);
 
   Double_t CorrectedDCA(const AliESDMuonTrack& track) const;
 
index cab2039..787daff 100644 (file)
@@ -840,7 +840,7 @@ void AliAnalysisTaskLinkToMC::CalculateTrackCompatibility(
        
        for (Int_t i = 0; i < esdTrack->GetNClusters(); i++)
        {
-               AliESDMuonCluster* cluster = static_cast<AliESDMuonCluster*>( esdTrack->GetClusters()[i] );
+               AliESDMuonCluster* cluster = esdTrack->GetESDEvent()->FindMuonCluster(esdTrack->GetClusterId(i));
                Double_t varX = cluster->GetErrX2();
                Double_t varY = cluster->GetErrY2();
                // If the variance is zero then use the default one or just 1
index fcbb0c5..1e76d44 100644 (file)
@@ -17,6 +17,7 @@
 
 // ROOT includes
 #include <TString.h>
+#include <TList.h>
 #include <TGeoManager.h>
 
 // STEER includes
 #include "AliMUONESDInterface.h"
 #include "AliMUONRefitter.h"
 #include "AliMUONTrack.h"
+#include "AliMUONTrackParam.h"
 #include "AliMUONVCluster.h"
 #include "AliMUONVTrackStore.h"
+#include "AliMUONLocalTrigger.h"
 #include "AliMUONGeometryTransformer.h"
 
 #ifndef SafeDelete
@@ -115,9 +118,16 @@ void AliAnalysisTaskMuonRefit::UserExec(Option_t *)
   Int_t nTracks = (Int_t)esd->GetNumberOfMuonTracks();
   if (nTracks < 1) return;
   
+  TList newGhosts;
+  newGhosts.SetOwner(kFALSE);
+  UInt_t firstGhostId = 0xFFFFFFFF - 1;
+  
   // load the current event
   fESDInterface->LoadEvent(*esd, kFALSE);
   
+  // remove clusters from ESD (keep digits as they will not change, just eventually not used anymore)
+  esd->FindListObject("MuonClusters")->Clear("C");
+  
   // modify clusters
   AliMUONVCluster* cluster = 0x0;
   TIter nextCluster(fESDInterface->CreateClusterIterator());
@@ -134,33 +144,51 @@ void AliAnalysisTaskMuonRefit::UserExec(Option_t *)
     AliESDMuonTrack* esdTrack = (AliESDMuonTrack*) esdTracks->UncheckedAt(iTrack);
     
     // skip ghost tracks (leave them unchanged)
-    if (!esdTrack->ContainTrackerData()) continue;
+    if (!esdTrack->ContainTrackerData()) {
+      if (esdTrack->GetUniqueID() <= firstGhostId) firstGhostId = esdTrack->GetUniqueID()-1;
+      continue;
+    }
     
     // Find the corresponding re-fitted MUON track
     AliMUONTrack* newTrack = (AliMUONTrack*) newTrackStore->FindObject(esdTrack->GetUniqueID());
     
+    // Find the corresponding locaTrigger if any
+    AliMUONLocalTrigger *locTrg = (esdTrack->ContainTriggerData()) ? fESDInterface->FindLocalTrigger(esdTrack->LoCircuit()) : 0x0;
+    if (locTrg && locTrg->IsNull()) locTrg = 0x0;
+    
     // replace the content of the current ESD track or remove it
     if (newTrack && (!fImproveTracks || newTrack->IsImproved())) {
-      Double_t vertex[3] = {esdTrack->GetNonBendingCoor(), esdTrack->GetBendingCoor(), esdTrack->GetZ()};
-      AliMUONESDInterface::MUONToESD(*newTrack, *esdTrack, vertex, fESDInterface->GetDigits());
       
       // eventually remove the trigger part if matching chi2 do not pass the new cut
-      if (newTrack->GetChi2MatchTrigger() > fSigmaCutForTrigger*fSigmaCutForTrigger) {
-       esdTrack->SetLocalTrigger(0);
-       esdTrack->SetChi2MatchTrigger(0.);
-       esdTrack->SetHitsPatternInTrigCh(0);
-       esdTrack->SetTriggerX1Pattern(0);
-       esdTrack->SetTriggerY1Pattern(0);
-       esdTrack->SetTriggerX2Pattern(0);
-       esdTrack->SetTriggerY2Pattern(0);
-       esdTrack->SetTriggerX3Pattern(0);
-       esdTrack->SetTriggerY3Pattern(0);
-       esdTrack->SetTriggerX4Pattern(0);
-       esdTrack->SetTriggerY4Pattern(0);
+      if (locTrg && newTrack->GetChi2MatchTrigger() > fSigmaCutForTrigger*fSigmaCutForTrigger) {
+       newTrack->SetMatchTrigger(0);
+       newTrack->SetLocalTrigger(0,0,0,0,0,0,0);
+       newTrack->SetChi2MatchTrigger(0.);
+       newTrack->SetHitsPatternInTrigCh(0);
+       newGhosts.AddLast(locTrg);
+       locTrg = 0x0;
+      }
+      
+      // fill the track info
+      Double_t vertex[3] = {esdTrack->GetNonBendingCoor(), esdTrack->GetBendingCoor(), esdTrack->GetZ()};
+      AliMUONESDInterface::MUONToESD(*newTrack, *esdTrack, vertex, locTrg);
+      
+      // add the clusters if not already there
+      for (Int_t i = 0; i < newTrack->GetNClusters(); i++) {
+       AliMUONVCluster *cl = static_cast<AliMUONTrackParam*>(newTrack->GetTrackParamAtCluster()->UncheckedAt(i))->GetClusterPtr();
+       if (esd->FindMuonCluster(cl->GetUniqueID())) continue;
+       AliESDMuonCluster *esdCl = esd->NewMuonCluster();
+       AliMUONESDInterface::MUONToESD(*cl, *esdCl, kTRUE);
       }
       
     } else {
+      
+      // keep the trigger part if any
+      if (locTrg) newGhosts.AddLast(locTrg);
+      
+      // remove the track
       esdTracks->Remove(esdTrack);
+      
     }
     
   }
@@ -171,6 +199,19 @@ void AliAnalysisTaskMuonRefit::UserExec(Option_t *)
   // compress the array of ESD tracks
   esdTracks->Compress();
   
+  // add new ghosts if not already there
+  TIter nextGhost(&newGhosts);
+  AliMUONLocalTrigger *locTrg = 0x0;
+  while ((locTrg = static_cast<AliMUONLocalTrigger*>(nextGhost()))) {
+    Bool_t alreadyThere = kFALSE;
+    for (Int_t iTrack = 0; iTrack < esdTracks->GetEntriesFast(); iTrack++) {
+      AliESDMuonTrack* esdTrack = (AliESDMuonTrack*) esdTracks->UncheckedAt(iTrack);
+      alreadyThere = (esdTrack->LoCircuit() == locTrg->LoCircuit());
+      if (alreadyThere) break;
+    }
+    if (!alreadyThere) AliMUONESDInterface::MUONToESD(*locTrg, *esd, firstGhostId--);
+  }
+  
 }
 
 //________________________________________________________________________
index 066bc91..c33f9df 100644 (file)
@@ -38,7 +38,7 @@ string ( REPLACE ".cxx" ".h" HDRS "${SRCS}" )
 set ( DHDR  PWGPPMUONliteLinkDef.h)
 
 set ( EINCLUDE
-  MUON
+  PWG/muon
   PWGPP/MUON/lite
   ANALYSIS
   ANALYSISalice
index 58b808f..6d857b8 100644 (file)
@@ -54,8 +54,6 @@
 #include "AliMUONPainterDataRegistry.h"
 #include "AliMUONTrackerDataWrapper.h"
 
-#include "AddTaskPhysicsSelection.C"
-#include "AddTaskCentrality.C"
 #include "AddTaskMuonResolution.C"
 
 #endif
@@ -272,25 +270,24 @@ AliAnalysisTaskMuonResolution* CreateAnalysisTrain(Int_t mode, Int_t iStep, Bool
   AliESDInputHandler* esdH = new AliESDInputHandler();
   esdH->SetReadFriends(kFALSE);
   esdH->SetInactiveBranches("*");
-  esdH->SetActiveBranches("MuonTracks AliESDRun. AliESDHeader. AliMultiplicity. AliESDFMD. AliESDVZERO. SPDVertex. PrimaryVertex. AliESDZDC.");
+  esdH->SetActiveBranches("MuonTracks MuonClusters MuonPads AliESDRun. AliESDHeader. AliMultiplicity. AliESDFMD. AliESDVZERO. SPDVertex. PrimaryVertex. AliESDZDC.");
   mgr->SetInputEventHandler(esdH);
   
   // event selection
   if (selectPhysics) {
-    AliPhysicsSelectionTask* physicsSelection = AddTaskPhysicsSelection();
-    if (!physicsSelection) {
+    gROOT->LoadMacro("$ALICE_ROOT/ANALYSIS/macros/AddTaskPhysicsSelection.C");
+    if (!gROOT->ProcessLineFast("AddTaskPhysicsSelection()")) {
       Error("CreateAnalysisTrain","AliPhysicsSelectionTask not created!");
       return 0x0;
     }
   }
   
   // centrality selection
-  AliCentralitySelectionTask* centralityTask = AddTaskCentrality();
-  if (!centralityTask) {
+  gROOT->LoadMacro("$ALICE_ROOT/ANALYSIS/macros/AddTaskCentrality.C");
+  if (!gROOT->ProcessLineFast("AddTaskCentrality()")) {
     Error("CreateAnalysisTrain","AliCentralitySelectionTask not created!");
     return 0x0;
   }
-  centralityTask->SetPass(1);
   
   // Muon Resolution analysis
   TString outputFileName = Form("chamberResolution_step%d.root", iStep);
@@ -300,8 +297,8 @@ AliAnalysisTaskMuonResolution* CreateAnalysisTrain(Int_t mode, Int_t iStep, Bool
     Error("CreateAnalysisTrain","AliAnalysisTaskMuonResolution not created!");
     return 0x0;
   }
-  //if (mode == kLocal) muonResolution->SetDefaultStorage("local://$ALICE_ROOT/OCDB");
-  muonResolution->SetDefaultStorage("alien://folder=/alice/data/2011/OCDB");
+  if (mode == kLocal) muonResolution->SetDefaultStorage("local://$ALICE_ROOT/OCDB");
+  else muonResolution->SetDefaultStorage("alien://folder=/alice/data/2011/OCDB");
   if (mode != kProof) muonResolution->ShowProgressBar();
   muonResolution->PrintClusterRes(kTRUE, kTRUE);
   muonResolution->SetStartingResolution(clusterResNB, clusterResB);
index 027b785..1a1eb71 100644 (file)
@@ -60,11 +60,11 @@ void RunMuonResolution(TString smode = "local", TString inputFileName = "AliESDs
   /// - nevents = maximum number of processed events
   
   // Load libraries locally
-  TString extraLibs = "RAWDatabase:CDB:STEER:MUONcore:MUONmapping:MUONcalib:MUONgeometry:MUONtrigger:MUONraw:MUONbase:MUONrec:CORRFW:PWG3base:PWG3muondep";
+  TString extraLibs = "RAWDatabase:CDB:STEER:MUONcore:MUONmapping:MUONcalib:MUONgeometry:MUONtrigger:MUONraw:MUONbase:MUONrec:CORRFW:PWGPPMUONdep";
   LoadAlirootLocally(extraLibs);
   
   // compile analysis macro locally
-  gROOT->LoadMacro("$ALICE_ROOT/PWG3/muondep/MuonResolution.C++g");
+  gROOT->LoadMacro("$ALICE_ROOT/PWGPP/MUON/dep/MuonResolution.C++g");
   MuonResolution(smode, inputFileName, alirootVersion, nSteps, selectPhysics, selectTrigger, matchTrig,
                 applyAccCut, minMomentum, correctForSystematics, extrapMode, nevents, extraLibs);
   
index fccdbd4..5f44911 100644 (file)
@@ -535,11 +535,10 @@ void AliAnalysisTaskMuonQA::UserExec(Option_t *)
     for (Int_t ich=0; ich<10; ich++) if (esdTrack->IsInMuonClusterMap(ich)) nChamberHit++;
     ((TH1F*)fList->UncheckedAt(kNChamberHitPerTrack))->Fill(nChamberHit);
     
-    // what follows concern clusters
-    if(!esdTrack->ClustersStored()) continue;
-    
-    AliESDMuonCluster *esdCluster = (AliESDMuonCluster*) esdTrack->GetClusters().First();
-    while (esdCluster) {
+    // loop over clusters
+    for (Int_t icl=0; icl<esdTrack->GetNClusters(); icl++) {
+      
+      AliESDMuonCluster* esdCluster = esdTrack->GetESDEvent()->FindMuonCluster(esdTrack->GetClusterId(icl));
       
       Int_t chId = esdCluster->GetChamberId();
       Int_t deId = esdCluster->GetDetElemId();
@@ -557,7 +556,6 @@ void AliAnalysisTaskMuonQA::UserExec(Option_t *)
        ((TH1F*)fListExpert->UncheckedAt(kClusterSizePerDE))->Fill(deId, esdCluster->GetNPads());
       }
       
-      esdCluster = (AliESDMuonCluster*) esdTrack->GetClusters().After(esdCluster);
     }
     
   }
index e4d2e5f..5fce701 100644 (file)
@@ -31,10 +31,12 @@ void RunMuonQA(TString inputFileName = "AliESDs.root", Bool_t selectPhysics = kT
   }
   
   // Load common libraries
-  gSystem->Load("libTree");
-  gSystem->Load("libGeom");
   gSystem->Load("libVMC");
-  gSystem->Load("libPhysics");
+  gSystem->Load("libTree.so");
+  gSystem->Load("libPhysics.so");
+  gSystem->Load("libMinuit.so");
+  gSystem->Load("libXMLParser.so");
+  gSystem->Load("libGui.so");
   gSystem->Load("libSTEERBase");
   gSystem->Load("libESD");
   gSystem->Load("libAOD");
@@ -42,6 +44,7 @@ void RunMuonQA(TString inputFileName = "AliESDs.root", Bool_t selectPhysics = kT
   gSystem->Load("libANALYSISalice");
   gSystem->Load("libCORRFW");
   gSystem->Load("libPWGmuon");
+  gSystem->Load("libPWGPPMUONlite");
   
   // Create input chain
   TChain* chain = CreateChain(inputFileName);
@@ -64,7 +67,7 @@ void RunMuonQA(TString inputFileName = "AliESDs.root", Bool_t selectPhysics = kT
   }
   
   // Muon QA analysis
-  gROOT->LoadMacro("$ALICE_ROOT/PWG3/muon/AddTaskMuonQA.C");
+  gROOT->LoadMacro("$ALICE_ROOT/PWGPP/PilotTrain/AddTaskMuonQA.C");
   AliAnalysisTaskMuonQA* muonQA = AddTaskMuonQA(selectPhysics, selectTrigger, selectMatched, selectCharge);
   if(!muonQA) {
     Error("RunMuonQA","AliAnalysisTaskMuonQA not created!");
index 140373b..719cfe2 100644 (file)
@@ -44,6 +44,8 @@
 #include "AliESDFMD.h"
 #include "AliESD.h"
 #include "AliESDMuonTrack.h"
+#include "AliESDMuonCluster.h"
+#include "AliESDMuonPad.h"
 #include "AliESDPmdTrack.h"
 #include "AliESDTrdTrack.h"
 #include "AliESDVertex.h"
@@ -98,6 +100,8 @@ ClassImp(AliESDEvent)
                                                        "TrkPileupVertices",
                                                        "Tracks",
                                                        "MuonTracks",
+                                                       "MuonClusters",
+                                                       "MuonPads",
                                                        "PmdTracks",
                                                        "AliESDTrdTrigger",
                                                        "TrdTracks",
@@ -139,6 +143,8 @@ AliESDEvent::AliESDEvent():
   fTrkPileupVertices(0),
   fTracks(0),
   fMuonTracks(0),
+  fMuonClusters(0),
+  fMuonPads(0),
   fPmdTracks(0),
   fTrdTracks(0),
   fTrdTracklets(0),
@@ -149,6 +155,7 @@ AliESDEvent::AliESDEvent():
   fEMCALCells(0), fPHOSCells(0),
   fCosmicTracks(0),
   fErrorLogs(0),
+  fOldMuonStructure(kFALSE),
   fESDOld(0),
   fESDFriendOld(0),
   fConnected(kFALSE),
@@ -184,6 +191,8 @@ AliESDEvent::AliESDEvent(const AliESDEvent& esd):
   fTrkPileupVertices(new TClonesArray(*esd.fTrkPileupVertices)),
   fTracks(new TClonesArray(*esd.fTracks)),
   fMuonTracks(new TClonesArray(*esd.fMuonTracks)),
+  fMuonClusters(new TClonesArray(*esd.fMuonClusters)),
+  fMuonPads(new TClonesArray(*esd.fMuonPads)),
   fPmdTracks(new TClonesArray(*esd.fPmdTracks)),
   fTrdTracks(new TClonesArray(*esd.fTrdTracks)),
   fTrdTracklets(new TClonesArray(*esd.fTrdTracklets)),
@@ -195,6 +204,7 @@ AliESDEvent::AliESDEvent(const AliESDEvent& esd):
   fPHOSCells(new AliESDCaloCells(*esd.fPHOSCells)),
   fCosmicTracks(new TClonesArray(*esd.fCosmicTracks)),
   fErrorLogs(new TClonesArray(*esd.fErrorLogs)),
+  fOldMuonStructure(esd.fOldMuonStructure),
   fESDOld(esd.fESDOld ? new AliESD(*esd.fESDOld) : 0),
   fESDFriendOld(esd.fESDFriendOld ? new AliESDfriend(*esd.fESDFriendOld) : 0),
   fConnected(esd.fConnected),
@@ -241,6 +251,8 @@ AliESDEvent::AliESDEvent(const AliESDEvent& esd):
   AddObject(fErrorLogs);
   AddObject(fESDACORDE);
   AddObject(fTOFHeader);
+  AddObject(fMuonClusters);
+  AddObject(fMuonPads);
   #ifdef MFT_UPGRADE
 //  AddObject(fESDMFT);
   #endif
@@ -335,6 +347,8 @@ AliESDEvent & AliESDEvent::operator=(const AliESDEvent& source) {
     }
   }
 
+  fOldMuonStructure = source.fOldMuonStructure;
+  
   fCentrality = source.fCentrality;
   fEventplane = source.fEventplane;
 
@@ -504,7 +518,9 @@ void AliESDEvent::ResetStdContent()
   if(fSPDPileupVertices)fSPDPileupVertices->Delete();
   if(fTrkPileupVertices)fTrkPileupVertices->Delete();
   if(fTracks)fTracks->Delete();
-  if(fMuonTracks)fMuonTracks->Delete();
+  if(fMuonTracks)fMuonTracks->Clear("C");
+  if(fMuonClusters)fMuonClusters->Clear("C");
+  if(fMuonPads)fMuonPads->Clear("C");
   if(fPmdTracks)fPmdTracks->Delete();
   if(fTrdTracks)fTrdTracks->Delete();
   if(fTrdTracklets)fTrdTracklets->Delete();
@@ -577,6 +593,8 @@ void AliESDEvent::Print(Option_t *) const
   printf("                 CaloClusters %d\n", GetNumberOfCaloClusters());
   printf("                 FMD       %s\n", (fESDFMD ? "yes" : "no"));
   printf("                 VZERO     %s\n", (fESDVZERO ? "yes" : "no"));
+  printf("                 muClusters %d\n", fMuonClusters ? fMuonClusters->GetEntriesFast() : 0);
+  printf("                 muPad     %d\n", fMuonPads ? fMuonPads->GetEntriesFast() : 0);
   if (fCosmicTracks) printf("                 Cosmics   %d\n",  GetNumberOfCosmicTracks());
   #ifdef MFT_UPGRADE
   //printf("                 MFT     %s\n", (fESDMFT ? "yes" : "no"));
@@ -987,10 +1005,151 @@ AliESDtrack*  AliESDEvent::NewTrack()
     return  track;
 }
 
- void AliESDEvent::AddMuonTrack(const AliESDMuonTrack *t) 
+//______________________________________________________________________________
+Bool_t AliESDEvent::MoveMuonObjects() 
+{
+  // move MUON clusters and pads to the new ESD structure in needed.
+  // to ensure backward compatibility
+  
+  if (!fOldMuonStructure) return kTRUE;
+  
+  if (!fMuonTracks || !fMuonClusters || !fMuonPads) return kFALSE;
+  
+  Bool_t reset = kTRUE;
+  Bool_t containTrackerData = kFALSE;
+  for (Int_t i = 0; i < fMuonTracks->GetEntriesFast(); i++) {
+    
+    AliESDMuonTrack *track = (AliESDMuonTrack*) fMuonTracks->UncheckedAt(i);
+    
+    if (track->ContainTrackerData()) containTrackerData = kTRUE;
+    else continue;
+    
+    if (!track->IsOldTrack()) continue;
+    
+    // remove objects connected to previous event if needed
+    if (reset) {
+      if (fMuonClusters->GetEntriesFast() > 0) fMuonClusters->Clear("C");
+      if (fMuonPads->GetEntriesFast() > 0) fMuonPads->Clear("C");
+      reset = kFALSE;
+    }
+    
+    track->MoveClustersToESD(*this);
+    
+  }
+  
+  // remove objects connected to previous event if needed
+  if (!containTrackerData) {
+    if (fMuonClusters->GetEntriesFast() > 0) fMuonClusters->Clear("C");
+    if (fMuonPads->GetEntriesFast() > 0) fMuonPads->Clear("C");
+  }
+  
+  return kTRUE;
+}
+
+//______________________________________________________________________________
+AliESDMuonTrack* AliESDEvent::GetMuonTrack(Int_t i)
+{
+  // get the MUON track at the position i in the internal array of track
+  if (!fMuonTracks) return 0x0;
+  if (!MoveMuonObjects()) return 0x0;
+  AliESDMuonTrack *track = (AliESDMuonTrack*) fMuonTracks->UncheckedAt(i);
+  track->SetESDEvent(this);
+  return track;
+}
+
+//______________________________________________________________________________
+void AliESDEvent::AddMuonTrack(const AliESDMuonTrack *t) 
+{
+  // add a MUON track
+  TClonesArray &fmu = *fMuonTracks;
+  AliESDMuonTrack *track = new(fmu[fMuonTracks->GetEntriesFast()]) AliESDMuonTrack(*t);
+  track->MoveClustersToESD(*this);
+}
+
+//______________________________________________________________________________
+AliESDMuonTrack* AliESDEvent::NewMuonTrack() 
+{
+  // create a new MUON track at the end of the internal array of track
+  TClonesArray &fmu = *fMuonTracks;
+  return new(fmu[fMuonTracks->GetEntriesFast()]) AliESDMuonTrack();
+}
+
+//______________________________________________________________________________
+Int_t AliESDEvent::GetNumberOfMuonClusters()
+{
+  // get the number of MUON clusters
+  if (!fMuonClusters) return 0;
+  if (!MoveMuonObjects()) return 0;
+  return fMuonClusters->GetEntriesFast();
+}
+
+//______________________________________________________________________________
+AliESDMuonCluster* AliESDEvent::GetMuonCluster(Int_t i)
+{
+  // get the MUON cluster at the position i in the internal array of cluster
+  if (!fMuonClusters) return 0x0;
+  if (!MoveMuonObjects()) return 0x0;
+  return (AliESDMuonCluster*) fMuonClusters->UncheckedAt(i);
+}
+
+//______________________________________________________________________________
+AliESDMuonCluster* AliESDEvent::FindMuonCluster(UInt_t clusterId)
+{
+  // find the MUON cluster with this Id in the internal array of cluster
+  if (!fMuonClusters) return 0x0;
+  if (!MoveMuonObjects()) return 0x0;
+  for (Int_t i = 0; i < fMuonClusters->GetEntriesFast(); i++) {
+    AliESDMuonCluster *cluster = (AliESDMuonCluster*) fMuonClusters->UncheckedAt(i);
+    if (cluster->GetUniqueID() == clusterId) return cluster;
+  }
+  return 0x0;
+}
+
+//______________________________________________________________________________
+AliESDMuonCluster* AliESDEvent::NewMuonCluster() 
+{
+  // create a new MUON cluster at the end of the internal array of cluster
+  TClonesArray &fmu = *fMuonClusters;
+  return new(fmu[fMuonClusters->GetEntriesFast()]) AliESDMuonCluster();
+}
+
+//______________________________________________________________________________
+Int_t AliESDEvent::GetNumberOfMuonPads()
+{
+  // get the number of MUON pads
+  if (!fMuonPads) return 0;
+  if (!MoveMuonObjects()) return 0;
+  return fMuonPads->GetEntriesFast();
+}
+
+//______________________________________________________________________________
+AliESDMuonPad* AliESDEvent::GetMuonPad(Int_t i)
 {
-    TClonesArray &fmu = *fMuonTracks;
-    new(fmu[fMuonTracks->GetEntriesFast()]) AliESDMuonTrack(*t);
+  // get the MUON pad at the position i in the internal array of pad
+  if (!fMuonPads) return 0x0;
+  if (!MoveMuonObjects()) return 0x0;
+  return (AliESDMuonPad*) fMuonPads->UncheckedAt(i);
+}
+
+//______________________________________________________________________________
+AliESDMuonPad* AliESDEvent::FindMuonPad(UInt_t padId)
+{
+  // find the MUON pad with this Id in the internal array of pad
+  if (!fMuonPads) return 0x0;
+  if (!MoveMuonObjects()) return 0x0;
+  for (Int_t i = 0; i < fMuonPads->GetEntriesFast(); i++) {
+    AliESDMuonPad *pad = (AliESDMuonPad*) fMuonPads->UncheckedAt(i);
+    if (pad->GetUniqueID() == padId) return pad;
+  }
+  return 0x0;
+}
+
+//______________________________________________________________________________
+AliESDMuonPad* AliESDEvent::NewMuonPad() 
+{
+  // create a new MUON pad at the end of the internal array of pad
+  TClonesArray &fmu = *fMuonPads;
+  return new(fmu[fMuonPads->GetEntriesFast()]) AliESDMuonPad();
 }
 
 void AliESDEvent::AddPmdTrack(const AliESDPmdTrack *t) 
@@ -1232,6 +1391,8 @@ void AliESDEvent::GetStdContent()
   fTrkPileupVertices = (TClonesArray*)fESDObjects->FindObject(fgkESDListName[kTrkPileupVertices]);
   fTracks = (TClonesArray*)fESDObjects->FindObject(fgkESDListName[kTracks]);
   fMuonTracks = (TClonesArray*)fESDObjects->FindObject(fgkESDListName[kMuonTracks]);
+  fMuonClusters = (TClonesArray*)fESDObjects->FindObject(fgkESDListName[kMuonClusters]);
+  fMuonPads = (TClonesArray*)fESDObjects->FindObject(fgkESDListName[kMuonPads]);
   fPmdTracks = (TClonesArray*)fESDObjects->FindObject(fgkESDListName[kPmdTracks]);
   fTrdTrigger = (AliESDTrdTrigger*)fESDObjects->FindObject(fgkESDListName[kTrdTrigger]);
   fTrdTracks = (TClonesArray*)fESDObjects->FindObject(fgkESDListName[kTrdTracks]);
@@ -1297,6 +1458,8 @@ void AliESDEvent::CreateStdContent()
   AddObject(new TClonesArray("AliESDVertex",0));
   AddObject(new TClonesArray("AliESDtrack",0));
   AddObject(new TClonesArray("AliESDMuonTrack",0));
+  AddObject(new TClonesArray("AliESDMuonCluster",0));
+  AddObject(new TClonesArray("AliESDMuonPad",0));
   AddObject(new TClonesArray("AliESDPmdTrack",0));
   AddObject(new AliESDTrdTrigger());
   AddObject(new TClonesArray("AliESDTrdTrack",0));
@@ -1323,6 +1486,25 @@ void AliESDEvent::CreateStdContent()
   GetStdContent();
 }
 
+void AliESDEvent::CompleteStdContent() 
+{
+  // create missing standard objects and add them to the TList of objects
+  
+  // add new MUON containers if missing (for backward compatibility)
+  if (!fESDObjects->FindObject(fgkESDListName[kMuonClusters])) {
+    TClonesArray* muonClusters = new TClonesArray("AliESDMuonCluster",0);
+    muonClusters->SetName(fgkESDListName[kMuonClusters]);
+    fESDObjects->AddAt(muonClusters, kMuonClusters);
+    fESDObjects->SetOwner(kTRUE);
+  }
+  if (!fESDObjects->FindObject(fgkESDListName[kMuonPads])) {
+    TClonesArray* muonPads = new TClonesArray("AliESDMuonPad",0);
+    muonPads->SetName(fgkESDListName[kMuonPads]);
+    fESDObjects->AddAt(muonPads, kMuonPads);
+    fESDObjects->SetOwner(kTRUE);
+  }
+}
+
 TObject* AliESDEvent::FindListObject(const char *name) const {
 //
 // Find object with name "name" in the list of branches
@@ -1412,6 +1594,7 @@ void AliESDEvent::ReadFromTree(TTree *tree, Option_t* opt){
 
   // if we find the "ESD" branch on the tree we do have the old structure
   if(tree->GetBranch("ESD")) {
+    fOldMuonStructure = kFALSE;
     char ** address  = (char **)(tree->GetBranch("ESD")->GetAddress());
     // do we have the friend branch
     TBranch * esdFB = tree->GetBranch("ESDfriend.");
@@ -1495,6 +1678,7 @@ void AliESDEvent::ReadFromTree(TTree *tree, Option_t* opt){
       fESDObjects->Delete();
       fESDObjects = connectedList;
       GetStdContent(); 
+      fOldMuonStructure = fESDObjects->TestBit(BIT(23));
       fConnected = true;
       return;
     }
@@ -1517,12 +1701,14 @@ void AliESDEvent::ReadFromTree(TTree *tree, Option_t* opt){
     // in principle
     // we only need new things in the list if we do no already have it..
     // TODO just add new entries
+    CompleteStdContent();
 
     if(fESDObjects->GetEntries()<kESDListN){
       AliWarning(Form("AliESDEvent::ReadFromTree() TList contains less than the standard contents %d < %d \n",
                      fESDObjects->GetEntries(),kESDListN));
     }
     // set the branch addresses
+    fOldMuonStructure = kFALSE;
     TIter next(fESDObjects);
     TNamed *el;
     while((el=(TNamed*)next())){
@@ -1546,6 +1732,9 @@ void AliESDEvent::ReadFromTree(TTree *tree, Option_t* opt){
           }
           else{
             AliWarning(Form("AliESDEvent::ReadFromTree() No Branch found with Name %s or %s.",bname.Data(),bname.Data()));
+           if (bname == fgkESDListName[kMuonClusters]) {
+             fOldMuonStructure = kTRUE;
+           }
           }
 
        }
@@ -1556,6 +1745,7 @@ void AliESDEvent::ReadFromTree(TTree *tree, Option_t* opt){
     // must not delete it
     fESDObjects->SetOwner(kTRUE);
     fESDObjects->SetName("ESDObjectsConnectedToTree");
+    fESDObjects->SetBit(BIT(23), fOldMuonStructure);
     // we are not owner of the list objects 
     // must not delete it
     tree->GetUserInfo()->Add(fESDObjects);
@@ -1566,6 +1756,7 @@ void AliESDEvent::ReadFromTree(TTree *tree, Option_t* opt){
     // we can't get the list from the user data, create standard content
     // and set it by hand (no ESDfriend at the moment
     CreateStdContent();
+    fOldMuonStructure = kFALSE;
     TIter next(fESDObjects);
     TNamed *el;
     while((el=(TNamed*)next())){
@@ -1579,6 +1770,9 @@ void AliESDEvent::ReadFromTree(TTree *tree, Option_t* opt){
        if(br){
          tree->SetBranchAddress(Form("%s.",bname.Data()),fESDObjects->GetObjectRef(el));
        }
+       else if (bname == fgkESDListName[kMuonClusters]) {
+         fOldMuonStructure = kTRUE;
+       }
       }
     }
     GetStdContent();
index 2d62f5f..1a5416f 100644 (file)
@@ -58,6 +58,8 @@ class AliESDTrdTrigger;
 class AliESDTrdTrack;
 class AliESDTrdTracklet;
 class AliESDMuonTrack;
+class AliESDMuonCluster;
+class AliESDMuonPad;
 class AliESD;
 class AliESDcascade;
 class AliCentrality;
@@ -91,6 +93,8 @@ public:
                       kTrkPileupVertices,
                       kTracks,
                       kMuonTracks,
+                      kMuonClusters,
+                      kMuonPads,
                       kPmdTracks,
                       kTrdTrigger,
                       kTrdTracks,
@@ -351,12 +355,19 @@ public:
     //     new(fhlt[fHLTHoughTracks->GetEntriesFast()]) AliESDHLTtrack(*t);
   }
   
-  AliESDMuonTrack *GetMuonTrack(Int_t i) const {
-    return (AliESDMuonTrack *)(fMuonTracks?fMuonTracks->UncheckedAt(i):0x0);
-  }
-
-  void AddMuonTrack(const AliESDMuonTrack *t);
-
+  Bool_t MoveMuonObjects();
+  
+  AliESDMuonTrack* GetMuonTrack(Int_t i);
+  AliESDMuonTrack* NewMuonTrack();
+  
+  AliESDMuonCluster* GetMuonCluster(Int_t i);
+  AliESDMuonCluster* FindMuonCluster(UInt_t clusterId);
+  AliESDMuonCluster* NewMuonCluster();
+  
+  AliESDMuonPad* GetMuonPad(Int_t i);
+  AliESDMuonPad* FindMuonPad(UInt_t padId);
+  AliESDMuonPad* NewMuonPad();
+  
   AliESDPmdTrack *GetPmdTrack(Int_t i) const {
     return (AliESDPmdTrack *)(fPmdTracks?fPmdTracks->UncheckedAt(i):0x0);
   }
@@ -442,6 +453,8 @@ public:
   //  fHLTHoughTracks->GetEntriesFast();  }
 
   Int_t GetNumberOfMuonTracks() const {return fMuonTracks?fMuonTracks->GetEntriesFast():0;}
+  Int_t GetNumberOfMuonClusters();
+  Int_t GetNumberOfMuonPads();
   Int_t GetNumberOfPmdTracks() const {return fPmdTracks?fPmdTracks->GetEntriesFast():0;}
   Int_t GetNumberOfTrdTracks() const {return fTrdTracks?fTrdTracks->GetEntriesFast():0;}
   Int_t GetNumberOfTrdTracklets() const {return fTrdTracklets?fTrdTracklets->GetEntriesFast():0;}
@@ -472,6 +485,7 @@ public:
   void ResetStdContent();
   void CreateStdContent();
   void CreateStdContent(Bool_t bUseThisList);
+  void CompleteStdContent();
   void SetStdNames();
   void CopyFromOldESD();
   TList* GetList() const {return fESDObjects;}
@@ -491,6 +505,8 @@ protected:
   AliESDEvent(const AliESDEvent&);
   static Bool_t ResetWithPlacementNew(TObject *pObject);
 
+  void AddMuonTrack(const AliESDMuonTrack *t);
+  
   TList *fESDObjects;             // List of esd Objects
 
   AliESDRun       *fESDRun;           //! Run information tmp put in the Userdata
@@ -512,6 +528,8 @@ protected:
   TClonesArray *fTrkPileupVertices;//! Pileup primary vertices reconstructed using the tracks 
   TClonesArray *fTracks;           //! ESD tracks 
   TClonesArray *fMuonTracks;       //! MUON ESD tracks
+  TClonesArray *fMuonClusters;     //! MUON ESD clusters
+  TClonesArray *fMuonPads;         //! MUON ESD pads
   TClonesArray *fPmdTracks;        //! PMD ESD tracks
   TClonesArray *fTrdTracks;        //! TRD ESD tracks (triggered)
   TClonesArray *fTrdTracklets;     //! TRD tracklets (for trigger)
@@ -524,7 +542,7 @@ protected:
   TClonesArray *fCosmicTracks;     //! Tracks created by cosmics finder
   TClonesArray *fErrorLogs;        //! Raw-data reading error messages
  
-
+  Bool_t fOldMuonStructure;        //! Flag if reading ESD with old MUON structure
 
   AliESD       *fESDOld;           //! Old esd Structure
   AliESDfriend *fESDFriendOld;     //! Old friend esd Structure
index 7ee9e30..f3aeb37 100644 (file)
@@ -23,6 +23,7 @@
 /// \author Philippe Pillot, Subatech
 //-----------------------------------------------------------------------------
 
+#include "AliESDEvent.h"
 #include "AliESDMuonCluster.h"
 #include "AliESDMuonPad.h"
 
@@ -41,6 +42,8 @@ AliESDMuonCluster::AliESDMuonCluster()
   fCharge(0.),
   fChi2(0.),
   fPads(0x0),
+  fNPads(0),
+  fPadsId(0x0),
   fLabel(-1)
 {
   /// default constructor
@@ -54,6 +57,8 @@ AliESDMuonCluster::AliESDMuonCluster (const AliESDMuonCluster& cluster)
   fCharge(cluster.fCharge),
   fChi2(cluster.fChi2),
   fPads(0x0),
+  fNPads(cluster.fNPads),
+  fPadsId(0x0),
   fLabel(cluster.fLabel)
 {
   /// Copy constructor
@@ -71,6 +76,8 @@ AliESDMuonCluster::AliESDMuonCluster (const AliESDMuonCluster& cluster)
       pad = (AliESDMuonPad*) cluster.fPads->After(pad);
     }
   }
+  
+  if (cluster.fPadsId) fPadsId = new TArrayI(*(cluster.fPadsId));
 }
 
 //_____________________________________________________________________________
@@ -101,6 +108,8 @@ AliESDMuonCluster& AliESDMuonCluster::operator=(const AliESDMuonCluster& cluster
     }
   } else fPads = 0x0;
   
+  SetPadsId(cluster.fNPads, cluster.GetPadsId());
+  
   return *this;
 }
 
@@ -109,50 +118,62 @@ AliESDMuonCluster::~AliESDMuonCluster()
 {
   /// Destructor
   delete fPads;
+  delete fPadsId;
 }
 
 //__________________________________________________________________________
-void AliESDMuonCluster::Clear(Option_t* /*opt*/)
+void AliESDMuonCluster::Clear(Option_t* opt)
 {
   /// Clear arrays
-  delete fPads;
-  fPads = 0x0;
+  if (opt && opt[0] == 'C') {
+    if (fPads) fPads->Clear("C");
+  } else {
+    delete fPads; fPads = 0x0;
+  }
+  delete fPadsId; fPadsId = 0x0;
+  fNPads = 0;
 }
 
 //_____________________________________________________________________________
-Int_t AliESDMuonCluster::GetNPads() const
+void AliESDMuonCluster::AddPadId(UInt_t padId)
 {
-  // return the number of pads associated to the cluster
-  if (!fPads) return 0;
-  
-  return fPads->GetEntriesFast();
+  /// Add the given pad Id to the list associated to the cluster
+  if (!fPadsId) fPadsId = new TArrayI(10);
+  if (fPadsId->GetSize() <= fNPads) fPadsId->Set(fNPads+10);
+  fPadsId->AddAt(static_cast<Int_t>(padId), fNPads++);
 }
 
 //_____________________________________________________________________________
-TClonesArray& AliESDMuonCluster::GetPads() const
+void AliESDMuonCluster::SetPadsId(Int_t nPads, const UInt_t *padsId)
 {
-  // return the array of pads associated to the cluster
-  if (!fPads) fPads = new TClonesArray("AliESDMuonPad",10);
+  /// Fill the list pads'Id associated to the cluster with the given list
   
-  return *fPads;
-}
-
-//_____________________________________________________________________________
-void AliESDMuonCluster::AddPad(const AliESDMuonPad &pad)
-{
-  // add a pad to the TClonesArray of pads associated to the cluster
-  if (!fPads) fPads = new TClonesArray("AliESDMuonPad",10);
+  if (nPads <= 0 || !padsId) {
+    delete fPadsId;
+    fPadsId = 0x0;
+    fNPads = 0;
+    return;
+  }
+  
+  if (!fPadsId) fPadsId = new TArrayI(nPads, reinterpret_cast<const Int_t*>(padsId));
+  else fPadsId->Set(nPads, reinterpret_cast<const Int_t*>(padsId));
+  fNPads = nPads;
   
-  new ((*fPads)[fPads->GetEntriesFast()]) AliESDMuonPad(pad);
 }
 
 //_____________________________________________________________________________
-Bool_t AliESDMuonCluster::PadsStored() const
+void AliESDMuonCluster::MovePadsToESD(AliESDEvent &esd)
 {
-  // return kTRUE if the pads associated to the cluster are registered
-  if (GetNPads() == 0) return kFALSE;
-  
-  return kTRUE;
+  /// move the pads to the new ESD structure
+  if (!fPads) return;
+  for (Int_t i = 0; i < fPads->GetEntriesFast(); i++) {
+    AliESDMuonPad *pad = static_cast<AliESDMuonPad*>(fPads->UncheckedAt(i));
+    AliESDMuonPad *newPad = esd.NewMuonPad();
+    *newPad = *pad;
+    AddPadId(newPad->GetUniqueID());
+  }
+  delete fPads;
+  fPads = 0x0;
 }
 
 //_____________________________________________________________________________
@@ -171,10 +192,7 @@ void AliESDMuonCluster::Print(Option_t */*option*/) const
   
   if (PadsStored()) {
     cout<<"  pad infos:"<<endl;
-    for (Int_t iPad=0; iPad<GetNPads(); iPad++) {
-      cout<<"  ";
-      ( (AliESDMuonPad*) fPads->UncheckedAt(iPad) )->Print();
-    }
+    for (Int_t iPad=0; iPad<GetNPads(); iPad++) cout<<"  "<<GetPadId(iPad)<<endl;
   }
 }
 
index e235b41..4e9cd7a 100644 (file)
@@ -12,8 +12,9 @@
 
 
 #include <TObject.h>
+#include <TArrayI.h>
 
-class AliESDMuonPad;
+class AliESDEvent;
 class TClonesArray;
 
 class AliESDMuonCluster : public TObject {
@@ -62,11 +63,21 @@ public:
   /// Return the index of this cluster (0..), part of the uniqueID
   Int_t    GetClusterIndex() const {return (GetUniqueID() & 0x0001FFFF);}
   
-  // Methods to get, fill and check the array of associated pads
-  Int_t         GetNPads() const;
-  TClonesArray& GetPads() const;
-  void          AddPad(const AliESDMuonPad &pad);
-  Bool_t        PadsStored() const;
+  // Add the given pad Id to the list associated to the cluster
+  void     AddPadId(UInt_t padId);
+  // Fill the list pads'Id associated to the cluster with the given list
+  void     SetPadsId(Int_t nPads, const UInt_t *padsId);
+  /// Return the number of pads associated to this cluster
+  Int_t    GetNPads() const {return fNPads;}
+  /// Return the Id of pad i
+  UInt_t   GetPadId(Int_t i) const {return (fPadsId && i >= 0 && i < fNPads) ? static_cast<UInt_t>(fPadsId->At(i)) : 0;}
+  /// Return the array of pads'Id
+  const UInt_t* GetPadsId() const {return fPadsId ? reinterpret_cast<UInt_t*>(fPadsId->GetArray()) : 0x0;}
+  /// Return kTrue if the pads'Id are stored
+  Bool_t   PadsStored() const {return (fNPads > 0);}
+  
+  // Transfer pads to the new ESD structure
+  void     MovePadsToESD(AliESDEvent &esd);
   
   /// Set the corresponding MC track number
   void  SetLabel(Int_t label) {fLabel = label;}
@@ -82,12 +93,15 @@ protected:
   Double32_t fCharge;   ///< cluster charge
   Double32_t fChi2;     ///< cluster chi2
   
-  mutable TClonesArray* fPads; ///< Array of pads attached to the cluster
+  mutable TClonesArray* fPads;  ///< Array of pads attached to the cluster -- deprecated
+  
+  Int_t    fNPads;  ///< number of pads attached to the cluster
+  TArrayI* fPadsId; ///< array of Ids of pads attached to the cluster
   
   Int_t fLabel; ///< point to the corresponding MC track
   
   
-  ClassDef(AliESDMuonCluster, 3) // MUON ESD cluster class
+  ClassDef(AliESDMuonCluster, 4) // MUON ESD cluster class
 };
 
 #endif
index d3d3861..e2c73bd 100644 (file)
@@ -71,6 +71,7 @@ AliESDMuonTrack::AliESDMuonTrack ():
   fHitsPatternInTrigCh(0),
   fNHit(0),
   fClusters(0x0),
+  fClustersId(0x0),
   fLabel(-1),
   fESDEvent(0)
 
@@ -118,6 +119,7 @@ AliESDMuonTrack::AliESDMuonTrack (const AliESDMuonTrack& muonTrack):
   fHitsPatternInTrigCh(muonTrack.fHitsPatternInTrigCh),
   fNHit(muonTrack.fNHit),
   fClusters(0x0),
+  fClustersId(0x0),
   fLabel(muonTrack.fLabel),
   fESDEvent(muonTrack.fESDEvent)
 {
@@ -136,6 +138,10 @@ AliESDMuonTrack::AliESDMuonTrack (const AliESDMuonTrack& muonTrack):
       cluster = (AliESDMuonCluster*) muonTrack.fClusters->After(cluster);
     }
   }
+  
+  // copy of cluster Ids
+  if (muonTrack.fClustersId) fClustersId = new TArrayI(*(muonTrack.fClustersId));
+  
 }
 
 //_____________________________________________________________________________
@@ -206,9 +212,19 @@ AliESDMuonTrack& AliESDMuonTrack::operator=(const AliESDMuonTrack& muonTrack)
     }
   } else fClusters = 0x0;
   
+  // copy of cluster Ids
+  if (muonTrack.fClustersId) {
+    if (fClustersId) *fClustersId = *(muonTrack.fClustersId);
+    else fClustersId = new TArrayI(*(muonTrack.fClustersId));
+  } else {
+    delete fClustersId;
+    fClustersId = 0x0;
+  }
+  
   return *this;
 }
 
+//__________________________________________________________________________
 void AliESDMuonTrack::Copy(TObject &obj) const {
   
   /// This overwrites the virtual TOBject::Copy()
@@ -222,19 +238,25 @@ void AliESDMuonTrack::Copy(TObject &obj) const {
 
 }
 
-
 //__________________________________________________________________________
 AliESDMuonTrack::~AliESDMuonTrack()
 {
   /// Destructor
   delete fClusters;
+  delete fClustersId;
 }
 
 //__________________________________________________________________________
 void AliESDMuonTrack::Clear(Option_t* opt)
 {
   /// Clear arrays
-  if (fClusters) fClusters->Clear(opt);
+  if (opt && opt[0] == 'C') {
+    if (fClusters) fClusters->Clear("C");
+  } else {
+    delete fClusters; fClusters = 0x0;
+  }
+  delete fClustersId; fClustersId = 0x0;
+  fNHit = 0;
 }
 
 //__________________________________________________________________________
@@ -275,6 +297,7 @@ void AliESDMuonTrack::Reset()
   fHitsPatternInTrigCh = 0;
   fNHit = 0;
   delete fClusters; fClusters = 0x0;
+  delete fClustersId; fClustersId = 0x0;
   for (Int_t i = 0; i < 15; i++) fCovariances[i] = 0.;
   fLabel = -1;
   fESDEvent = 0;
@@ -570,39 +593,29 @@ Bool_t AliESDMuonTrack::MatchTriggerDigits() const
 }
 
 //_____________________________________________________________________________
-Int_t AliESDMuonTrack::GetNClusters() const
+void AliESDMuonTrack::AddClusterId(UInt_t clusterId)
 {
-  /// return the number of clusters associated to the track
-  if (!fClusters) return 0;
-  
-  return fClusters->GetEntriesFast();
+  /// add the given cluster Id to the list associated to the track
+  if (!fClustersId) fClustersId = new TArrayI(5);
+  if (fClustersId->GetSize() <= fNHit) fClustersId->Set(fNHit+1);
+  fClustersId->AddAt(static_cast<Int_t>(clusterId), fNHit++);
 }
 
 //_____________________________________________________________________________
-TClonesArray& AliESDMuonTrack::GetClusters() const
+void AliESDMuonTrack::MoveClustersToESD(AliESDEvent &esd)
 {
-  /// return the array of clusters associated to the track
-  if (!fClusters) fClusters = new TClonesArray("AliESDMuonCluster",10);
-  
-  return *fClusters;
-}
-
-//_____________________________________________________________________________
-void AliESDMuonTrack::AddCluster(const AliESDMuonCluster &cluster)
-{
-  /// add a cluster to the TClonesArray of clusters associated to the track
-  if (!fClusters) fClusters = new TClonesArray("AliESDMuonCluster",10);
-  
-  new ((*fClusters)[fClusters->GetEntriesFast()]) AliESDMuonCluster(cluster);
-}
-
-//_____________________________________________________________________________
-Bool_t AliESDMuonTrack::ClustersStored() const
-{
-  /// return kTRUE if the clusters associated to the track are registered
-  if (GetNClusters() == 0) return kFALSE;
-  
-  return kTRUE;
+  /// move the clusters (and attached pads) to the new ESD structure
+  if (!fClusters) return;
+  fNHit = 0;
+  for (Int_t i = 0; i < fClusters->GetEntriesFast(); i++) {
+    AliESDMuonCluster *cluster = static_cast<AliESDMuonCluster*>(fClusters->UncheckedAt(i));
+    cluster->MovePadsToESD(esd);
+    AliESDMuonCluster *newCluster = esd.NewMuonCluster();
+    *newCluster = *cluster;
+    AddClusterId(newCluster->GetUniqueID());
+  }
+  delete fClusters;
+  fClusters = 0x0;
 }
 
 //_____________________________________________________________________________
index 18ed1b3..2f27d6c 100644 (file)
 #include <TMath.h>
 #include <TMatrixD.h>
 #include <TDatabasePDG.h>
+#include <TArrayI.h>
 
 #include "AliVParticle.h"
 
-class AliESDMuonCluster;
 class AliESDEvent;
 class TClonesArray;
 class TLorentzVector;
@@ -97,7 +97,6 @@ public:
   Double_t GetChi2(void) const {return fChi2;}
   void     SetChi2(Double_t Chi2) {fChi2 = Chi2;}
   UChar_t  GetNHit(void) const {return fNHit;}
-  void     SetNHit(UInt_t NHit) {fNHit = NHit;}
   Int_t    GetNDF() const;
   Double_t GetNormalizedChi2() const;
   
@@ -146,11 +145,14 @@ public:
   void     Connected(Bool_t flag = kTRUE) {flag ? SETBIT(fMuonClusterMap,31) : CLRBIT(fMuonClusterMap,31);}
   Bool_t   IsConnected() const {return TESTBIT(fMuonClusterMap,31);}
   
-  // Methods to get, fill and check the array of associated clusters
-  Int_t         GetNClusters() const;
-  TClonesArray& GetClusters() const;
-  void          AddCluster(const AliESDMuonCluster &cluster);
-  Bool_t        ClustersStored() const;
+  // Methods to fill and get the Id of associated clusters
+  void     AddClusterId(UInt_t clusterId);
+  Int_t    GetNClusters() const {return static_cast<Int_t>(fNHit);}
+  UInt_t   GetClusterId(Int_t i) const {return (fClustersId && i >= 0 && i < fNHit) ? static_cast<UInt_t>(fClustersId->At(i)) : 0;}
+  
+  // Method to transfer clusters to the new ESD structure
+  Bool_t   IsOldTrack() {return (fClusters);}
+  void     MoveClustersToESD(AliESDEvent &esd);
   
   // Methods to compute track momentum
   Double_t Px() const;
@@ -285,15 +287,17 @@ protected:
   
   UInt_t   fMuonClusterMap;        ///< Map of clusters in tracking chambers
   UShort_t fHitsPatternInTrigCh;   ///< Word containing info on the hits left in trigger chambers
-  UChar_t  fNHit;                  ///< number of hit in the track
+  UChar_t  fNHit;                  ///< number of clusters attached to the track
+  
+  mutable TClonesArray* fClusters; ///< Array of clusters attached to the track -- deprecated
   
-  mutable TClonesArray* fClusters; ///< Array of clusters attached to the track
+  TArrayI* fClustersId;            ///< Array of clusters'Id attached to the track
   
   Int_t fLabel;                    ///< point to the corresponding MC track
 
   AliESDEvent*   fESDEvent; //!Pointer back to event to which the track belongs
   
-  ClassDef(AliESDMuonTrack,13) // MUON ESD track class 
+  ClassDef(AliESDMuonTrack,14) // MUON ESD track class 
 };
 
 #endif