The changes to perform the trigger chamber efficiency determination from ESD
authorivana <ivana@f7af4fe6-9843-0410-8265-dc069ae4e863>
Tue, 11 Dec 2007 16:28:02 +0000 (16:28 +0000)
committerivana <ivana@f7af4fe6-9843-0410-8265-dc069ae4e863>
Tue, 11 Dec 2007 16:28:02 +0000 (16:28 +0000)
(without any modification of AliESDMuonTrack):
- Using the remaining 8 bits (only 7 bits needed for this purpose) of the
  trigger chamber hit pattern, which is already in the AliESDMuonTrack,
  defined as an UShort_t of 16 bits.
- Also included lots of changes in AliMUONTrackHitPattern and
  AliMUONTriggerEfficiencyCells (in this last class, just removed the data
  members and method for the original trigger efficiency calculation, which
  were not depending on local boards. In this way the calibration object gets a
  considerable reduction in size.
(Diego)

12 files changed:
MUON/AliMUONReconstructor.cxx
MUON/AliMUONReconstructor.h
MUON/AliMUONTrackHitPattern.cxx
MUON/AliMUONTrackHitPattern.h
MUON/AliMUONTracker.cxx
MUON/AliMUONTracker.h
MUON/AliMUONTriggerEfficiencyCells.cxx
MUON/AliMUONTriggerEfficiencyCells.h
MUON/AliMUONVTrackReconstructor.cxx
MUON/Calib/TriggerEfficiency/Run0_99999999_v0_s0.root
MUON/MUONrecLinkDef.h
MUON/libMUONrec.pkg

index 0ddd4ebe331d22bee7d45aa9d40e72f21102c96a..f47a7558b7e5a52a85f9fb7072a17eb535d78054 100644 (file)
@@ -90,7 +90,6 @@
 #include "AliMUONRecoParam.h"
 #include "AliMUONSimpleClusterServer.h"
 #include "AliMUONTracker.h"
-#include "AliMUONTriggerChamberEff.h"
 #include "AliMUONTriggerCircuit.h"
 #include "AliMUONTriggerCrateStore.h"
 #include "AliMUONTriggerStoreV1.h"
@@ -132,8 +131,7 @@ fCalibrationData(0x0),
 fDigitCalibrator(0x0),
 fClusterServer(0x0),
 fTriggerStore(0x0),
-fTrackStore(0x0),
-fTrigChamberEff(0x0)
+fTrackStore(0x0)
 {
   /// normal ctor
 
@@ -161,7 +159,6 @@ AliMUONReconstructor::~AliMUONReconstructor()
   delete fClusterServer;
   delete fTriggerStore;
   delete fTrackStore;
-  delete fTrigChamberEff;
 }
 
 //_____________________________________________________________________________
@@ -294,19 +291,6 @@ AliMUONReconstructor::CreateTriggerCircuit() const
 
 }
 
-//_____________________________________________________________________________
-void
-AliMUONReconstructor::CreateTriggerChamberEff() const
-{
-  /// Create (and create if necessary) the trigger chamber efficiency class
-  if (fTrigChamberEff) return;
-
-  AliCodeTimerAuto("")
-
-  fTrigChamberEff = new AliMUONTriggerChamberEff(fTransformer,fDigitMaker,kTRUE);
-  //fTrigChamberEff->SetDebugLevel(1);
-}
-
 //_____________________________________________________________________________
 AliTracker* 
 AliMUONReconstructor::CreateTracker() const
@@ -315,7 +299,6 @@ AliMUONReconstructor::CreateTracker() const
   
   CreateTriggerCircuit();
   CreateDigitMaker();
-  CreateTriggerChamberEff();
   CreateClusterServer();
   
   if (!fClusterServer) 
@@ -329,8 +312,7 @@ AliMUONReconstructor::CreateTracker() const
   AliMUONTracker* tracker = new AliMUONTracker(*fClusterServer,
                                                fDigitMaker,
                                                fTransformer,
-                                               fTriggerCircuit,
-                                               fTrigChamberEff);
+                                               fTriggerCircuit);
   
   return tracker;
 }
index d8d0fa997d6da643288deedc36010effc305c094..62a7b3aa191c6cc6359ac325237838403465cc35 100644 (file)
@@ -33,8 +33,6 @@ class AliMUONCalibrationData;
 class AliMUONTracker;
 class AliMUONVTrackStore;
 
-class AliMUONTriggerChamberEff;
-
 class AliMUONRecoParam;
 
 class AliMUONVClusterFinder;
@@ -75,7 +73,6 @@ private:
   void CreateDigitMaker() const;
   void CreateTriggerCircuit() const;
   void CreateClusterServer() const;
-  void CreateTriggerChamberEff() const;
   void FillTreeR(AliMUONVTriggerStore* triggerStore,
                  TTree& clustersTree) const;
   
@@ -93,11 +90,10 @@ private:
   mutable AliMUONVClusterServer* fClusterServer; //!<  Clusterizer
   mutable AliMUONVTriggerStore* fTriggerStore; //!< Trigger container
   mutable AliMUONVTrackStore* fTrackStore; //!< Track container
-  mutable AliMUONTriggerChamberEff* fTrigChamberEff; //!< pointer to trigger chamber efficiency class
   
   static AliMUONRecoParam* fgRecoParam; //!< parameters used to tune the MUON reconstruction
   
-  ClassDef(AliMUONReconstructor,4) // Implementation of AliReconstructor
+  ClassDef(AliMUONReconstructor,5) // Implementation of AliReconstructor
 };
 
 #endif
index 3a77b9041d5919f18e81f8195b375a0ba1b861d2..3049b0c72524da6386d97806f2da41d6c699d2dc 100644 (file)
@@ -20,7 +20,7 @@
 /// \class AliMUONTrackHitPattern
 ///
 /// This class propagates tracks to trigger chambers 
-/// searching for fired strips.
+/// searching for matching trigger tracks and fired strips.
 ///
 /// To each track, a hit pattern for trigger chambers is set.
 /// The hit pattern is a UShort_t with 8 bits used:
@@ -32,7 +32,7 @@
 /// cathode:    bending   | non-bending
 ///                                                                      </pre>
 /// The main method is:
-/// * GetHitPattern
+/// * ExecuteValidation
 ///
 ///  \author Diego Stocco
 //-----------------------------------------------------------------------------
 #include "AliMpDEManager.h"
 #include "AliMUONReconstructor.h"
 #include "AliMUONRecoParam.h"
+#include "AliMUONTriggerTrack.h"
+#include "AliMUONVTriggerTrackStore.h"
+
+#include "AliMpConstants.h"
 
 #include "AliMagF.h"
 #include "AliLog.h"
 #include <TClonesArray.h>
 #include <TMath.h>
 #include <TMatrixD.h>
+#include <TROOT.h>
+#include <TDirectory.h>
+#include <TFile.h>
+#include <TSystem.h>
+
+#include <cassert>
 
 /// \cond CLASSIMP
 ClassImp(AliMUONTrackHitPattern) // Class implementation in ROOT context
@@ -79,9 +89,11 @@ AliMUONTrackHitPattern::AliMUONTrackHitPattern(const AliMUONGeometryTransformer&
                                                const AliMUONDigitMaker& digitMaker)
     : TObject(),
       fTransformer(transformer),
