]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - MUON/MUONRecoCheck.C
Bug fix for loading the LUT for chambers 1 to 6. (Indra)
[u/mrichter/AliRoot.git] / MUON / MUONRecoCheck.C
index 1a15a00655e415b1a5d7dc55179427f7ea1f1353..c15e3302fba236b4fe4ad80a4aac8c403aa5e5f9 100644 (file)
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/
 
+// $Id$
+
+/// \ingroup macros
+/// \file MUONRecoCheck.C
+/// \brief Utility macro to check the muon reconstruction. 
+///
+/// Reconstructed tracks are compared to reference tracks. The reference tracks 
+/// are built from AliTrackReference for the hit in chamber (0..9) and from 
+/// kinematics (TreeK) for the vertex parameters.  
+///
+/// \author Jean-Pierre Cussonneau, Subatech  
+
 // ROOT includes
+#include "TMath.h"
 #include "TClonesArray.h"
 #include "TH1.h"
+#include "TH2.h"
+#include "TGraphErrors.h"
+#include "TF1.h"
 #include "TFile.h"
-#include <TGeoManager.h>
 
 // STEER includes
-#include "AliRun.h"
-#include "AliHeader.h"
-#include "AliMC.h"
-#include "AliStack.h"
-#include "AliMagFMaps.h"
-#include "AliTracker.h"
+#include "AliCDBManager.h"
 
 // MUON includes
+#include "AliMUONCDB.h"
 #include "AliMUONConstants.h"
 #include "AliMUONTrack.h"
 #include "AliMUONRecoCheck.h"
 #include "AliMUONTrackParam.h"
-#include "AliMUONTrackExtrap.h"
-
+#include "AliMUONRecoParam.h"
 #include "AliMUONVTrackStore.h"
+#include "AliMUONVCluster.h"
 
