#include "AliMUONRecoParam.h"
#include "AliMUONSimpleClusterServer.h"
#include "AliMUONTracker.h"
-#include "AliMUONTriggerChamberEff.h"
#include "AliMUONTriggerCircuit.h"
#include "AliMUONTriggerCrateStore.h"
#include "AliMUONTriggerStoreV1.h"
fDigitCalibrator(0x0),
fClusterServer(0x0),
fTriggerStore(0x0),
-fTrackStore(0x0),
-fTrigChamberEff(0x0)
+fTrackStore(0x0)
{
/// normal ctor
delete fClusterServer;
delete fTriggerStore;
delete fTrackStore;
- delete fTrigChamberEff;
}
//_____________________________________________________________________________
}
-//_____________________________________________________________________________
-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
CreateTriggerCircuit();
CreateDigitMaker();
- CreateTriggerChamberEff();
CreateClusterServer();
if (!fClusterServer)
AliMUONTracker* tracker = new AliMUONTracker(*fClusterServer,
fDigitMaker,
fTransformer,
- fTriggerCircuit,
- fTrigChamberEff);
+ fTriggerCircuit);
return tracker;
}
class AliMUONTracker;
class AliMUONVTrackStore;
-class AliMUONTriggerChamberEff;
-
class AliMUONRecoParam;
class AliMUONVClusterFinder;
void CreateDigitMaker() const;
void CreateTriggerCircuit() const;
void CreateClusterServer() const;
- void CreateTriggerChamberEff() const;
void FillTreeR(AliMUONVTriggerStore* triggerStore,
TTree& clustersTree) const;
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
/// \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:
/// 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
const AliMUONDigitMaker& digitMaker)
: TObject(),
fTransformer(transformer),
- fDigitMaker(digitMaker)
+ fDigitMaker(digitMaker),
+ fkMaxDistance(99999.)
{
/// Default constructor
+ InitMembers();
// Set magnetic field
const AliMagF* kField = AliTracker::GetFieldMap();
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;
}
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];
for(Int_t cath=0; cath<2; ++cath)
{
isMatch[cath]=kFALSE;
- minMatchDist[cath]=9999.;
+ minMatchDist[cath]=fkMaxDistance/10.;
}
TIter next(digitStore.CreateIterator());
const AliMUONTrackParam& trackParam) const
{
//
- /// Decides if the digit belongs to the track.
+ /// Decides if the digit belongs to the tracker track.
//
AliMUONTrackParam trackParamAtPadZ(trackParam);
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();
}
+
// 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
{
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
#include "AliMUONTrackReconstructor.h"
#include "AliMUONTrackReconstructorK.h"
#include "AliMUONTrackStoreV1.h"
-#include "AliMUONTriggerChamberEff.h"
#include "AliMUONTriggerTrackStoreV1.h"
#include "AliMUONClusterStoreV2.h"
#include "AliMUONVTriggerStore.h"
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),
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);
class AliMUONDigitMaker;
class AliMUONGeometryTransformer;
class AliMUONTrackHitPattern;
-class AliMUONTriggerChamberEff;
class AliMUONTriggerCircuit;
class AliMUONVClusterStore;
class AliMUONVTrackReconstructor;
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);
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
// 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
//-----------------------------------------------------------------------------
/// 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];
}
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];
}
}
-//__________________________________________________________________________
-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
{
}
-//__________________________________________________________________________
-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
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)
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()));
}
-//__________________________________________________________________________
-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)
{
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;
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();
}
}
-//__________________________________________________________________________
-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;
+ }
}
/// 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];
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);
}
}
}
}
-
//_____________________________________________________________________________
void AliMUONTriggerEfficiencyCells::CalculateEfficiency(Int_t trigger44, Int_t trigger34,
Float_t &efficiency, Float_t &error,
//_____________________________________________________________________________
-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
return;
}
- GetListsForCheck(geoFilename);
+ GetListsForCheck(geoFilename, cdbStorage, runNumber);
Char_t histoName[40], histoTitle[90];
//_____________________________________________________________________________
-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.
return;
}
- GetListsForCheck(geoFilename);
+ GetListsForCheck(geoFilename, cdbStorage, runNumber);
const Int_t kNumOfBoards = AliMpConstants::NofLocalBoards();
//__________________________________________________________________________
-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,
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);
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++){
#define ALIMUONTRIGGEREFFICIENCYCELLS_H
#include "TObject.h"
-#include "TArrayF.h"
#include "TArrayI.h"
-#include "TVector2.h"
-#include "TMatrix.h"
#include "TH1F.h"
#include "TList.h"
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,
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
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
/// 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();
}
//__________________________________________________________________________
#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+;
AliMUONPadStatusMaker.cxx \
AliMUONPadStatusMapMaker.cxx \
AliMUONTrackHitPattern.cxx \
- AliMUONTriggerChamberEff.cxx \
AliMUONVClusterStore.cxx \
AliMUONClusterStoreV1.cxx \
AliMUONClusterStoreV2.cxx \