-      fDigitMaker(digitMaker)
+      fDigitMaker(digitMaker),
+      fkMaxDistance(99999.)
 {
     /// Default constructor
+    InitMembers();
 
     // Set magnetic field
     const AliMagF* kField = AliTracker::GetFieldMap();
@@ -94,53 +106,351 @@ AliMUONTrackHitPattern::AliMUONTrackHitPattern(const AliMUONGeometryTransformer&
 AliMUONTrackHitPattern::~AliMUONTrackHitPattern(void)
 {
   /// Destructor
+  delete fTrigCovariance;
+  for(Int_t cath=0; cath<fgkNcathodes; cath++){
+    delete fPadFired[cath];
+  }
 }
 
 
 //______________________________________________________________________________
-void AliMUONTrackHitPattern::GetHitPattern(AliMUONVTrackStore& trackStore,
-                                           const AliMUONVTriggerStore& triggerStore) const
+void AliMUONTrackHitPattern::InitMembers()
 {
-    //
-    /// Main method:
-    /// Loops on reco tracks, extrapolates them to trigger chambers
-    /// and searches for matching digits
-    //
+  //
+  /// Initialize data members
+  //
+  fDeltaZ = TMath::Abs(AliMUONConstants::DefaultChamberZ(12) - AliMUONConstants::DefaultChamberZ(10));
+
+  const Double_t kTrigNonBendReso = AliMUONConstants::TriggerNonBendingReso();
+  const Double_t kTrigBendReso = AliMUONConstants::TriggerBendingReso();
+  const Double_t kTrigSlopeBendReso = 1.414 * AliMUONConstants::TriggerBendingReso()/fDeltaZ;
+  const Double_t kTrigCovSlopeBend = - kTrigBendReso * kTrigBendReso / fDeltaZ;
+
+  // Covariance matrix 3x3 (X,Y,slopeY) for trigger tracks
+  fTrigCovariance = new TMatrixD(3,3);
+  fTrigCovariance->Zero();
+  (*fTrigCovariance)(0,0) = kTrigNonBendReso * kTrigNonBendReso;
+  (*fTrigCovariance)(1,1) = kTrigBendReso * kTrigBendReso;
+  (*fTrigCovariance)(2,2) = kTrigSlopeBendReso * kTrigSlopeBendReso;
+  (*fTrigCovariance)(1,2) = (*fTrigCovariance)(2,1) = kTrigCovSlopeBend;
+
+  const Int_t kMaxNpads[fgkNcathodes] = {GetMaxX(0)*GetMaxY(0), GetMaxX(1)*GetMaxY(1)};
+  Char_t histoName[40];
+  Char_t *cathCode[fgkNcathodes] = {"bendPlane", "nonBendPlane"};
+
+  const Int_t kNslats = 18;
+
+  for(Int_t cath=0; cath<fgkNcathodes; cath++){
+    sprintf(histoName, "fPadFired%s", cathCode[cath]);
+    fPadFired[cath] = new TH3F(histoName, histoName,
+                              fgkNchambers, -0.5, (Float_t)fgkNchambers - 0.5,
+                              kNslats, -0.5, (Float_t)kNslats - 0.5,
+                              kMaxNpads[cath], -0.5, (Float_t)kMaxNpads[cath] - 0.5);
+  }
+}
 
-    const Int_t kMask[2][4]= {{0x80, 0x40, 0x20, 0x10},
-                              {0x08, 0x04, 0x02, 0x01}};
-    Bool_t isMatch[2];
 
-    UShort_t pattern=0;
-    
-    AliMUONDigitStoreV1 digitStore;
+//_____________________________________________________________________________
+void AliMUONTrackHitPattern::CheckConstants() const
+{
+/// Check consistence of redefined constants 
+
+  assert(fgkNcathodes == AliMpConstants::NofCathodes());    
+  assert(fgkNchambers == AliMpConstants::NofTriggerChambers());    
+  assert(fgkNplanes == AliMpConstants::NofTriggerChambers() * fgkNcathodes);    
+}
+
+
+//______________________________________________________________________________
+void AliMUONTrackHitPattern::ExecuteValidation(AliMUONVTrackStore& trackStore,
+                                              const AliMUONVTriggerTrackStore& triggerTrackStore,
+                                              const AliMUONVTriggerStore& triggerStore) const
+{
+  //
+  /// Main method:
+  /// Loops on reco tracks, extrapolates them to trigger chambers
+  /// and searches for matching trigger tracks and digits
+  //
+
+  AliMUONDigitStoreV1 digitStore;
+  TriggerDigits(triggerStore,digitStore);
+
+
+  TIter itTrack(trackStore.CreateIterator());
+  AliMUONTrack* track;
+
+  const Int_t kFirstTrigCh = AliMUONConstants::NTrackingCh();
+
+  while ( ( track = static_cast<AliMUONTrack*>(itTrack()) ) )
+  { 
+    AliMUONTrackParam trackParam(*((AliMUONTrackParam*) (track->GetTrackParamAtCluster()->Last())));
+
+    ApplyMCSCorrections(trackParam);
+    AliMUONTrackExtrap::ExtrapToZCov(&trackParam, AliMUONConstants::DefaultChamberZ(kFirstTrigCh)); // extrap to 1st trigger chamber
+
+    AliMUONTriggerTrack *matchedTriggerTrack = MatchTriggerTrack(track, trackParam, triggerTrackStore, triggerStore);
+
+    UShort_t pattern = GetHitPattern(trackParam, matchedTriggerTrack, digitStore);
+    track->SetHitsPatternInTrigCh(pattern);
+  }
+}
+
+
+//______________________________________________________________________________
+AliMUONTriggerTrack * 
+AliMUONTrackHitPattern::MatchTriggerTrack(AliMUONTrack* track,
+                                         AliMUONTrackParam& trackParam,
+                                         const AliMUONVTriggerTrackStore& triggerTrackStore,
+                                         const AliMUONVTriggerStore& triggerStore) const
+{
+  //
+  /// Match track with trigger track
+  //
+
+  Int_t matchTrigger = 0;
+  Int_t loTrgNum(-1);
+  Double_t distTriggerTrack[3], sigma2[3];
+  Double_t chi2;
+  Double_t chi2MatchTrigger = 0., minChi2MatchTrigger = 999.;
+  Int_t doubleMatch = -1; // Check if track matches 2 trigger tracks
+  Double_t doubleChi2 = -1.;
+  AliMUONTriggerTrack* doubleTriggerTrack = 0x0;
+  AliMUONTriggerTrack* matchedTriggerTrack = 0x0;
     
-    TriggerDigits(triggerStore,digitStore);
+  const TMatrixD& kParamCov = trackParam.GetCovariances();
     
-    AliMUONTrack* muonTrack;
-    TIter next(trackStore.CreateIterator());
+  Double_t xTrack = trackParam.GetNonBendingCoor();
+  Double_t yTrack = trackParam.GetBendingCoor();
+  Double_t ySlopeTrack = trackParam.GetBendingSlope();
+
+  // Covariance matrix 3x3 (X,Y,slopeY) for tracker tracks
+  TMatrixD trackCov(3,3);
+  trackCov.Zero();
+  trackCov(0,0) = kParamCov(0,0);
+  trackCov(1,1) = kParamCov(2,2);
+  trackCov(2,2) = kParamCov(3,3);
+  trackCov(1,2) = kParamCov(2,3);
+  trackCov(2,1) = kParamCov(3,2);
+
+  TMatrixD sumCov(trackCov,TMatrixD::kPlus,*fTrigCovariance);
+
+  Bool_t isCovOK = kTRUE;
+
+  if (sumCov.Determinant() != 0) {
+    sumCov.Invert();
+  } else {
+    AliWarning(" Determinant = 0");
+    isCovOK = kFALSE;
+    sigma2[0] = kParamCov(0,0);
+    sigma2[1] = kParamCov(2,2);
+    sigma2[2] = kParamCov(3,3);
+    // sigma of distributions (trigger-track) X,Y,slopeY
+    const Double_t kDistSigma[3]={AliMUONConstants::TriggerNonBendingReso(),
+                                 AliMUONConstants::TriggerBendingReso(),
+                                 1.414 * AliMUONConstants::TriggerBendingReso()/fDeltaZ};
+    for (Int_t iVar = 0; iVar < 3; iVar++) sigma2[iVar] += kDistSigma[iVar] * kDistSigma[iVar];
+  }
 
-    const Int_t kNTrackingCh = AliMUONConstants::NTrackingCh();
+  AliMUONTriggerTrack *triggerTrack;
+  TIter itTriggerTrack(triggerTrackStore.CreateIterator());
+  while ( ( triggerTrack = static_cast<AliMUONTriggerTrack*>(itTriggerTrack() ) ) )
+  {
+    distTriggerTrack[0] = triggerTrack->GetX11() - xTrack;
+    distTriggerTrack[1] = triggerTrack->GetY11() - yTrack;
+    distTriggerTrack[2] = TMath::Tan(triggerTrack->GetThetay()) - ySlopeTrack;
+
+    if(isCovOK){
+      TMatrixD paramDiff(3,1);
+      for(Int_t iVar = 0; iVar < 3; iVar++)
+       paramDiff(iVar,0) = distTriggerTrack[iVar];
+       
+      TMatrixD tmp(sumCov,TMatrixD::kMult,paramDiff);
+      TMatrixD chi2M(paramDiff,TMatrixD::kTransposeMult,tmp);
+      chi2 = chi2M(0,0);
+    }
+    else {
+      chi2 = 0.;
+      for (Int_t iVar = 0; iVar < 3; iVar++) chi2 += distTriggerTrack[iVar]*distTriggerTrack[iVar]/sigma2[iVar];
+    }
 
-    while ( ( muonTrack = static_cast<AliMUONTrack*>(next()) ) )
+    chi2 /= 3.; // Normalized Chi2: 3 degrees of freedom (X,Y,slopeY)
+    if (chi2 < AliMUONReconstructor::GetRecoParam()->GetMaxNormChi2MatchTrigger()) 
     {
-      pattern = 0;
-      AliMUONTrackParam trackParam(*((AliMUONTrackParam*) (muonTrack->GetTrackParamAtCluster()->Last())));
-
-      ApplyMCSCorrections(trackParam);
-
-      for(Int_t ch=0; ch<4; ++ch)
+      Bool_t isDoubleTrack = (TMath::Abs(chi2 - minChi2MatchTrigger)<1.);
+      if (chi2 < minChi2MatchTrigger && chi2 < AliMUONReconstructor::GetRecoParam()->GetMaxNormChi2MatchTrigger()) 
       {
-       Int_t iChamber = kNTrackingCh+ch;
-        AliMUONTrackExtrap::ExtrapToZCov(&trackParam, AliMUONConstants::DefaultChamberZ(iChamber));
-        FindPadMatchingTrack(digitStore, trackParam, isMatch, iChamber);
-        for(Int_t cath=0; cath<2; ++cath)
-        {
-          if(isMatch[cath]) pattern |= kMask[cath][ch];
+       if(isDoubleTrack)
+       {
+         doubleMatch = loTrgNum;
+         doubleChi2 = chi2MatchTrigger;
+         doubleTriggerTrack = matchedTriggerTrack;
        }
+       minChi2MatchTrigger = chi2;
+       chi2MatchTrigger = chi2;
+       loTrgNum = triggerTrack->GetLoTrgNum();
+       matchedTriggerTrack = triggerTrack;
+       AliMUONLocalTrigger* locTrg = triggerStore.FindLocal(loTrgNum);
+       matchTrigger = 1;
+       if(locTrg->LoLpt()>0) matchTrigger = 2;
+       if(locTrg->LoHpt()>0) matchTrigger = 3;
+      }
+      else if(isDoubleTrack) 
+      {
+       doubleMatch = triggerTrack->GetLoTrgNum();
+       doubleChi2 = chi2;
       }
-      muonTrack->SetHitsPatternInTrigCh(pattern);
     }
+  }
+  if(doubleMatch>=0)
+  { // If two trigger tracks match, select the one passing more trigger cuts
+    AliDebug(1, Form("Two candidates found: %i and %i",loTrgNum,doubleMatch));
+    AliMUONLocalTrigger* locTrg1 = triggerStore.FindLocal(doubleMatch);
+    if((locTrg1->LoLpt()>0 && matchTrigger<2) || (locTrg1->LoHpt() && matchTrigger<3))
+    {
+      if(locTrg1->LoHpt()>0) matchTrigger=3;
+      else matchTrigger = 2;
+      loTrgNum = doubleMatch;
+      chi2MatchTrigger = doubleChi2;
+      matchedTriggerTrack = doubleTriggerTrack;
+    }
+  }
+    
+  track->SetMatchTrigger(matchTrigger);
+  track->SetLoTrgNum(loTrgNum);
+  track->SetChi2MatchTrigger(chi2MatchTrigger);
+
+  AliMUONLocalTrigger* locTrg = static_cast<AliMUONLocalTrigger*>(triggerStore.FindLocal(loTrgNum));
+
+  if (locTrg)
+  {    
+    track->SetLocalTrigger(locTrg->LoCircuit(),
+                          locTrg->LoStripX(),
+                          locTrg->LoStripY(),
+                          locTrg->LoDev(),
+                          locTrg->LoLpt(),
+                          locTrg->LoHpt());
+  }
+
+  return matchedTriggerTrack;
+}
+
+
+//______________________________________________________________________________
+UShort_t AliMUONTrackHitPattern::GetHitPattern(AliMUONTrackParam &trackParam,
+                                              AliMUONTriggerTrack* matchedTriggerTrack,
+                                              AliMUONVDigitStore& digitStore) const
+{
+  //
+  /// Get hit pattern on trigger chambers for the current track
+  //
+  UShort_t pattern = 0;
+  Bool_t isMatch[2];
+  const Int_t kNTrackingCh = AliMUONConstants::NTrackingCh();
+
+  Bool_t patternFromTrigTrack = kFALSE;
+
+
+  // Calculate hit pattern from trigger track
+  if(matchedTriggerTrack){
+    patternFromTrigTrack = PerformTrigTrackMatch(pattern, matchedTriggerTrack, digitStore);
+  }
+
+  if(patternFromTrigTrack) return pattern;
+
+
+  // Calculate hit pattern from tracker track propagation
+  // if hit pattern from trigger track failed
+
+  for(Int_t ch=0; ch<4; ++ch)
+  {
+    Int_t iChamber = kNTrackingCh+ch;
+    AliMUONTrackExtrap::ExtrapToZCov(&trackParam, AliMUONConstants::DefaultChamberZ(iChamber));
+    FindPadMatchingTrack(digitStore, trackParam, isMatch, iChamber);
+    for(Int_t cath=0; cath<2; ++cath)
+    {
+      if(isMatch[cath]) SetBit(pattern, cath, ch);
+    }
+  }
+  return pattern;
+}
+
+
+//______________________________________________________________________________
+void AliMUONTrackHitPattern::SetBit(UShort_t& pattern, Int_t cathode, Int_t chamber) const
+{
+  //
+  /// Set hits pattern
+  //
+  const Int_t kMask[2][4]= {{0x80, 0x40, 0x20, 0x10},
+                           {0x08, 0x04, 0x02, 0x01}};
+  pattern |= kMask[cathode][chamber];
+}
+
+
+//______________________________________________________________________________
+void AliMUONTrackHitPattern::AddEffInfo(UShort_t& pattern, Int_t slat, Int_t effType) const
+{
+  //
+  /// Set info on efficiency calculation
+  //
+  pattern += effType << 8;
+  pattern += slat << 10;
+}
+
+
+//______________________________________________________________________________
+void 
+AliMUONTrackHitPattern::ApplyMCSCorrections(AliMUONTrackParam& trackParam) const
+{
+  //
+  /// Returns uncertainties on extrapolated position.
+  /// Takes into account Branson plane corrections in the iron wall.
+  //
+
+  const Float_t kZFilterOut = AliMUONConstants::MuonFilterZEnd();
+  const Float_t kFilterThickness = TMath::Abs(kZFilterOut-AliMUONConstants::MuonFilterZBeg()); // cm
+
+  AliMUONTrackExtrap::ExtrapToZCov(&trackParam, kZFilterOut); // Extrap to muon filter end
+  AliMUONTrackExtrap::AddMCSEffect(&trackParam, kFilterThickness, AliMUONConstants::MuonFilterX0()); // Add MCS effects
+  return;
+}
+
+
+//______________________________________________________________________________
+Bool_t 
+AliMUONTrackHitPattern::TriggerDigits(const AliMUONVTriggerStore& triggerStore,
+                                      AliMUONVDigitStore& digitStore) const
+{
+  //
+  /// make (S)Digit for trigger
+  //
+  
+  digitStore.Clear();
+  
+  AliMUONLocalTrigger* locTrg;
+  TIter next(triggerStore.CreateLocalIterator());
+  
+  while ( ( locTrg = static_cast<AliMUONLocalTrigger*>(next()) ) ) 
+  {
+    if (locTrg->IsNull()) continue;
+   
+    TArrayS xyPattern[2];
+    locTrg->GetXPattern(xyPattern[0]);
+    locTrg->GetYPattern(xyPattern[1]);
+
+    // do we need this ? (Ch.F.)
+//     for(Int_t cath=0; cath<2; ++cath)
+//     {
+//       for(Int_t ch=0; ch<4; ++ch)
+//       {
+//         if(xyPattern[cath][ch]==0) continue;
+//       }
+//     }
+    
+    Int_t nBoard = locTrg->LoCircuit();
+    fDigitMaker.TriggerDigits(nBoard, xyPattern, digitStore);
+  }
+  return kTRUE;
 }
 
 
@@ -151,7 +461,7 @@ AliMUONTrackHitPattern::FindPadMatchingTrack(AliMUONVDigitStore& digitStore,
                                              Bool_t isMatch[2], Int_t iChamber) const
 {
     //
-    /// Given track position, searches for matching digits.
+    /// Given the tracker track position, searches for matching digits.
     //
 
     Float_t minMatchDist[2];
@@ -159,7 +469,7 @@ AliMUONTrackHitPattern::FindPadMatchingTrack(AliMUONVDigitStore& digitStore,
     for(Int_t cath=0; cath<2; ++cath)
     {
       isMatch[cath]=kFALSE;
-      minMatchDist[cath]=9999.;
+      minMatchDist[cath]=fkMaxDistance/10.;
     }
 
     TIter next(digitStore.CreateIterator());
@@ -199,7 +509,7 @@ AliMUONTrackHitPattern::MinDistanceFromPad(Float_t xPad, Float_t yPad, Float_t z
                                            const AliMUONTrackParam& trackParam) const
 {
     //
-    /// Decides if the digit belongs to the track.
+    /// Decides if the digit belongs to the tracker track.
     //
 
     AliMUONTrackParam trackParamAtPadZ(trackParam);
@@ -221,64 +531,450 @@ AliMUONTrackHitPattern::MinDistanceFromPad(Float_t xPad, Float_t yPad, Float_t z
     Float_t deltaX = TMath::Abs(xPad-xTrackAtPad)-dpx;
     Float_t deltaY = TMath::Abs(yPad-yTrackAtPad)-dpy;
 
-    Float_t matchDist = 99999.;
+    Float_t matchDist = fkMaxDistance;
     if(deltaX<=maxDistX && deltaY<=maxDistY) matchDist = TMath::Max(deltaX, deltaY);
 
     return matchDist;
 }
 
 
-//______________________________________________________________________________
-void 
-AliMUONTrackHitPattern::ApplyMCSCorrections(AliMUONTrackParam& trackParam) const
+//_____________________________________________________________________________
+Int_t AliMUONTrackHitPattern::FindPadMatchingTrig(AliMUONVDigitStore& digitStore, Int_t &detElemId,
+                                                 Float_t coor[2], Bool_t isMatch[2],
+                                                 TArrayI nboard[2], TArrayF &zRealMatch, Float_t y11) const
+{
+    //
+    /// Check slat and board number of digit matching trigger track
+    //
+
+    enum {kBending, kNonBending};
+
+    Float_t minMatchDist[fgkNcathodes];
+    Int_t padsInCheckArea[fgkNcathodes];
+
+    for(Int_t cath=0; cath<fgkNcathodes; cath++){
+       isMatch[cath] = kFALSE;
+       minMatchDist[cath] = fkMaxDistance/10.;
+       padsInCheckArea[cath] = 0;
+    }
+    Int_t iChamber = AliMpDEManager::GetChamberId(detElemId);
+    Int_t ch = iChamber-10;
+    Float_t oldDeltaZ = AliMUONConstants::DefaultChamberZ(iChamber) - AliMUONConstants::DefaultChamberZ(10);
+    Float_t y = coor[1];
+    Int_t iSlat = detElemId%100;
+    Int_t trigDigitBendPlane = -1;
+    Int_t foundDetElemId = detElemId;
+    Float_t foundZmatch=999.;
+    Float_t yCoorAtPadZ=999.;
+
+    TIter next(digitStore.CreateIterator());
+    AliMUONVDigit* mDigit;
+    Int_t idigit=0;
+    
+    while ( ( mDigit = static_cast<AliMUONVDigit*>(next()) ) )
+    {
+       idigit++;
+       Int_t currDetElemId = mDigit->DetElemId();
+       Int_t currCh = AliMpDEManager::GetChamberId(currDetElemId);
+       if(currCh!=iChamber) continue;
+       Int_t currSlat = currDetElemId%100;
+       Int_t slatDiff = TMath::Abs(currSlat-iSlat);
+       if(slatDiff>1 && slatDiff<17) continue; // Check neighbour slats
+       Int_t cathode = mDigit->Cathode();
+       Int_t ix = mDigit->PadX();
+       Int_t iy = mDigit->PadY();
+       Float_t xpad, ypad, zpad;
+       const AliMpVSegmentation* seg = AliMpSegmentation::Instance()
+           ->GetMpSegmentation(currDetElemId,AliMp::GetCathodType(cathode));
+
+       AliMpPad pad = seg->PadByIndices(AliMpIntPair(ix,iy),kTRUE);
+       Float_t xlocal1 = pad.Position().X();
+       Float_t ylocal1 = pad.Position().Y();
+       Float_t dpx = pad.Dimensions().X();
+       Float_t dpy = pad.Dimensions().Y();
+       fTransformer.Local2Global(currDetElemId, xlocal1, ylocal1, 0, xpad, ypad, zpad);
+       AliDebug(2, Form("DetElemId = %i\tCathode = %i\t(x,y) Pad = (%i,%i) = (%.2f,%.2f)\tDim = (%.2f,%.2f)\tTrack = (%.2f,%.2f)\n",currDetElemId,cathode,ix,iy,xpad,ypad,dpx,dpy,coor[0],coor[1]));
+       // searching track intersection with chambers (second approximation)
+       if(ch%2==1){
+           //if(iChamber%2==1){
+           Float_t deltaZ = zpad - zRealMatch[0];
+           y = (coor[1]-y11)*deltaZ/oldDeltaZ + y11;
+           if(TMath::Abs(y-coor[1])>0.1) AliDebug(3, Form("oldDeltaZ = %7.2f   newDeltaZ = %7.2f\toldY = %7.2f   new y = %7.2f\n",oldDeltaZ,deltaZ,coor[1],y));
+       }
+       Float_t matchDist = PadMatchTrack(xpad, ypad, dpx, dpy, coor[0], y);
+       if(matchDist<fkMaxDistance/2.) padsInCheckArea[cathode]++;
+       if(matchDist>minMatchDist[cathode])continue;
+       isMatch[cathode] = kTRUE;
+       minMatchDist[cathode] = matchDist;
+       foundDetElemId = currDetElemId;
+       foundZmatch=zpad;
+       yCoorAtPadZ=y;
+       if(cathode==kBending) trigDigitBendPlane = idigit;
+       for (Int_t loc=0; loc<pad.GetNofLocations(); loc++){
+           AliMpIntPair location = pad.GetLocation(loc);
+           nboard[cathode][loc] = location.GetFirst();
+       }
+       for(Int_t loc=pad.GetNofLocations(); loc<fgkNlocations; loc++){
+           nboard[cathode][loc]=-1;
+       }
+
+       // Fired pads info
+       Int_t currPair = ix*GetMaxY(cathode) + iy;
+       fPadFired[cathode]->Fill(ch, currSlat, currPair);
+    }
+
+    for(Int_t cath=0; cath<fgkNcathodes; cath++){
+       if(padsInCheckArea[cath]>2) {
+         AliDebug(1, Form("padsInCheckArea[%i] = %i\n",cath,padsInCheckArea[cath]));
+           return -500;
+       }
+    }
+
+    if(isMatch[kBending] || isMatch[kNonBending]){
+       detElemId = foundDetElemId;
+       zRealMatch[ch] = foundZmatch;
+       coor[1] = yCoorAtPadZ;
+    }
+    return trigDigitBendPlane;
+}
+
+//_____________________________________________________________________________
+Float_t AliMUONTrackHitPattern::PadMatchTrack(Float_t xPad, Float_t yPad,
+                                               Float_t dpx, Float_t dpy, 
+                                               Float_t xTrackAtPad, Float_t yTrackAtPad) const
+{
+    //
+    /// Decides if the digit belongs to the trigger track.
+    //
+
+    Float_t maxDist = 2.;//3. // cm
+    Float_t maxDistCheckArea = 6.; // cm
+
+    Float_t matchDist = fkMaxDistance;
+
+    Float_t deltaX = TMath::Abs(xPad-xTrackAtPad)-dpx;
+    Float_t deltaY = TMath::Abs(yPad-yTrackAtPad)-dpy;
+    Float_t maxDistX = maxDist;
+    Float_t maxDistY = maxDist;
+
+    if(deltaX<=maxDistX && deltaY<=maxDistY) matchDist = TMath::Max(deltaX, deltaY);
+    else if(deltaX<=maxDistCheckArea && deltaY<=maxDistCheckArea) matchDist = fkMaxDistance/5.;
+    return matchDist;
+}
+
+
+//_____________________________________________________________________________
+Int_t AliMUONTrackHitPattern::DetElemIdFromPos(Float_t x, Float_t y, 
+                                                Int_t chamber, Int_t cathode) const
+{
+    //
+    /// Given the (x,y) position in the chamber,
+    /// it returns the corresponding slat
+    //
+
+    Int_t resultingDetElemId = -1;
+    AliMpDEIterator it;
+    Float_t minDist = 999.;
+    for ( it.First(chamber-1); ! it.IsDone(); it.Next() ){
+       Int_t detElemId = it.CurrentDEId();
+       Int_t ich = detElemId/100-10;
+       Float_t tolerance=0.2*((Float_t)ich);
+       Float_t currDist=9999.;
+
+       const AliMpVSegmentation* seg = 
+           AliMpSegmentation::Instance()
+           ->GetMpSegmentation(detElemId,AliMp::GetCathodType(cathode));
+       if (!seg) continue;
+
+       Float_t deltax = seg->Dimensions().X();
+       Float_t deltay = seg->Dimensions().Y();
+       Float_t xlocal1 =  -deltax;
+       Float_t ylocal1 =  -deltay;
+       Float_t xlocal2 =  +deltax;
+       Float_t ylocal2 =  +deltay;
+       Float_t xg01, yg01, zg1, xg02, yg02, zg2;
+       fTransformer.Local2Global(detElemId, xlocal1, ylocal1, 0, xg01, yg01, zg1);
+       fTransformer.Local2Global(detElemId, xlocal2, ylocal2, 0, xg02, yg02, zg2);
+
+       Float_t xg1 = xg01, xg2 = xg02, yg1 = yg01, yg2 = yg02;
+
+       if(xg01>xg02){
+           xg1 = xg02;
+           xg2 = xg01;
+       }
+       if(yg01>yg02){
+           yg1 = yg02;
+           yg2 = yg01;
+       }
+
+       if(x>=xg1-tolerance && x<=xg2+tolerance && y>=yg1-tolerance && y<=yg2+tolerance){ // takes into account errors in extrapolation
+           if(y<yg1) currDist = yg1-y;
+           else if(y>yg2) currDist = y-yg2;
+           if(currDist<minDist) {
+               resultingDetElemId = detElemId;
+               minDist=currDist;
+               continue;
+           }
+           resultingDetElemId = detElemId;
+           break;
+       }
+    } // loop on detElemId
+    return resultingDetElemId;
+}
+
+
+//_____________________________________________________________________________
+void AliMUONTrackHitPattern::LocalBoardFromPos(Float_t x, Float_t y,
+                                                Int_t detElemId, Int_t cathode,
+                                                Int_t localBoard[4]) const
+{
+    //
+    /// Given the (x,y) position in the chamber,
+    /// it returns the corresponding local board
+    //
+
+    for(Int_t loc=0; loc<fgkNlocations; loc++){
+       localBoard[loc]=-1;
+    }
+    Float_t xl, yl, zl;
+    fTransformer.Global2Local(detElemId, x, y, 0, xl, yl, zl);
+    TVector2 pos(xl,yl);
+    const AliMpVSegmentation* seg = 
+       AliMpSegmentation::Instance()
+          ->GetMpSegmentation(detElemId,AliMp::GetCathodType(cathode));
+    if (seg){
+       AliMpPad pad = seg->PadByPosition(pos,kFALSE);
+       for (Int_t loc=0; loc<pad.GetNofLocations(); loc++){
+           AliMpIntPair location = pad.GetLocation(loc);
+           localBoard[loc] = location.GetFirst();
+       }
+    }
+}
+
+
+//_____________________________________________________________________________
+Bool_t AliMUONTrackHitPattern::PerformTrigTrackMatch(UShort_t &pattern,
+                                                    AliMUONTriggerTrack *matchedTrigTrack,
+                                                    AliMUONVDigitStore& digitStore) const
 {
   //
-  /// Returns uncertainties on extrapolated position.
-  /// Takes into account Branson plane corrections in the iron wall.
+  /// It searches for matching digits around the trigger track.
   //
 
-  const Float_t kZFilterOut = AliMUONConstants::MuonFilterZEnd();
-  const Float_t kFilterThickness = TMath::Abs(kZFilterOut-AliMUONConstants::MuonFilterZBeg()); // cm
+  enum {kBending, kNonBending};
 
-  AliMUONTrackExtrap::ExtrapToZCov(&trackParam, kZFilterOut);
-  AliMUONTrackExtrap::AddMCSEffect(&trackParam, kFilterThickness, AliMUONConstants::MuonFilterX0());
-  return;
+  Int_t chOrder[fgkNchambers] = {0,2,1,3};
+
+  TArrayF zRealMatch(fgkNchambers);
+  TArrayF correctFactor(fgkNcathodes);
+
+  Bool_t isMatch[fgkNcathodes];
+  for(Int_t cath=0; cath<fgkNcathodes; cath++){
+    isMatch[cath] = kFALSE;
+  }
+
+  TArrayF zMeanChamber(fgkNchambers);
+  for(Int_t ch=0; ch<fgkNchambers; ch++){
+    zMeanChamber[ch] = AliMUONConstants::DefaultChamberZ(10+ch);
+  }
+
+  TArrayI digitPerTrack(fgkNcathodes);
+
+  Float_t trackIntersectCh[fgkNchambers][fgkNcathodes];
+
+  TArrayI triggeredDigits;
+  triggeredDigits.Set(fgkNchambers);
+  triggeredDigits.Reset(-1);
+
+  TArrayI trigScheme[fgkNcathodes];
+  TArrayI slatThatTriggered[fgkNcathodes];
+  for(Int_t cath=0; cath<fgkNcathodes; cath++){
+    trigScheme[cath].Set(fgkNchambers);
+    slatThatTriggered[cath].Set(fgkNchambers);
+  }
+
+  Int_t boardThatTriggered[fgkNchambers][fgkNcathodes][fgkNlocations];
+  TArrayI nboard[fgkNcathodes];
+  for(Int_t cath=0; cath<fgkNcathodes; cath++){
+    nboard[cath].Set(fgkNlocations);
+  }
+  Int_t ineffBoard[fgkNlocations];
+  for(Int_t loc=0; loc<fgkNlocations; loc++){
+    ineffBoard[loc] = -1;
+  }
+
+  digitPerTrack.Reset();
+  for(Int_t ch=0; ch<fgkNchambers; ch++){
+    zRealMatch[ch] = zMeanChamber[ch];
+    for(Int_t cath=0; cath<fgkNcathodes; cath++){
+      for(Int_t loc=0; loc<fgkNlocations; loc++){
+       boardThatTriggered[ch][cath][loc]=-1;
+      }
+    }
+  }
+
+  for(Int_t cath=0; cath<fgkNcathodes; cath++){
+    slatThatTriggered[cath].Reset(-1);
+    trigScheme[cath].Reset();
+  }
+
+  Bool_t isClearEvent = kTRUE;
+
+  //Float_t x11 = matchedTrigTrack->GetX11();// x position (info from non-bending plane)
+  Float_t y11 = matchedTrigTrack->GetY11();// y position (info from bending plane)
+  Float_t thetaX = matchedTrigTrack->GetThetax();
+  Float_t thetaY = matchedTrigTrack->GetThetay();
+
+  for(Int_t ch=0; ch<fgkNchambers; ch++) { // chamber loop
+    Int_t currCh = chOrder[ch];
+    AliDebug(2, Form("zMeanChamber[%i] = %.2f\tzRealMatch[0] = %.2f\n",currCh,zMeanChamber[currCh],zRealMatch[0]));
+
+    for(Int_t cath=0; cath<fgkNcathodes; cath++){
+      correctFactor[cath]=1.;
+    }
+    // calculate corrections to trigger track theta
+    if(ch>=1) correctFactor[kNonBending] = zMeanChamber[0]/zRealMatch[0];// corrects x position
+    if(ch>=2) correctFactor[kBending] = (zMeanChamber[2] - zMeanChamber[0]) / (zRealMatch[2] - zRealMatch[0]);// corrects y position
+
+    // searching track intersection with chambers (first approximation)
+    Float_t deltaZ = zMeanChamber[currCh] - zMeanChamber[0];
+    trackIntersectCh[currCh][0] = zMeanChamber[currCh] * TMath::Tan(thetaX) * correctFactor[kNonBending];// x position (info from non-bending plane) 
+    trackIntersectCh[currCh][1] = y11 + deltaZ * TMath::Tan(thetaY) * correctFactor[kBending];// y position (info from bending plane)
+    Int_t detElemIdFromTrack = DetElemIdFromPos(trackIntersectCh[currCh][0], trackIntersectCh[currCh][1], 11+currCh, 0);
+    if(detElemIdFromTrack<0) {
+      AliDebug(1, "Warning: trigger track outside trigger chamber\n");
+      continue;
+    }
+               
+    triggeredDigits[currCh] = FindPadMatchingTrig(digitStore, detElemIdFromTrack, trackIntersectCh[currCh], isMatch, nboard, zRealMatch, y11);
+
+    // if FindPadMatchingTrig = -500 => too many digits matching pad =>
+    //                               => Event not clear => Reject track
+    if(triggeredDigits[currCh]<-100){
+      isClearEvent = kFALSE;
+      AliDebug(1, Form("Warning: track = %p (%i) matches many pads. Rejected!\n",(void *)matchedTrigTrack, detElemIdFromTrack));
+      break;
+    }
+
+    for(Int_t cath=0; cath<fgkNcathodes; cath++){
+      if(!isMatch[cath]) continue;
+      SetBit(pattern, cath, currCh);
+      digitPerTrack[cath]++;
+      trigScheme[cath][currCh]++;
+      slatThatTriggered[cath][currCh] = detElemIdFromTrack;
+      for(Int_t loc=0; loc<fgkNlocations; loc++){
+       boardThatTriggered[currCh][cath][loc] = nboard[cath][loc];
+      }
+    }
+  } // end chamber loop
+
+  for(Int_t cath=0; cath<fgkNcathodes; cath++){
+    if(digitPerTrack[cath]<3) isClearEvent = kFALSE;
+    if(!isClearEvent) AliDebug(1, Form("Warning: found %i digits for trigger track cathode %i.\nRejecting event\n", digitPerTrack[cath],cath));
+  }
+
+  if(!isClearEvent) return kFALSE;
+
+  Int_t goodForEff = kBoardEff;
+
+  Int_t ineffSlat = -1;
+  Int_t ineffDetElId = -1;
+  Int_t firstSlat = slatThatTriggered[kBending][0]%100;
+  if(firstSlat<0) firstSlat = slatThatTriggered[kBending][1]%100;
+  Int_t firstBoard = boardThatTriggered[0][kBending][0];
+  if(firstBoard<0) firstBoard = boardThatTriggered[1][kBending][0];
+  for(Int_t ch=0; ch<fgkNchambers; ch++){
+    Bool_t isCurrChIneff = kFALSE;
+    Int_t currSlat = slatThatTriggered[kBending][ch]%100;
+    if(currSlat<0){
+      ineffDetElId = DetElemIdFromPos(trackIntersectCh[ch][0], trackIntersectCh[ch][1], 11+ch, kBending);
+      currSlat = ineffDetElId%100;
+      ineffSlat = currSlat;
+      isCurrChIneff = kTRUE;
+    }
+    if(currSlat!=firstSlat) {
+      AddEffInfo(pattern, 20, kChEff);
+      return kTRUE;
+    }
+    Bool_t atLeastOneLoc=kFALSE;
+    if(isCurrChIneff) LocalBoardFromPos(trackIntersectCh[ch][0], trackIntersectCh[ch][1], ineffDetElId, kBending, ineffBoard);
+    for(Int_t loc=0; loc<fgkNlocations; loc++){
+      Int_t currBoard = boardThatTriggered[ch][kBending][loc];
+      if(isCurrChIneff) currBoard = ineffBoard[loc];
+      if(currBoard==firstBoard){
+       atLeastOneLoc=kTRUE;
+       break;
+      }
+    }
+    if(!atLeastOneLoc) goodForEff = kSlatEff;
+  } // end chamber loop
+  
+  AddEffInfo(pattern, firstSlat, goodForEff);
+  return kTRUE;
 }
 
 
-//______________________________________________________________________________
-Bool_t 
-AliMUONTrackHitPattern::TriggerDigits(const AliMUONVTriggerStore& triggerStore,
-                                      AliMUONVDigitStore& digitStore) const
+//_____________________________________________________________________________
+void AliMUONTrackHitPattern::UpdateQA() const
 {
   //
-  /// make (S)Digit for trigger
+  /// Save map of fired strips in the QA file
   //
-  
-  digitStore.Clear();
-  
-  AliMUONLocalTrigger* locTrg;
-  TIter next(triggerStore.CreateLocalIterator());
-  
-  while ( ( locTrg = static_cast<AliMUONLocalTrigger*>(next()) ) ) 
-  {
-    if (locTrg->IsNull()) continue;
-   
-    TArrayS xyPattern[2];
-    locTrg->GetXPattern(xyPattern[0]);
-    locTrg->GetYPattern(xyPattern[1]);
 
-    // do we need this ? (Ch.F.)
-//     for(Int_t cath=0; cath<2; ++cath)
-//     {
-//       for(Int_t ch=0; ch<4; ++ch)
-//       {
-//         if(xyPattern[cath][ch]==0) continue;
-//       }
-//     }
+  TDirectory *dir = gDirectory;
+
+  TFile *logFile = 0x0;
+  TString logFileName;
+  Bool_t reopenFile = kFALSE;
+  TString baseFileName = "MUON.QA";
+  TString dirName = "EfficiencyRelated";
+
+  TSeqCollection *list = gROOT->GetListOfFiles();
+  Int_t n = list->GetEntries();
+  for(Int_t i=0; i<n; i++) {
+    logFile = (TFile*)list->At(i);
+    logFileName = logFile->GetName();
+    if (logFileName.Contains(baseFileName.Data())) break;
+    logFile = 0x0;
+  }
+
+  if(!logFile) {
+    void * dirp = gSystem->OpenDirectory(gSystem->pwd());
+    const char * name = 0x0;
+    // Add all files matching *pattern* to the chain
+    while((name = gSystem->GetDirEntry(dirp))) {
+      logFileName = name;
+      if (logFileName.Contains(baseFileName.Data())) {
+       logFile = new TFile(logFileName.Data(), "update");
+       AliWarning(Form("%s already stored on disk. Re-opening in update mode.",baseFileName.Data()));
+       break;
+      }
+      logFile = 0x0;
+    }//directory loop
+    reopenFile = kTRUE;
+  }
     
-    Int_t nBoard = locTrg->LoCircuit();
-    fDigitMaker.TriggerDigits(nBoard, xyPattern, digitStore);
+  if(logFile){
+    logFile->cd();
+    TDirectory *muonDir = (TDirectory*)logFile->Get("MUON");
+    muonDir->cd();
+    TDirectory *effDir = (TDirectory*)muonDir->Get(dirName.Data());
+    if(!effDir) {
+      effDir = muonDir->mkdir(dirName.Data());
+    }
+    effDir->cd();
+    TH3F *histo = 0x0;
+    for(Int_t cath=0; cath<fgkNcathodes; cath++){
+      histo = (TH3F*) effDir->Get(fPadFired[cath]->GetName());
+      if(!histo) histo = (TH3F*)fPadFired[cath]->Clone();
+      else histo->Add(fPadFired[cath]);
+      histo->Write(histo->GetName(), TObject::kOverwrite);
+    }
+    if(reopenFile){
+      logFile->Close();
+    }
   }
-  return kTRUE;
+  else AliWarning(Form("Map of strips entering efficiency calculation could not be found in %s", baseFileName.Data()));
+  dir->cd();
 }
+
index 2db13ebed70fe04113fc813f47b1872cc22b927a..280d7c88f0fd7ecb48f4a339945a2c1c37724f24 100644 (file)
 //  Author: Diego Stocco
 
 #include <TObject.h>
+#include <TMatrixD.h>
+#include <TArrayI.h>
+#include <TArrayF.h>
+#include <TH3.h>
 
 class AliMUONVTrackStore;
 class AliMUONVTriggerStore;
+class AliMUONVTriggerTrackStore;
 class AliMUONTrackParam;
 class AliMUONDigitMaker;
 class AliMUONGeometryTransformer;
 class AliMUONVDigitStore;
+class AliMUONTriggerTrack;
+class AliMUONTrack;
 
 class AliMUONTrackHitPattern : public TObject 
 {
@@ -27,33 +34,96 @@ public:
   AliMUONTrackHitPattern(const AliMUONGeometryTransformer& transformer,
                          const AliMUONDigitMaker& digitMaker);
   virtual ~AliMUONTrackHitPattern(); // Destructor
-    
-    void GetHitPattern(AliMUONVTrackStore& trackStore,
-                       const AliMUONVTriggerStore& triggerStore) const;
-    
-    void FindPadMatchingTrack(AliMUONVDigitStore& digitStore,
-                              const AliMUONTrackParam& trackParam,
-                              Bool_t isMatch[2], Int_t iChamber) const;
 
-    Float_t MinDistanceFromPad(Float_t xPad, Float_t yPad, Float_t zPad,
-                               Float_t dpx, Float_t dpy, 
-                               const AliMUONTrackParam& trackParam) const;
+  void ExecuteValidation(AliMUONVTrackStore& trackStore,
+                        const AliMUONVTriggerTrackStore& triggerTrackStore,
+                        const AliMUONVTriggerStore& triggerStore) const;
+  
+  AliMUONTriggerTrack* MatchTriggerTrack(AliMUONTrack* track,
+                                        AliMUONTrackParam& trackParam,
+                                        const AliMUONVTriggerTrackStore& triggerTrackStore,
+                                        const AliMUONVTriggerStore& triggerStore) const;
     
-    void ApplyMCSCorrections(AliMUONTrackParam& trackParam) const;
+  UShort_t GetHitPattern(AliMUONTrackParam& trackParam,
+                        AliMUONTriggerTrack* matchedTriggerTrack,
+                        AliMUONVDigitStore& digitStore) const;
+
+  void UpdateQA() const;
+
+protected:
+  void ApplyMCSCorrections(AliMUONTrackParam& trackParam) const;
+  
+  Bool_t TriggerDigits(const AliMUONVTriggerStore& triggerStore, 
+                      AliMUONVDigitStore& digitStore) const;
+
+  void InitMembers();
+  
+  void SetBit(UShort_t& pattern, Int_t cathode, Int_t chamber) const;
+  
+  void AddEffInfo(UShort_t& pattern, Int_t slat, Int_t effType) const;
+  
+
+  // Methods for hit pattern from tracker track
+  void FindPadMatchingTrack(AliMUONVDigitStore& digitStore,
+                           const AliMUONTrackParam& trackParam,
+                           Bool_t isMatch[2], Int_t iChamber) const;
+
+  Float_t MinDistanceFromPad(Float_t xPad, Float_t yPad, Float_t zPad,
+                            Float_t dpx, Float_t dpy, 
+                            const AliMUONTrackParam& trackParam) const;
 
-    Bool_t TriggerDigits(const AliMUONVTriggerStore& triggerStore, 
-                         AliMUONVDigitStore& digitStore) const;
+  // Methods for hit pattern from matched trigger track
+  Bool_t PerformTrigTrackMatch(UShort_t &pattern,
+                              AliMUONTriggerTrack *matchedTrigTrack,
+                              AliMUONVDigitStore& digitStore) const;
+  
+  Int_t FindPadMatchingTrig(AliMUONVDigitStore& digitStore, Int_t &detElemId, Float_t coor[2],
+                           Bool_t isMatch[2], TArrayI nboard[2],
+                           TArrayF &zRealMatch, Float_t y11) const;
+  
+  Float_t PadMatchTrack(Float_t xPad, Float_t yPad, Float_t dpx, Float_t dpy,
+                       Float_t xTrackAtPad, Float_t yTrackAtPad) const;
+  
+  Int_t DetElemIdFromPos(Float_t x, Float_t y, Int_t chamber, Int_t cathode) const;
+  
+  void LocalBoardFromPos(Float_t x, Float_t y, Int_t detElemId,
+                        Int_t cathode, Int_t localBoard[4]) const;
 
 private:
-    /// Not implemented
-    AliMUONTrackHitPattern(const AliMUONTrackHitPattern& rhs);
-    /// Not implemented
-    AliMUONTrackHitPattern& operator = (const AliMUONTrackHitPattern& rhs);
+  /// Not implemented
+  AliMUONTrackHitPattern(const AliMUONTrackHitPattern& rhs);
+  /// Not implemented
+  AliMUONTrackHitPattern& operator = (const AliMUONTrackHitPattern& rhs);
+
+  void CheckConstants() const;
+  /// Get max number of strips along x
+  Int_t GetMaxX(Int_t cath) const {return (cath==0) ? 7 : 112;}
+  /// Get max number of strips along x
+  Int_t GetMaxY(Int_t cath) const {return (cath==0) ? 64 : 1;}
+
+  const AliMUONGeometryTransformer& fTransformer; //!< geometry transformer
+  const AliMUONDigitMaker& fDigitMaker; //!< pointer to digit maker
+
+  Double_t fDeltaZ; //!< distance between stations
+
+  TMatrixD* fTrigCovariance; //!< Covariance matrix 3x3 (X,Y,slopeY) for trigger tracks
+
+  const Float_t fkMaxDistance; //!< Maximum distance for reference
+  static const Int_t fgkNcathodes=2; //!<Number of cathodes
+  static const Int_t fgkNchambers=4; //!<Number of chambers
+  static const Int_t fgkNplanes=8;   //!<Number of planes
+  static const Int_t fgkNlocations=4; //!<Number of locations
+
+  enum {
+    kNoEff,
+    kChEff,
+    kSlatEff,
+    kBoardEff
+  };
 
-    const AliMUONGeometryTransformer& fTransformer; //!< geometry transformer
-    const AliMUONDigitMaker& fDigitMaker; ///< pointer to digit maker
+  TH3F *fPadFired[fgkNcathodes]; ///< Histo counting the fired pads
 
-    ClassDef(AliMUONTrackHitPattern, 0) // MUON track hit pattern
+  ClassDef(AliMUONTrackHitPattern, 0) // MUON track hit pattern
 };
 
 #endif
index adfc1cafaa5517905226cd7f5f960c4d86c0ed8c..797b4dc8c4e274fe4be19f354df8c722b982298c 100644 (file)
@@ -44,7 +44,6 @@
 #include "AliMUONTrackReconstructor.h"
 #include "AliMUONTrackReconstructorK.h"
 #include "AliMUONTrackStoreV1.h"
-#include "AliMUONTriggerChamberEff.h"
 #include "AliMUONTriggerTrackStoreV1.h"
 #include "AliMUONClusterStoreV2.h"
 #include "AliMUONVTriggerStore.h"
@@ -68,13 +67,11 @@ ClassImp(AliMUONTracker)
 AliMUONTracker::AliMUONTracker(AliMUONVClusterServer& clusterServer,
                                const AliMUONDigitMaker* digitMaker,
                                const AliMUONGeometryTransformer* transformer,
-                               const AliMUONTriggerCircuit* triggerCircuit,
-                               AliMUONTriggerChamberEff* chamberEff)
+                               const AliMUONTriggerCircuit* triggerCircuit)
 : AliTracker(),
   fDigitMaker(digitMaker), // not owner
   fTransformer(transformer), // not owner
   fTriggerCircuit(triggerCircuit), // not owner
-  fTrigChamberEff(chamberEff), // not owner
   fTrackHitPatternMaker(0x0),
   fTrackReco(0x0),
   fClusterStore(0x0),
@@ -177,13 +174,6 @@ Int_t AliMUONTracker::Clusters2Tracks(AliESDEvent* esd)
     fTrackReco->ValidateTracksWithTrigger(*trackStore,*triggerTrackStore,*fTriggerStore,*fTrackHitPatternMaker);
   }
   
-  // Compute trigger chamber efficiency
-  if( triggerTrackStore && fTrigChamberEff){
-      AliCodeTimerStart("EventChamberEff");
-      fTrigChamberEff->EventChamberEff(*fTriggerStore,*triggerTrackStore,*trackStore);
-      AliCodeTimerStop("EventChamberEff");
-  }
-  
   // Fill ESD
   FillESD(*trackStore,esd);
   
index 0306d7e8168595d129b41579be3b9842256bdee8..d320c9edc67296c45136b5cdcaeb42174cf0c447 100644 (file)
@@ -17,7 +17,6 @@ class AliESDEvent;
 class AliMUONDigitMaker;
 class AliMUONGeometryTransformer;
 class AliMUONTrackHitPattern;
-class AliMUONTriggerChamberEff;
 class AliMUONTriggerCircuit;
 class AliMUONVClusterStore;
 class AliMUONVTrackReconstructor;
@@ -32,8 +31,7 @@ class AliMUONTracker : public AliTracker
   AliMUONTracker(AliMUONVClusterServer& clusterServer,
                  const AliMUONDigitMaker* digitMaker=0,
                  const AliMUONGeometryTransformer* transformer=0,
-                 const AliMUONTriggerCircuit* triggerCircuit=0,
-                 AliMUONTriggerChamberEff* chamberEff=0);
+                 const AliMUONTriggerCircuit* triggerCircuit=0);
   virtual ~AliMUONTracker();
   
   virtual Int_t Clusters2Tracks(AliESDEvent* esd);
@@ -65,7 +63,6 @@ private:
   const AliMUONDigitMaker* fDigitMaker; //!< digit maker (not owner)
   const AliMUONGeometryTransformer* fTransformer; //!< geometry transformer (not owner)
   const AliMUONTriggerCircuit* fTriggerCircuit; //!< trigger circuit (not owner)
-  AliMUONTriggerChamberEff* fTrigChamberEff; //!< trigger efficiency (not owner)
   AliMUONTrackHitPattern* fTrackHitPatternMaker; //!< trigger hit pattern maker
   AliMUONVTrackReconstructor* fTrackReco; //!< track reconstructor
   mutable AliMUONVClusterStore* fClusterStore; //!< cluster container
index e3ff5d08e06419b23c471d16ffef363e2d9d90c4..de74331f11ed65f462b5031e30cee3328ed04c1f 100755 (executable)
@@ -19,6 +19,7 @@
 // Classes for display
 #include "AliMUONGeometryTransformer.h"
 #include "AliMpCDB.h"
+#include "AliCDBManager.h"
 #include "AliMpDDLStore.h"
 #include "AliMpDDL.h"
 #include "AliMpTriggerCrate.h"
 /// \class AliMUONTriggerEfficiencyCells
 /// A class to store and give access to the trigger chamber efficiency.
 ///
-/// Efficiency is stored per cathode on local boards, or, alternatively,
-/// on "cells" of a given size.
+/// Efficiency is stored per cathode on local boards
 ///
 /// The main method of this class is IsTriggered().
 ///
-/// $ALICE_ROOT/MUON/data/TriggerChamberefficiencyCells.dat contains efficiency 
+/// $ALICE_ROOT/MUON/data/efficiencyCells.dat contains efficiency 
 /// for each chamber (i.e. DetElement). 
 ///
 /// In the case of local boards, efficiency is stored from left to right
 /// per increasing board number (from 1 to 234)
 ///
-/// Otherwise, he efficiency cells goes from right to left and 
-/// from bottom to top of the chamber, namely, the efficiencies tabulated in the 
-/// file refers to the following reference frame:
-///
-/// <pre>
-/// x
-/// <----------------------------------|
-///                                    |
-///    ---------------------------     |
-///   | 0.97 | 0.97 | 0.97 | 0.97 |    |
-///    ---------------------------     |
-///   | 0.97 | 0.97 | 0.97 | 0.97 |    |
-///    ---------------------------     |
-///   | 0.97 | 0.97 | 0.97 | 0.97 |    |
-///    ---------------------------     |
-///                                    |
-///                                   \/ y
-/// </pre>
-///
-///  In both cases, the file can be edited in order to change efficiency
-///  in a chosen local board/region of the chamber.
+/// The file can be edited in order to change efficiency
+/// in a chosen local board/region of the chamber.
 ///
 ///
 /// But please note that this object is also available from the CDB 
-/// (generated using the MUONCDB.C macro)
 ///
 /// \author Diego Stocco; INFN Torino
 //-----------------------------------------------------------------------------
@@ -164,11 +144,6 @@ fFiredDisplayHistoList(other.fFiredDisplayHistoList)
 /// Copy constructor
 
   for(Int_t chCath=0; chCath<fgkNplanes; chCath++){
-    for(Int_t slat=0; slat<fgkNslats; slat++){
-      fCellContent[chCath][slat] = other.fCellContent[chCath][slat];
-    }
-    fCellSize[chCath] = other.fCellSize[chCath];
-    fCellNumber[chCath] = other.fCellNumber[chCath];
     fBoardEfficiency[chCath] = other.fBoardEfficiency[chCath];
     fSlatEfficiency[chCath] = other.fSlatEfficiency[chCath];
   }
@@ -183,11 +158,6 @@ AliMUONTriggerEfficiencyCells& AliMUONTriggerEfficiencyCells::operator=(const Al
     return *this;
 
   for(Int_t chCath=0; chCath<fgkNplanes; chCath++){
-    for(Int_t slat=0; slat<fgkNslats; slat++){
-      fCellContent[chCath][slat] = other.fCellContent[chCath][slat];
-    }
-    fCellSize[chCath] = other.fCellSize[chCath];
-    fCellNumber[chCath] = other.fCellNumber[chCath];
     fBoardEfficiency[chCath] = other.fBoardEfficiency[chCath];
     fSlatEfficiency[chCath] = other.fSlatEfficiency[chCath];
   }
@@ -211,24 +181,6 @@ AliMUONTriggerEfficiencyCells::~AliMUONTriggerEfficiencyCells()
 }
 
 
-//__________________________________________________________________________
-void AliMUONTriggerEfficiencyCells::GetCellEfficiency(Int_t detElemId, Float_t x, Float_t y, Float_t &eff1, Float_t &eff2) const
-{
-///  Get the efficiencies of the 2 cathodes at a given location (x,y)
-
-  Int_t chamber = FindChamberIndex(detElemId);
-  Int_t slat = FindSlatIndex(detElemId);
-  TArrayI cell = CellByCoord(detElemId,x,y);
-  eff1 = 0.0;
-  eff2 = 0.0;
-  if(cell.At(0)>=0 && cell.At(1)>=0)
-  {
-    eff1 = fCellContent[chamber][slat][cell.At(0)][cell.At(1)];
-    eff2 = fCellContent[fgkNchambers+chamber][slat][cell.At(0)][cell.At(1)];
-  }
-}
-
-
 //__________________________________________________________________________
 void AliMUONTriggerEfficiencyCells::GetCellEfficiency(Int_t detElemId, Int_t localBoard, Float_t &eff1, Float_t &eff2) const
 {
@@ -241,22 +193,6 @@ void AliMUONTriggerEfficiencyCells::GetCellEfficiency(Int_t detElemId, Int_t loc
 }
 
 
-//__________________________________________________________________________
-void 
-AliMUONTriggerEfficiencyCells::IsTriggered(Int_t detElemId, Float_t x, Float_t y, Bool_t &trig1, Bool_t &trig2) const
-{
-///  Whether or not a given location (x,y) has a chance to trig, on each cathode.
-
-  Float_t eff1 = 0.0;
-  Float_t eff2 = 0.0;
-  GetCellEfficiency(detElemId, x, y, eff1, eff2);
-  trig1 = kTRUE; 
-  trig2 = kTRUE;
-  if(gRandom->Rndm()>eff1)trig1 = kFALSE;
-  if(gRandom->Rndm()>eff2)trig2 = kFALSE;
-}
-
-
 //__________________________________________________________________________
 void 
 AliMUONTriggerEfficiencyCells::IsTriggered(Int_t detElemId, Int_t localBoard, Bool_t &trig1, Bool_t &trig2) const
@@ -272,23 +208,6 @@ AliMUONTriggerEfficiencyCells::IsTriggered(Int_t detElemId, Int_t localBoard, Bo
   if(gRandom->Rndm()>eff2)trig2 = kFALSE;
 }
 
-//__________________________________________________________________________
-TArrayI AliMUONTriggerEfficiencyCells::CellByCoord(Int_t detElemId, Float_t x, Float_t y) const
-{
-///  Get the efficiencies at a given location.
-
-  Int_t chamber = FindChamberIndex(detElemId);
-  Int_t slat = FindSlatIndex(detElemId);
-  Int_t cell[fgkNcathodes]={-1,-1};
-  Float_t maxX = fCellSize[chamber][slat]*((Float_t)fCellNumber[chamber][slat]);
-  Float_t maxY = fCellSize[fgkNchambers+chamber][slat]*((Float_t)fCellNumber[fgkNchambers+chamber][slat]);
-  if(x>=0 & x<maxX & y>=0 & y<maxY)
-  {
-    cell[0] = (Int_t)(x/fCellSize[chamber][slat]);
-    cell[1] = (Int_t)(y/fCellSize[fgkNchambers+chamber][slat]);
-  }
-  return TArrayI(fgkNcathodes,cell);
-}
 
 //__________________________________________________________________________
 void AliMUONTriggerEfficiencyCells::ReadFile(const Char_t* filename)
@@ -307,7 +226,7 @@ void AliMUONTriggerEfficiencyCells::ReadFile(const Char_t* filename)
   if (file.good()){
       file >> dat;
       if(!strcmp(dat,"localBoards"))ReadFileBoards(file);
-      else ReadFileXY(file);
+      else AliWarning("File .dat in wrong format");
       file.close();
   } else {
       AliWarning(Form("Can't read file %s",fileName.Data()));
@@ -315,45 +234,6 @@ void AliMUONTriggerEfficiencyCells::ReadFile(const Char_t* filename)
 }
 
 
-//__________________________________________________________________________
-void AliMUONTriggerEfficiencyCells::ReadFileXY(ifstream &file)
-{
-///  Structure of file (.dat) containing geometrical efficency
-    Int_t datInt=0, detEl=0, chamber=0, rpc=0, chCath=0;
-    Float_t datFloat=0.0;
-    Char_t dat[50];
-
-    while (file >> dat) {
-       file >> detEl;
-       chamber = FindChamberIndex(detEl);
-       rpc = FindSlatIndex(detEl);
-       file >> dat;
-       for(Int_t i=0; i<fgkNcathodes; i++){
-           chCath = fgkNchambers*i + chamber;
-           file >> datInt;
-           fCellNumber[chCath][rpc] = datInt;
-           file >> dat;
-       }
-       for(Int_t i=0; i<fgkNcathodes; i++){
-           chCath = fgkNchambers*i + chamber;
-           file >> datFloat;
-           fCellSize[chCath][rpc] = datFloat;
-           if(i==0)file >> dat;
-       }
-       for(Int_t cath=0; cath<fgkNcathodes; cath++){
-           chCath = fgkNchambers*cath + chamber;
-           file >> dat;
-           file >> datInt;
-           for(Int_t iy=0; iy<fCellNumber[fgkNchambers+chamber][rpc]; iy++){
-               for(Int_t ix=0; ix<fCellNumber[chamber][rpc]; ix++){
-                   file >> datFloat;
-                   fCellContent[chCath][rpc][ix][iy] = datFloat;
-               }
-           }
-       }
-    }
-}
-
 //__________________________________________________________________________
 void AliMUONTriggerEfficiencyCells::ReadFileBoards(ifstream &file)
 {
@@ -365,7 +245,6 @@ void AliMUONTriggerEfficiencyCells::ReadFileBoards(ifstream &file)
     while (file >> dat) {
            file >> detEl;
            chamber = FindChamberIndex(detEl);
-           //rpc = FindSlatIndex(detEl);
            for(Int_t cath=0; cath<fgkNcathodes; cath++){
                chCath = fgkNchambers*cath + chamber;
                file >> dat;
@@ -389,20 +268,50 @@ void AliMUONTriggerEfficiencyCells::ReadHistoBoards(const Char_t *filename)
        AliWarning(Form("Can't read file %s",filename));
        return;
     }
-    Char_t histoName[30];
+    Char_t histoName[40];
     Char_t *cathCode[fgkNcathodes] = {"bendPlane", "nonBendPlane"};
+    enum {kAllChEff, kChNonEff, kNumOfHistoTypes};
+    Char_t *histoTypeName[2] = {"CountInCh", "NonCountInCh"};
 
-    for(Int_t ch=0; ch<fgkNchambers; ch++){
-       for(Int_t cath=0; cath<fgkNcathodes; cath++){
-           sprintf(histoName, "%sBoardEffChamber%i", cathCode[cath], 11+ch);
-           if(!(TH1F *)file->Get(histoName)) {
-               AliWarning(Form("Can't find histo %s in file %s",histoName, filename));
-               continue;
-           }
-           Int_t chCath = fgkNchambers*cath + ch;
-           fBoardEfficiency[chCath] = (TH1F *)file->Get(histoName);
+    if(!fCountHistoList) fCountHistoList = new TList();
+    else fCountHistoList->Delete();
+    if(!fNoCountHistoList) fNoCountHistoList = new TList();
+    else fNoCountHistoList->Delete();
+
+    TList *currList[2] = {fCountHistoList, fNoCountHistoList};
+
+    TH1F *histo = 0x0;
+    
+    for(Int_t cath=0; cath<fgkNcathodes; cath++){
+      for(Int_t hType=0; hType<kNumOfHistoTypes; hType++){
+       sprintf(histoName, "%sChamber%s", cathCode[cath], histoTypeName[hType]);
+       histo = (TH1F*)file->Get(histoName);
+       currList[hType]->Add(histo);
+      }
+    }
+
+    for(Int_t cath=0; cath<fgkNcathodes; cath++){
+      for(Int_t ch=0; ch<fgkNchambers; ch++){
+       for(Int_t hType=0; hType<kNumOfHistoTypes; hType++){
+         sprintf(histoName, "%sSlat%s%i", cathCode[cath], histoTypeName[hType], 11+ch);
+         histo = (TH1F*)file->Get(histoName);
+         currList[hType]->Add(histo);
        }
+      }
     }
+
+    for(Int_t cath=0; cath<fgkNcathodes; cath++){
+      for(Int_t ch=0; ch<fgkNchambers; ch++){
+       for(Int_t hType=0; hType<kNumOfHistoTypes; hType++){
+         sprintf(histoName, "%sBoard%s%i", cathCode[cath], histoTypeName[hType], 11+ch);
+         histo = (TH1F*)file->Get(histoName);
+         currList[hType]->Add(histo);
+       }
+      }
+    }
+
+    InitHistos();
+    FillHistosFromList();
 }
 
 
@@ -429,51 +338,16 @@ Int_t AliMUONTriggerEfficiencyCells::FindChamberIndex(Int_t detElemId) const
 }
 
 
-//__________________________________________________________________________
-Int_t AliMUONTriggerEfficiencyCells::FindSlatIndex(Int_t detElemId) const
-{
-///  From detElemId to slat index.
-  Int_t slat = detElemId%100;
-  return slat;
-}
-
-
-//__________________________________________________________________________
-TVector2 AliMUONTriggerEfficiencyCells::ChangeReferenceFrame(Float_t x, Float_t y, Float_t x0, Float_t y0)
-{
-/// (x0,y0) position of the local reference frame (center of the chamber)
-
-    Float_t x1 = x0-x;//reflection of axis
-    Float_t y1 = y+y0;
-    return TVector2(x1,y1);
-}
-
 //__________________________________________________________________________
 void
 AliMUONTriggerEfficiencyCells::Reset()
 {
 ///  Sets our internal array contents to zero.
 
-    for(Int_t chCath=0; chCath<fgkNplanes; chCath++){
-       fCellSize[chCath].Set(fgkNslats);
-       fCellNumber[chCath].Set(fgkNslats);
-       for(Int_t slat=0; slat<fgkNslats; slat++){
-           fCellContent[chCath][slat].ResizeTo(fgkNcells,fgkNcells);
-       }
-    }
-
-    for(Int_t chCath=0; chCath<fgkNplanes; chCath++){
-       fCellSize[chCath].Reset();
-       fCellNumber[chCath].Reset();
-       for(Int_t slat=0; slat<fgkNslats; slat++){
-           fCellContent[chCath][slat].Zero();
-       }
-    }
-
-    for(Int_t chCath=0; chCath<fgkNplanes; chCath++){
-      fBoardEfficiency[chCath] = 0x0;
-      fSlatEfficiency[chCath] = 0x0;
-    }
+  for(Int_t chCath=0; chCath<fgkNplanes; chCath++){
+    fBoardEfficiency[chCath] = 0x0;
+    fSlatEfficiency[chCath] = 0x0;
+  }
 }
 
 
@@ -484,6 +358,7 @@ AliMUONTriggerEfficiencyCells::InitHistos()
 ///  Sets our internal array contents to zero.
 
   const Int_t kNumOfBoards = AliMpConstants::NofLocalBoards();
+  const Int_t kNslats = 18;
   Int_t chCath=0;
   Char_t histoName[40];
 
@@ -495,7 +370,7 @@ AliMUONTriggerEfficiencyCells::InitHistos()
       sprintf(histoName, "%sBoardEffChamber%i", cathCode[cath], 11+ch);
       fBoardEfficiency[chCath] = new TH1F(histoName, histoName, kNumOfBoards, 1-0.5, kNumOfBoards+1.-0.5);
       sprintf(histoName, "%sSlatEffChamber%i", cathCode[cath], 11+ch);
-      fSlatEfficiency[chCath] = new TH1F(histoName, histoName, fgkNslats, 0-0.5, fgkNslats-0.5);
+      fSlatEfficiency[chCath] = new TH1F(histoName, histoName, kNslats, 0-0.5, kNslats-0.5);
     }
   }
 }
@@ -551,7 +426,6 @@ AliMUONTriggerEfficiencyCells::FillHistosFromList()
 }
 
 
-
 //_____________________________________________________________________________
 void AliMUONTriggerEfficiencyCells::CalculateEfficiency(Int_t trigger44, Int_t trigger34,
                                                        Float_t &efficiency, Float_t &error,
@@ -574,7 +448,9 @@ void AliMUONTriggerEfficiencyCells::CalculateEfficiency(Int_t trigger44, Int_t t
 
 
 //_____________________________________________________________________________
-void AliMUONTriggerEfficiencyCells::CheckFiredStrips(const Char_t* geoFilename)
+void AliMUONTriggerEfficiencyCells::CheckFiredStrips(const Char_t* geoFilename,
+                                                    const Char_t* cdbStorage,
+                                                    Int_t runNumber)
 {
   //
   /// Check for fired strips participating to efficiency
@@ -588,7 +464,7 @@ void AliMUONTriggerEfficiencyCells::CheckFiredStrips(const Char_t* geoFilename)
     return;
   }
 
-  GetListsForCheck(geoFilename);
+  GetListsForCheck(geoFilename, cdbStorage, runNumber);
 
   Char_t histoName[40], histoTitle[90];
 
@@ -625,7 +501,10 @@ void AliMUONTriggerEfficiencyCells::CheckFiredStrips(const Char_t* geoFilename)
 
 
 //_____________________________________________________________________________
-void AliMUONTriggerEfficiencyCells::DisplayEfficiency(Bool_t perSlat, const Char_t* geoFilename)
+void AliMUONTriggerEfficiencyCells::DisplayEfficiency(Bool_t perSlat,
+                                                     const Char_t* geoFilename,
+                                                     const Char_t* cdbStorage,
+                                                     Int_t runNumber)
 {
   //
   /// Display calculated efficiency.
@@ -646,7 +525,7 @@ void AliMUONTriggerEfficiencyCells::DisplayEfficiency(Bool_t perSlat, const Char
     return;
   }
   
-  GetListsForCheck(geoFilename);
+  GetListsForCheck(geoFilename, cdbStorage, runNumber);
 
   const Int_t kNumOfBoards = AliMpConstants::NofLocalBoards();
 
@@ -703,7 +582,9 @@ void AliMUONTriggerEfficiencyCells::DisplayEfficiency(Bool_t perSlat, const Char
 
 
 //__________________________________________________________________________
-Bool_t AliMUONTriggerEfficiencyCells::GetListsForCheck(const Char_t* geoFilename)
+Bool_t AliMUONTriggerEfficiencyCells::GetListsForCheck(const Char_t* geoFilename,
+                                                      const Char_t* cdbStorage,
+                                                      Int_t runNumber)
 {
   //
   /// Getting histograms for efficiency, 
@@ -722,6 +603,9 @@ Bool_t AliMUONTriggerEfficiencyCells::GetListsForCheck(const Char_t* geoFilename
   if(!fFiredFitHistoList && fFiredStrips) fFiredFitHistoList = new TList();
   if(!fFiredDisplayHistoList && fFiredStrips) fFiredDisplayHistoList = new TList();
 
+  AliCDBManager::Instance()->SetDefaultStorage(cdbStorage);
+  AliCDBManager::Instance()->SetRun(runNumber);
+
   AliMUONGeometryTransformer *transform = new AliMUONGeometryTransformer();
   transform->LoadGeometryData(geoFilename);
 
@@ -943,10 +827,14 @@ Bool_t AliMUONTriggerEfficiencyCells::GetListsForCheck(const Char_t* geoFilename
            Int_t histoBin = localId;
            efficiency = fBoardEfficiency[chCath]->GetBinContent(histoBin);
            efficiencyError = fBoardEfficiency[chCath]->GetBinError(histoBin);
+           if(efficiency==0.) efficiency = kDummyFired; // It allows to graphically distinguish
+                                                        // efficiency = 0 from no hit on board
 
            histoBin = slat+1;
            efficiencySlat = fSlatEfficiency[chCath]->GetBinContent(histoBin);
            efficiencySlatError = fSlatEfficiency[chCath]->GetBinError(histoBin);
+           if(efficiencySlat==0.) efficiencySlat = kDummyFired; // It allows to graphically distinguish
+                                                                // efficiency = 0 from no hit on slat
 
            for(Int_t binX=x1; binX<=x2; binX++){
              for(Int_t binY=y1; binY<=y2; binY++){
index 03816e30b846d1f195e4c51009672a8902369833..660cb6a9e8e28cdaa8271cd4d503c3c4ead140a2 100755 (executable)
 #define ALIMUONTRIGGEREFFICIENCYCELLS_H
 
 #include "TObject.h"
-#include "TArrayF.h"
 #include "TArrayI.h"
-#include "TVector2.h"
-#include "TMatrix.h"
 #include "TH1F.h"
 #include "TList.h"
 
@@ -30,25 +27,29 @@ public:
 
   virtual ~AliMUONTriggerEfficiencyCells();
 
-  void GetCellEfficiency(Int_t detElemId, Float_t x, Float_t y, Float_t &eff1, Float_t &eff2) const;
   void GetCellEfficiency(Int_t detElemId, Int_t localBoard, Float_t &eff1, Float_t &eff2) const;
     
-  void IsTriggered(Int_t detElemId, Float_t x, Float_t y, Bool_t &trig1, Bool_t &trig2) const;
   void IsTriggered(Int_t detElemId, Int_t localBoard, Bool_t &trig1, Bool_t &trig2) const;
 
-  void DisplayEfficiency(Bool_t perSlat=kFALSE, const Char_t* geoFilename="geometry.root");
   Bool_t SumRunEfficiency(const AliMUONTriggerEfficiencyCells &other);
 
+
+  // Methods for display
+  void DisplayEfficiency(Bool_t perSlat=kFALSE,
+                        const Char_t* geoFilename="geometry.root",
+                        const Char_t* cdbStorage = "local://$ALICE_ROOT",
+                        Int_t runNumber=0);
+
+  // Methods for efficiency check
   /// Set the list of fired strips
   void SetFiredStrips(TList *firedStrips){fFiredStrips = firedStrips;}
-  void CheckFiredStrips(const Char_t *geoFilename="geometry.root");
+  void CheckFiredStrips(const Char_t *geoFilename="geometry.root",
+                       const Char_t* cdbStorage = "local://$ALICE_ROOT",
+                       Int_t runNumber=0);
                                 // Check for strips with lower counts than others:
                                 // syntomatic of possible read-out problems in boards
-  void Reset();
-    
 protected:
-    TArrayI CellByCoord(Int_t detElemId, Float_t x, Float_t y) const;
-    TVector2 ChangeReferenceFrame(Float_t x, Float_t y, Float_t x0, Float_t y0);
+    void Reset();
     void ReadFile(const Char_t* filename="$ALICE_ROOT/MUON/data/efficiencyCells.dat");
     void CalculateEfficiency(Int_t trigger44, Int_t trigger34,
                             Float_t &efficiency, Float_t &error,
@@ -58,25 +59,18 @@ protected:
 private:
     void CheckConstants() const;
     Int_t FindChamberIndex(Int_t detElemId) const;
-    Int_t FindSlatIndex(Int_t detElemId) const;
-    void ReadFileXY(ifstream &file);
     void ReadFileBoards(ifstream &file);
     void ReadHistoBoards(const Char_t* filename="MUON.TriggerEfficiencyMap.root");
     void InitHistos();
     void FillHistosFromList();
-    Bool_t GetListsForCheck(const Char_t* geoFilename="geometry.root");
+    Bool_t GetListsForCheck(const Char_t* geoFilename,
+                           const Char_t* cdbStorage, Int_t runNumber);
     
-    static const Int_t fgkNcells=80;   ///< Number of cells
     static const Int_t fgkNcathodes=2; ///<Number of cathodes
     static const Int_t fgkNchambers=4; ///<Number of chambers
     static const Int_t fgkNplanes=8;   ///<Number of planes
-    static const Int_t fgkNslats=18;   ///<Number of slats
 
     
-    TMatrixF fCellContent[fgkNplanes][fgkNslats]; ///< the cells content
-    TArrayF  fCellSize[fgkNplanes];    ///< the size of the cells
-    TArrayI  fCellNumber[fgkNplanes];  ///< id of the cells
-    
     TH1F *fBoardEfficiency[fgkNplanes];///< the boards content
     TH1F *fSlatEfficiency[fgkNplanes];///< the slats content
 
@@ -89,6 +83,6 @@ private:
     TList *fFiredFitHistoList; //!< list of fired strips for checks
     TList *fFiredDisplayHistoList; //!< list of fired strips for display
 
-    ClassDef(AliMUONTriggerEfficiencyCells,5) // Trigger efficiency store
+    ClassDef(AliMUONTriggerEfficiencyCells,6) // Trigger efficiency store
 };
 #endif
index 7c44f936b6975d403024135dafd0f07745befd2f..1bccc72cc19104d33a85a1b3cef3f3d62410c359 100644 (file)
@@ -756,164 +756,8 @@ void AliMUONVTrackReconstructor::ValidateTracksWithTrigger(AliMUONVTrackStore& t
   /// Try to match track from tracking system with trigger track
   AliCodeTimerAuto("");
 
-  const Double_t kDeltaZ = TMath::Abs(AliMUONConstants::DefaultChamberZ(12) - AliMUONConstants::DefaultChamberZ(10));
-
-  //static const Double_t kDistSigma[3]={1,1,0.02}; // sigma of distributions (trigger-track) X,Y,slopeY
-  // sigma of distributions (trigger-track) X,Y,slopeY
-  const Double_t kDistSigma[3]={AliMUONConstants::TriggerNonBendingReso(),
-                               AliMUONConstants::TriggerBendingReso(),
-                               1.414 * AliMUONConstants::TriggerBendingReso()/kDeltaZ};
-
-  const Double_t kTrigNonBendReso = AliMUONConstants::TriggerNonBendingReso();
-  const Double_t kTrigBendReso = AliMUONConstants::TriggerBendingReso();
-  const Double_t kTrigSlopeBendReso = 1.414 * AliMUONConstants::TriggerBendingReso()/kDeltaZ;
-  const Double_t kTrigCovSlopeBend = - kTrigBendReso * kTrigBendReso / kDeltaZ;
-
-  // Covariance matrix 3x3 (X,Y,slopeY) for trigger tracks
-  TMatrixD trigCov(3,3);
-  trigCov.Zero();
-  trigCov(0,0) = kTrigNonBendReso * kTrigNonBendReso;
-  trigCov(1,1) = kTrigBendReso * kTrigBendReso;
-  trigCov(2,2) = kTrigSlopeBendReso * kTrigSlopeBendReso;
-  trigCov(1,2) = trigCov(2,1) = kTrigCovSlopeBend;
-
-  Int_t matchTrigger;
-  Int_t loTrgNum(-1);
-  Double_t distTriggerTrack[3], sigma2[3];
-  Double_t xTrack, yTrack, ySlopeTrack, chi2MatchTrigger, minChi2MatchTrigger, chi2;
-
-  TIter itTrack(trackStore.CreateIterator());
-  AliMUONTrack* track;
-
-  const Float_t kZFilterOut = AliMUONConstants::MuonFilterZEnd();
-  const Float_t kFilterThickness = TMath::Abs(kZFilterOut-AliMUONConstants::MuonFilterZBeg()); // cm
-  const Int_t kFirstTrigCh = AliMUONConstants::NTrackingCh();
-  
-  while ( ( track = static_cast<AliMUONTrack*>(itTrack()) ) )
-  {
-    matchTrigger = 0;
-    chi2MatchTrigger = 0.;
-    loTrgNum = -1;
-    Int_t doubleMatch=-1; // Check if track matches 2 trigger tracks
-    Double_t doubleChi2 = -1.;
-    
-    AliMUONTrackParam trackParam(*((AliMUONTrackParam*) (track->GetTrackParamAtCluster()->Last())));
-
-    AliMUONTrackExtrap::ExtrapToZCov(&trackParam, kZFilterOut); // Extrap to muon filter end
-    AliMUONTrackExtrap::AddMCSEffect(&trackParam, kFilterThickness, AliMUONConstants::MuonFilterX0()); // Add MCS effects
-    AliMUONTrackExtrap::ExtrapToZCov(&trackParam, AliMUONConstants::DefaultChamberZ(kFirstTrigCh)); // extrap to 1st trigger chamber
-
-    const TMatrixD& kParamCov = trackParam.GetCovariances();
-    
-    xTrack = trackParam.GetNonBendingCoor();
-    yTrack = trackParam.GetBendingCoor();
-    ySlopeTrack = trackParam.GetBendingSlope();
-
-    // Covariance matrix 3x3 (X,Y,slopeY) for tracker tracks
-    TMatrixD trackCov(3,3);
-    trackCov.Zero();
-    trackCov(0,0) = kParamCov(0,0);
-    trackCov(1,1) = kParamCov(2,2);
-    trackCov(2,2) = kParamCov(3,3);
-    trackCov(1,2) = kParamCov(2,3);
-    trackCov(2,1) = kParamCov(3,2);
-
-    TMatrixD sumCov(trackCov,TMatrixD::kPlus,trigCov);
-
-    Bool_t isCovOK = kTRUE;
-
-    if (sumCov.Determinant() != 0) {
-      sumCov.Invert();
-    } else {
-      AliWarning(" Determinant = 0");
-      isCovOK = kFALSE;
-      sigma2[0] = kParamCov(0,0);
-      sigma2[1] = kParamCov(2,2);
-      sigma2[2] = kParamCov(3,3);
-      for (Int_t iVar = 0; iVar < 3; iVar++) sigma2[iVar] += kDistSigma[iVar] * kDistSigma[iVar];
-    }
-
-    minChi2MatchTrigger = 999.;
-
-    AliMUONTriggerTrack *triggerTrack;
-    TIter itTriggerTrack(triggerTrackStore.CreateIterator());
-    while ( ( triggerTrack = static_cast<AliMUONTriggerTrack*>(itTriggerTrack() ) ) )
-    {
-      distTriggerTrack[0] = triggerTrack->GetX11()-xTrack;
-      distTriggerTrack[1] = triggerTrack->GetY11()-yTrack;
-      distTriggerTrack[2] = TMath::Tan(triggerTrack->GetThetay())-ySlopeTrack;
-
-      if(isCovOK){
-       TMatrixD paramDiff(3,1);
-       for(Int_t iVar = 0; iVar < 3; iVar++)
-         paramDiff(iVar,0) = distTriggerTrack[iVar];
-       
-       TMatrixD tmp(sumCov,TMatrixD::kMult,paramDiff);
-       TMatrixD chi2M(paramDiff,TMatrixD::kTransposeMult,tmp);
-       chi2 = chi2M(0,0);
-      }
-      else {
-       chi2 = 0.;
-       for (Int_t iVar = 0; iVar < 3; iVar++) chi2 += distTriggerTrack[iVar]*distTriggerTrack[iVar]/sigma2[iVar];
-      }
-
-      chi2 /= 3.; // Normalized Chi2: 3 degrees of freedom (X,Y,slopeY)
-      if (chi2 < AliMUONReconstructor::GetRecoParam()->GetMaxNormChi2MatchTrigger()) 
-      {
-        Bool_t isDoubleTrack = (TMath::Abs(chi2 - minChi2MatchTrigger)<1.);
-        if (chi2 < minChi2MatchTrigger && chi2 < AliMUONReconstructor::GetRecoParam()->GetMaxNormChi2MatchTrigger()) 
-        {
-          if(isDoubleTrack)
-          {
-            doubleMatch = loTrgNum;
-            doubleChi2 = chi2MatchTrigger;
-          }
-          minChi2MatchTrigger = chi2;
-          chi2MatchTrigger = chi2;
-          loTrgNum = triggerTrack->GetLoTrgNum();
-          AliMUONLocalTrigger* locTrg = triggerStore.FindLocal(loTrgNum);
-          matchTrigger=1;
-          if(locTrg->LoLpt()>0)matchTrigger=2;
-          if(locTrg->LoHpt()>0)matchTrigger=3;
-        }
-        else if(isDoubleTrack) 
-        {
-          doubleMatch = triggerTrack->GetLoTrgNum();
-          doubleChi2 = chi2;
-        }
-      }
-    }
-    if(doubleMatch>=0)
-    { // If two trigger tracks match, select the one passing more trigger cuts
-      AliDebug(1, Form("Two candidates found: %i and %i",loTrgNum,doubleMatch));
-      AliMUONLocalTrigger* locTrg1 = triggerStore.FindLocal(doubleMatch);
-      if((locTrg1->LoLpt()>0 && matchTrigger<2) || (locTrg1->LoHpt() && matchTrigger<3))
-      {
-        if(locTrg1->LoHpt()>0)matchTrigger=3;
-        else matchTrigger=2;
-        loTrgNum = doubleMatch;
-        chi2MatchTrigger=doubleChi2;
-      }
-    }
-    
-    track->SetMatchTrigger(matchTrigger);
-    track->SetLoTrgNum(loTrgNum);
-    track->SetChi2MatchTrigger(chi2MatchTrigger);
-    
-    AliMUONLocalTrigger* locTrg = static_cast<AliMUONLocalTrigger*>(triggerStore.FindLocal(loTrgNum));
-    
-    if (locTrg)
-    {    
-      track->SetLocalTrigger(locTrg->LoCircuit(),
-                             locTrg->LoStripX(),
-                             locTrg->LoStripY(),
-                             locTrg->LoDev(),
-                             locTrg->LoLpt(),
-                             locTrg->LoHpt());
-    }    
-  }  
-  
-  trackHitPattern.GetHitPattern(trackStore,triggerStore);
+  trackHitPattern.ExecuteValidation(trackStore, triggerTrackStore, triggerStore);
+  trackHitPattern.UpdateQA();
 }
 
   //__________________________________________________________________________
index 3b2ff2bec562c0854b12eec4cab47c433eee4e39..7faf74483f2c259596a2dcf44c2a4b6481ce420b 100644 (file)
Binary files a/MUON/Calib/TriggerEfficiency/Run0_99999999_v0_s0.root and b/MUON/Calib/TriggerEfficiency/Run0_99999999_v0_s0.root differ
index 3c136d248b7c654dd4ccddeb940a8e299aa5d887..b8c4856aa79adcc9e3302f973f6529d511292a34 100644 (file)
@@ -31,7 +31,6 @@
 #pragma link C++ class AliMUONClusterFinderMLEM+;
 #pragma link C++ class AliMUONClusterSplitterMLEM+;
 #pragma link C++ class AliMUONTrackHitPattern+;
-#pragma link C++ class AliMUONTriggerChamberEff+;
 
 #pragma link C++ class AliMUONVClusterStore+;
 #pragma link C++ class AliMUONClusterStoreV1+;
index 7022bbdf60ac88471f96540073b8c7cce36f3fa7..9a2701930271dee909a9bc2135cbabcc45f2593f 100644 (file)
@@ -27,7 +27,6 @@ SRCS:= AliMUONReconstructor.cxx \
        AliMUONPadStatusMaker.cxx \
        AliMUONPadStatusMapMaker.cxx \
        AliMUONTrackHitPattern.cxx \
-       AliMUONTriggerChamberEff.cxx \
        AliMUONVClusterStore.cxx \
        AliMUONClusterStoreV1.cxx \
        AliMUONClusterStoreV2.cxx \