-Int_t TrackCheck( Bool_t *compTrack);
-
-void MUONRecoCheck (Int_t nEvent = 1, char* geoFilename = "geometry.root", 
-                    char * filenameSim="galice_sim.root", char * filename="galice.root"){
-  
-  // Utility macro to check the muon reconstruction. Reconstructed tracks are compared
-  // to reference tracks. The reference tracks are built from AliTrackReference for the
-  // hit in chamber (0..9) and from kinematics (TreeK) for the vertex parameters.     
-  
-  Bool_t *compTrack;
-  Bool_t compTrackOK[10];
-  Int_t nHitOK = 0;
-  Int_t testTrack = 0; 
-  Int_t iTrack = 0;
-  AliMUONTrack* trackOK(0x0);
-  Int_t trackID = 0;
-  Double_t sigma2Cut = 16;  // 4 sigmas cut, sigma2Cut = 4*4
-  AliMUONTrackParam *trackParam;
-  TClonesArray *trackParamAtHit;
-  Double_t x1,y1,z1,pX1,pY1,pZ1,p1;
-  Double_t x2,y2,z2,pX2,pY2,pZ2,p2;
+void MUONRecoCheck (Int_t nEvent = -1, char * pathSim="./generated/", char * esdFileName="AliESDs.root",
+                   const char* ocdbPath = "local://$ALICE_ROOT/OCDB")
+{
   
   // File for histograms and histogram booking
   TFile *histoFile = new TFile("MUONRecoCheck.root", "RECREATE");
   
   TH1F *hReconstructible = new TH1F("hReconstructible"," Nb of reconstructible tracks ",15,-0.5,14.5);
   TH1F *hReco = new TH1F("hReco"," Nb of reconstructed tracks / evt",15,-0.5,14.5);
-  TH1F *hNHitComp = new TH1F("hNHitComp"," Nb of compatible hits / track ",15,-0.5,14.5);
-  TH1F *hTestTrack = new TH1F("hTestTrack"," Reconstruction requirement / track",15,-0.5,14.5);
+  TH1F *hNClusterComp = new TH1F("hNClusterComp"," Nb of compatible clusters / track ",15,-0.5,14.5);
   TH1F *hTrackRefID = new TH1F("hTrackRefID"," track reference ID ",100,-0.5,99.5);
   
-  TH1F *hResMomVertex = new TH1F("hMomVertex"," delta P vertex (GeV/c)",100,-10.,10);
-  TH1F *hResMomFirstHit = new TH1F("hMomFirstHit"," delta P first hit (GeV/c)",100,-10.,10);
+  // momentum resolution
+  TH1F *hResMomVertex = new TH1F("hResMomVertex"," delta P vertex (GeV/c)",100,-10.,10);
+  TH1F *hResMomFirstCluster = new TH1F("hResMomFirstCluster"," delta P first cluster (GeV/c)",100,-10.,10);
+  TH2D *hResMomVertexVsMom = new TH2D("hResMomVertexVsMom","#Delta_{p} at vertex versus p (GeV/c)",30,0.,300.,800,-20.,20.);
+  TH2D *hResMomFirstClusterVsMom = new TH2D("hResMomFirstClusterVsMom","#Delta_{p} at first cluster versus p (GeV/c)",30,0.,300.,800,-20.,20.);
+  TGraphErrors* gResMomVertexVsMom = new TGraphErrors(30);
+  gResMomVertexVsMom->SetName("gResMomVertexVsMom");
+  gResMomVertexVsMom->SetTitle("#Delta_{p}/p at vertex versus p;p (GeV/c);#sigma_{p}/p (%)");
+  TGraphErrors* gResMomFirstClusterVsMom = new TGraphErrors(30);
+  gResMomFirstClusterVsMom->SetName("gResMomFirstClusterVsMom");
+  gResMomFirstClusterVsMom->SetTitle("#Delta_{p}/p at first cluster versus p;p (GeV/c);#sigma_{p}/p (%)");
+  TF1* f = new TF1("f","gaus");
   
-  // Import TGeo geometry (needed by AliMUONTrackExtrap::ExtrapToVertex)
-  if (!gGeoManager) {
-    TGeoManager::Import(geoFilename);
-    if (!gGeoManager) {
-      Error("MUONmass_ESD", "getting geometry from file %s failed", geoFilename);
-      return;
-    }
+  // residuals at clusters
+  histoFile->mkdir("residuals","residuals");
+  histoFile->cd("residuals");
+  TH1F* hResidualXInCh[AliMUONConstants::NTrackingCh()];
+  TH1F* hResidualYInCh[AliMUONConstants::NTrackingCh()];
+  for (Int_t i = 0; i < AliMUONConstants::NTrackingCh(); i++) {
+    hResidualXInCh[i] = new TH1F(Form("hResidualXInCh%d",i+1), Form("cluster-track residual-X distribution in chamber %d;#Delta_{X} (cm)",i+1), 1000, -1., 1.);
+    hResidualYInCh[i] = new TH1F(Form("hResidualYInCh%d",i+1), Form("cluster-track residual-Y distribution in chamber %d;#Delta_{Y} (cm)",i+1), 1000, -0.5, 0.5);
   }
+  TGraphErrors* gResidualXPerChMean = new TGraphErrors(AliMUONConstants::NTrackingCh());
+  gResidualXPerChMean->SetName("gResidualXPerChMean");
+  gResidualXPerChMean->SetTitle("cluster-track residual-X per Ch: mean;chamber ID;<#Delta_{Y}> (cm)");
+  gResidualXPerChMean->SetMarkerStyle(kFullDotLarge);
+  TGraphErrors* gResidualYPerChMean = new TGraphErrors(AliMUONConstants::NTrackingCh());
+  gResidualYPerChMean->SetName("gResidualYPerChMean");
+  gResidualYPerChMean->SetTitle("cluster-track residual-Y per Ch: mean;chamber ID;<#Delta_{Y}> (cm)");
+  gResidualYPerChMean->SetMarkerStyle(kFullDotLarge);
+  TGraphErrors* gResidualXPerChSigma = new TGraphErrors(AliMUONConstants::NTrackingCh());
+  gResidualXPerChSigma->SetName("gResidualXPerChSigma");
+  gResidualXPerChSigma->SetTitle("cluster-track residual-X per Ch: sigma;chamber ID;#sigma_{X} (cm)");
+  gResidualXPerChSigma->SetMarkerStyle(kFullDotLarge);
+  TGraphErrors* gResidualYPerChSigma = new TGraphErrors(AliMUONConstants::NTrackingCh());
+  gResidualYPerChSigma->SetName("gResidualYPerChSigma");
+  gResidualYPerChSigma->SetTitle("cluster-track residual-Y per Ch: sigma;chamber ID;#sigma_{X} (cm)");
+  gResidualYPerChSigma->SetMarkerStyle(kFullDotLarge);
   
-  // set  mag field 
-  // waiting for mag field in CDB 
-  printf("Loading field map...\n");
-  AliMagFMaps* field = new AliMagFMaps("Maps","Maps", 1, 1., 10., AliMagFMaps::k5kG);
-  AliTracker::SetFieldMap(field, kFALSE);
-  // set the magnetic field for track extrapolations
-  AliMUONTrackExtrap::SetField(AliTracker::GetFieldMap());
-    
-  AliMUONRecoCheck rc(filename,filenameSim);
+  AliMUONRecoCheck rc(esdFileName, pathSim);
+  
+  // load necessary data from OCDB
+  AliCDBManager::Instance()->SetDefaultStorage(ocdbPath);
+  AliCDBManager::Instance()->SetRun(rc.GetRunNumber());
+  AliMUONRecoParam* recoParam = AliMUONCDB::LoadRecoParam();
+  if (!recoParam) return;
+  
+  // get sigma cut from recoParam to associate clusters with TrackRefs in case the label are not used
+  Double_t sigmaCut = (recoParam->ImproveTracks()) ? recoParam->GetSigmaCutForImprovement() : recoParam->GetSigmaCutForTracking();
+  // compute the mask of requested stations from recoParam
+  UInt_t requestedStationMask = 0;
+  for (Int_t i = 0; i < 5; i++) if (recoParam->RequestStation(i)) requestedStationMask |= ( 1 << i );
+  // get from recoParam whether a track need 2 chambers hit in the same station (4 or 5) or not to be reconstructible
+  Bool_t request2ChInSameSt45 = !recoParam->MakeMoreTrackCandidates();
   
   Int_t nevents = rc.NumberOfEvents();
   
-  if (nevents < nEvent) nEvent = nevents;
+  if (nevents < nEvent || nEvent < 0) nEvent = nevents;
   
   Int_t ievent;
   Int_t nReconstructibleTracks = 0;
   Int_t nReconstructedTracks = 0;
   Int_t nReconstructibleTracksCheck = 0;
+  AliMUONTrackParam *trackParam;
+  Double_t x1,y1,z1,pX1,pY1,pZ1,p1,pT1;
+  Double_t x2,y2,z2,pX2,pY2,pZ2,p2,pT2;
   
   for (ievent=0; ievent<nEvent; ievent++)
   {
     if (!(ievent%10)) printf(" **** event # %d  \n",ievent);
     
-    AliMUONVTrackStore* trackStore = rc.ReconstructedTracks(ievent);
-    AliMUONVTrackStore* trackRefStore = rc.ReconstructibleTracks(ievent);
+    AliMUONVTrackStore* trackStore = rc.ReconstructedTracks(ievent, kFALSE);
+    AliMUONVTrackStore* trackRefStore = rc.ReconstructibleTracks(ievent, requestedStationMask, request2ChInSameSt45);
     
     hReconstructible->Fill(trackRefStore->GetSize());
     hReco->Fill(trackStore->GetSize());
@@ -111,48 +139,36 @@ void MUONRecoCheck (Int_t nEvent = 1, char* geoFilename = "geometry.root",
     nReconstructibleTracks += trackRefStore->GetSize();
     nReconstructedTracks += trackStore->GetSize();
     
+    // loop over trackRef
     TIter next(trackRefStore->CreateIterator());
     AliMUONTrack* trackRef;
-    
     while ( ( trackRef = static_cast<AliMUONTrack*>(next()) ) )
     {
-      testTrack = 0;
-      trackOK = 0x0;
-      for (Int_t ch = 0; ch < AliMUONConstants::NTrackingCh(); ch++) 
-      {
-        compTrackOK[ch] = kFALSE;
-      }
       
+      hTrackRefID->Fill(trackRef->GetMCLabel());
+      
+      AliMUONTrack* trackMatched = 0x0;
+      Int_t nMatchClusters = 0;
+      
+      // loop over trackReco and look for compatible track
       TIter next2(trackStore->CreateIterator());
       AliMUONTrack* trackReco;
-      
       while ( ( trackReco = static_cast<AliMUONTrack*>(next2()) ) )
       {
-        // check if trackRef is compatible with trackReco
-        compTrack = trackRef->CompatibleTrack(trackReco,sigma2Cut);
-        
-        iTrack = TrackCheck(compTrack);
-        
-        if (iTrack > testTrack) 
-        {
-          nHitOK = 0;
-          for (Int_t ch = 0; ch < AliMUONConstants::NTrackingCh(); ch++) 
-          {
-            if (compTrack[ch]) nHitOK++;
-            compTrackOK[ch] = compTrack[ch];
-          }
-          testTrack = iTrack;
-          trackOK = trackReco;
-        }
+       
+       // check if trackReco is compatible with trackRef
+       Int_t n = 0;
+       if (trackReco->Match(*trackRef, sigmaCut, nMatchClusters)) {
+         trackMatched = trackReco;
+         nMatchClusters = n;
+         break;
+       }
+       
       }
       
-      hTestTrack->Fill(testTrack);
-      trackID = trackRef->GetTrackID();
-      hTrackRefID->Fill(trackID);
-      
-      if (testTrack == 4) {     // tracking requirements verified, track is found
+      if (trackMatched) { // tracking requirements verified, track is found
         nReconstructibleTracksCheck++;
-        hNHitComp->Fill(nHitOK);
+        hNClusterComp->Fill(nMatchClusters);
         trackParam = trackRef->GetTrackParamAtVertex();
         x1 = trackParam->GetNonBendingCoor();
         y1 = trackParam->GetBendingCoor();
@@ -161,11 +177,10 @@ void MUONRecoCheck (Int_t nEvent = 1, char* geoFilename = "geometry.root",
         pY1 = trackParam->Py();
         pZ1 = trackParam->Pz();
         p1  = trackParam->P();
+        pT1 = TMath::Sqrt(pX1*pX1 + pY1*pY1);
         
         //     printf(" Ref. track at vertex: x,y,z: %f %f %f px,py,pz,p: %f %f %f %f \n",x1,y1,z1,pX1,pY1,pZ1,p1);
-        trackReco = trackOK;
-        trackParam = new AliMUONTrackParam(*((AliMUONTrackParam*)(trackReco->GetTrackParamAtHit()->First())));
-        AliMUONTrackExtrap::ExtrapToVertex(trackParam,x1,y1,z1);
+       trackParam = trackMatched->GetTrackParamAtVertex();
         x2 = trackParam->GetNonBendingCoor();
         y2 = trackParam->GetBendingCoor();
         z2 = trackParam->GetZ();
@@ -173,13 +188,13 @@ void MUONRecoCheck (Int_t nEvent = 1, char* geoFilename = "geometry.root",
         pY2 = trackParam->Py();
         pZ2 = trackParam->Pz();
         p2  = trackParam->P();
-        delete trackParam;
+        pT2 = TMath::Sqrt(pX2*pX2 + pY2*pY2);
         //     printf(" Reconst. track at vertex: x,y,z: %f %f %f px,py,pz: %f %f %f %f \n",x2,y2,z2,pX2,pY2,pZ2,p2);
         
         hResMomVertex->Fill(p2-p1);
-        
-        trackParamAtHit =  trackRef->GetTrackParamAtHit();
-        trackParam = (AliMUONTrackParam*) trackParamAtHit->First();
+       hResMomVertexVsMom->Fill(p1,p2-p1);
+       
+        trackParam = (AliMUONTrackParam*) trackRef->GetTrackParamAtCluster()->First();
         x1 = trackParam->GetNonBendingCoor();
         y1 = trackParam->GetBendingCoor();
         z1 = trackParam->GetZ();
@@ -187,9 +202,10 @@ void MUONRecoCheck (Int_t nEvent = 1, char* geoFilename = "geometry.root",
         pY1 = trackParam->Py();
         pZ1 = trackParam->Pz();
         p1  = trackParam->P();
-        //     printf(" Ref. track at 1st hit: x,y,z: %f %f %f px,py,pz: %f %f %f \n",x1,y1,z1,pX1,pY1,pZ1);
-        trackParamAtHit =  trackOK->GetTrackParamAtHit();
-        trackParam = (AliMUONTrackParam*) trackParamAtHit->First();
+        pT1 = TMath::Sqrt(pX1*pX1 + pY1*pY1);
+       
+        //     printf(" Ref. track at 1st cluster: x,y,z: %f %f %f px,py,pz: %f %f %f \n",x1,y1,z1,pX1,pY1,pZ1);
+        trackParam = (AliMUONTrackParam*) trackMatched->GetTrackParamAtCluster()->First();
         x2 = trackParam->GetNonBendingCoor();
         y2 = trackParam->GetBendingCoor();
         z2 = trackParam->GetZ();
@@ -197,50 +213,83 @@ void MUONRecoCheck (Int_t nEvent = 1, char* geoFilename = "geometry.root",
         pY2 = trackParam->Py();
         pZ2 = trackParam->Pz();
         p2  = trackParam->P();
-        //     printf(" Reconst. track at 1st hit: x,y,z: %f %f %f px,py,pz: %f %f %f \n",x2,y2,z2,pX2,pY2,pZ2);
+        pT2 = TMath::Sqrt(pX2*pX2 + pY2*pY2);
+        //     printf(" Reconst. track at 1st cluster: x,y,z: %f %f %f px,py,pz: %f %f %f \n",x2,y2,z2,pX2,pY2,pZ2);
         
-        hResMomFirstHit->Fill(p2-p1);
-              
+        hResMomFirstCluster->Fill(p2-p1);
+       hResMomFirstClusterVsMom->Fill(p1,p2-p1);
+       
+       // Fill residuals
+       // Loop over clusters of first track
+       AliMUONTrackParam* trackParamAtCluster1 = (AliMUONTrackParam*) trackMatched->GetTrackParamAtCluster()->First();
+       while (trackParamAtCluster1) {
+         AliMUONVCluster* cluster1 = trackParamAtCluster1->GetClusterPtr();
+         AliMUONTrackParam* trackParamAtCluster2 = (AliMUONTrackParam*) trackRef->GetTrackParamAtCluster()->First();
+         while (trackParamAtCluster2) {
+           AliMUONVCluster* cluster2 = trackParamAtCluster2->GetClusterPtr();
+           if (cluster1->GetDetElemId() == cluster2->GetDetElemId()) {
+             hResidualXInCh[cluster1->GetChamberId()]->Fill(cluster1->GetX() - cluster2->GetX());
+             hResidualYInCh[cluster1->GetChamberId()]->Fill(cluster1->GetY() - cluster2->GetY());
+             break;
+           }
+           trackParamAtCluster2 = (AliMUONTrackParam*) trackRef->GetTrackParamAtCluster()->After(trackParamAtCluster2);
+         }
+         trackParamAtCluster1 = (AliMUONTrackParam*) trackMatched->GetTrackParamAtCluster()->After(trackParamAtCluster1);
+       }
+       
       }
+      
     } // end loop track ref.
 
   } // end loop on event  
   
-  delete field;
+  // compute momentum resolution versus p
+  for (Int_t i = 1; i <= hResMomVertexVsMom->GetNbinsX(); i++) {
+    TH1D *tmp = hResMomVertexVsMom->ProjectionY("tmp",i,i,"e");
+    Double_t p = hResMomVertexVsMom->GetBinCenter(i);
+    gResMomVertexVsMom->SetPoint(i-1,p,100.*tmp->GetRMS()/p);
+    gResMomVertexVsMom->SetPointError(i-1,hResMomVertexVsMom->GetBinWidth(i)/2.,100.*tmp->GetRMSError()/p);
+    delete tmp;
+  }
+  for (Int_t i = 1; i <= hResMomFirstClusterVsMom->GetNbinsX(); i++) {
+    TH1D *tmp = hResMomFirstClusterVsMom->ProjectionY("tmp",i,i,"e");
+    Double_t p = hResMomFirstClusterVsMom->GetBinCenter(i);
+    f->SetParameters(1.,0.,1.);
+    f->SetParLimits(0,0.,1.e3);
+    tmp->Fit("f","WWN");
+    gResMomFirstClusterVsMom->SetPoint(i-1,p,100.*f->GetParameter(2)/p);
+    gResMomFirstClusterVsMom->SetPointError(i-1,hResMomFirstClusterVsMom->GetBinWidth(i)/2.,100.*f->GetParError(2)/p);
+    delete tmp;
+  }
+  
+  // compute residual mean and dispersion
+  for (Int_t i = 0; i < AliMUONConstants::NTrackingCh(); i++) {
+    hResidualXInCh[i]->GetXaxis()->SetRangeUser(-3.*hResidualXInCh[i]->GetRMS(), 3.*hResidualXInCh[i]->GetRMS());
+    gResidualXPerChMean->SetPoint(i, i+1, hResidualXInCh[i]->GetMean());
+    gResidualXPerChMean->SetPointError(i, 0., hResidualXInCh[i]->GetMeanError());
+    gResidualXPerChSigma->SetPoint(i, i+1, hResidualXInCh[i]->GetRMS());
+    gResidualXPerChSigma->SetPointError(i, 0., hResidualXInCh[i]->GetRMSError());
+    hResidualXInCh[i]->GetXaxis()->SetRange(0,0);
+    hResidualYInCh[i]->GetXaxis()->SetRangeUser(-3.*hResidualYInCh[i]->GetRMS(), 3.*hResidualYInCh[i]->GetRMS());
+    gResidualYPerChMean->SetPoint(i, i+1, hResidualYInCh[i]->GetMean());
+    gResidualYPerChMean->SetPointError(i, 0., hResidualYInCh[i]->GetMeanError());
+    gResidualYPerChSigma->SetPoint(i, i+1, hResidualYInCh[i]->GetRMS());
+    gResidualYPerChSigma->SetPointError(i, 0., hResidualYInCh[i]->GetRMSError());
+    hResidualYInCh[i]->GetXaxis()->SetRange(0,0);
+  }
   
   printf(" nb of reconstructible tracks: %d \n", nReconstructibleTracks);
   printf(" nb of reconstructed tracks: %d \n", nReconstructedTracks);
   printf(" nb of reconstructible tracks which are reconstructed: %d \n", nReconstructibleTracksCheck);
   
   histoFile->Write();
+  histoFile->cd();
+  gResMomVertexVsMom->Write();
+  gResMomFirstClusterVsMom->Write();
+  gResidualXPerChMean->Write();
+  gResidualXPerChSigma->Write();
+  gResidualYPerChMean->Write();
+  gResidualYPerChSigma->Write();
   histoFile->Close();
 }
 
-
-Int_t TrackCheck( Bool_t *compTrack)
-{
-  // Apply reconstruction requirements
-  // Return number of validated conditions 
-  // If all the tests are verified then TrackCheck = 4 (good track)
-  Int_t iTrack = 0;
-  Int_t hitsInLastStations = 0;
-  
-  // apply reconstruction requirements
-  if (compTrack[0] || compTrack[1]) iTrack++; // at least one hit in st. 0
-  if (compTrack[2] || compTrack[3]) iTrack++; // at least one hit in st. 1
-  if (compTrack[4] || compTrack[5]) iTrack++; // at least one hit in st. 2
-  for (Int_t ch = 6; ch < AliMUONConstants::NTrackingCh(); ch++) {
-    if (compTrack[ch]) hitsInLastStations++; 
-  }
-  if (hitsInLastStations > 2) iTrack++; // at least 3 hits in st. 3 & 4
-  
-  return iTrack;
-  
-}
-
-
-
-
-
-
-