* provided "as is" without express or implied warranty. *
**************************************************************************/
-////////////////////////////////////
-///
+/* $Id$ */
+
+
+//-----------------------------------------------------------------------------
/// \class AliMUONTrackHitPattern
///
/// This class propagates tracks to trigger chambers
///
/// To each track, a hit pattern for trigger chambers is set.
/// The hit pattern is a UShort_t with 8 bits used:
-///
+/// <pre>
/// 1 1 0 1 1 1 0 1
/// | | |
/// ----------- ------------
/// chamber: 11 12 13 14 | 11 12 13 14
/// cathode: bending | non-bending
-///
+/// </pre>
/// The main method is:
/// * GetHitPattern
///
/// \author Diego Stocco
-///
-////////////////////////////////////
+//-----------------------------------------------------------------------------
#include "AliMUONTrackHitPattern.h"
-#include "AliMUONData.h"
-#include "AliMUONTrack.h"
-#include "AliMUONTrackParam.h"
-#include "AliMUONTrackExtrap.h"
+
#include "AliMUONConstants.h"
+#include "AliMUONVDigit.h"
+#include "AliMUONDigitMaker.h"
+#include "AliMUONDigitStoreV1.h"
#include "AliMUONGeometryTransformer.h"
-#include "AliMUONDigit.h"
#include "AliMUONLocalTrigger.h"
-#include "AliMUONTriggerCrateStore.h"
#include "AliMUONLocalTriggerBoard.h"
-#include "AliMUONTriggerCircuit.h"
-#include "AliMUONDigitMaker.h"
-
+#include "AliMUONTrack.h"
+#include "AliMUONTrackExtrap.h"
+#include "AliMUONTrackParam.h"
+#include "AliMUONVTrackStore.h"
+#include "AliMUONVTriggerStore.h"
#include "AliMpPad.h"
-#include "AliMpVSegmentation.h"
#include "AliMpSegmentation.h"
+#include "AliMpVSegmentation.h"
+#include "AliMpDEManager.h"
+#include "AliMUONReconstructor.h"
+#include "AliMUONRecoParam.h"
+#include "AliMagF.h"
#include "AliLog.h"
#include "AliTracker.h"
-#include "AliMagF.h"
#include <Riostream.h>
+#include <TArrayS.h>
#include <TClonesArray.h>
#include <TMath.h>
#include <TMatrixD.h>
-#include <TArrayS.h>
/// \cond CLASSIMP
ClassImp(AliMUONTrackHitPattern) // Class implementation in ROOT context
//______________________________________________________________________________
-AliMUONTrackHitPattern::AliMUONTrackHitPattern(AliMUONData *data)
+AliMUONTrackHitPattern::AliMUONTrackHitPattern(const AliMUONGeometryTransformer& transformer,
+ const AliMUONDigitMaker& digitMaker)
: TObject(),
- fMUONData(data),
- fTransformer(new AliMUONGeometryTransformer(kTRUE)),
- fCrateManager(new AliMUONTriggerCrateStore())
+ fTransformer(transformer),
+ fDigitMaker(digitMaker)
{
/// Default constructor
const AliMagF* kField = AliTracker::GetFieldMap();
if (!kField) AliFatal("No field available");
AliMUONTrackExtrap::SetField(kField);
-
- // Geometry transformer
- fTransformer->ReadGeometryData("volpath.dat", "geometry.root");
-
- // Crate manager to retrieve local boards
- fCrateManager->ReadFromFile();
-
- for(Int_t ch=0; ch<4; ch++){
- fTriggerDigitsList[ch].Clear();
- }
}
//______________________________________________________________________________
AliMUONTrackHitPattern::~AliMUONTrackHitPattern(void)
{
-/// Destructor
- for(Int_t ch=0; ch<4; ch++){
- fTriggerDigitsList[ch].Delete();
- }
- delete fCrateManager;
+ /// Destructor
}
//______________________________________________________________________________
-void AliMUONTrackHitPattern::GetHitPattern(TClonesArray *recTracksPtr)
+void AliMUONTrackHitPattern::GetHitPattern(AliMUONVTrackStore& trackStore,
+ const AliMUONVTriggerStore& triggerStore) const
{
//
/// Main method:
/// Loops on reco tracks, extrapolates them to trigger chambers
/// and searches for matching digits
//
-
- const Int_t mask[2][4]={{0x80, 0x40, 0x20, 0x10},
- {0x08, 0x04, 0x02, 0x01}};
+
+ const Int_t kMask[2][4]= {{0x80, 0x40, 0x20, 0x10},
+ {0x08, 0x04, 0x02, 0x01}};
Bool_t isMatch[2];
+
UShort_t pattern=0;
- TriggerDigits();
- Int_t nRecTracks = (Int_t)recTracksPtr->GetEntriesFast();
- for(Int_t iTrack=0; iTrack<nRecTracks; iTrack++){
- pattern = 0;
- AliMUONTrack *muonTrack = (AliMUONTrack*) recTracksPtr->At(iTrack);
- AliMUONTrackParam *trackParam = (AliMUONTrackParam*) ((muonTrack->GetTrackParamAtHit())->Last());
- for(Int_t ch=0; ch<4; ch++){
- AliMUONTrackExtrap::ExtrapToZCov(trackParam, AliMUONConstants::DefaultChamberZ(10+ch));
- FindPadMatchingTrack(trackParam, isMatch, ch);
- for(Int_t cath=0; cath<2; cath++){
- if(isMatch[cath]) pattern |= mask[cath][ch];
- }
+
+ AliMUONDigitStoreV1 digitStore;
+
+ TriggerDigits(triggerStore,digitStore);
+
+ AliMUONTrack* muonTrack;
+ TIter next(trackStore.CreateIterator());
+
+ const Int_t kNTrackingCh = AliMUONConstants::NTrackingCh();
+
+ while ( ( muonTrack = static_cast<AliMUONTrack*>(next()) ) )
+ {
+ pattern = 0;
+ AliMUONTrackParam trackParam(*((AliMUONTrackParam*) (muonTrack->GetTrackParamAtCluster()->Last())));
+
+ ApplyMCSCorrections(trackParam);
+
+ 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]) pattern |= kMask[cath][ch];
}
- muonTrack->SetHitsPatternInTrigCh(pattern);
+ }
+ muonTrack->SetHitsPatternInTrigCh(pattern);
}
- return;
}
//______________________________________________________________________________
-void AliMUONTrackHitPattern::FindPadMatchingTrack(AliMUONTrackParam *trackParam,
- Bool_t isMatch[2], Int_t iChamber)
+void
+AliMUONTrackHitPattern::FindPadMatchingTrack(AliMUONVDigitStore& digitStore,
+ const AliMUONTrackParam& trackParam,
+ Bool_t isMatch[2], Int_t iChamber) const
{
//
/// Given track position, searches for matching digits.
Float_t minMatchDist[2];
- for(Int_t cath=0; cath<2; cath++){
- isMatch[cath]=kFALSE;
- minMatchDist[cath]=9999.;
+ for(Int_t cath=0; cath<2; ++cath)
+ {
+ isMatch[cath]=kFALSE;
+ minMatchDist[cath]=9999.;
}
- Int_t ndigits = (Int_t)fTriggerDigitsList[iChamber].GetEntries();
- AliMUONDigit * mDigit = 0x0;
- for(Int_t idigit=0; idigit<ndigits; idigit++) { // digit loop
- mDigit = (AliMUONDigit*)fTriggerDigitsList[iChamber].At(idigit);
- Int_t currDetElemId = mDigit->DetElemId();
-
- 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);
- Float_t matchDist = MinDistanceFromPad(xpad, ypad, zpad, dpx, dpy, trackParam);
- if(matchDist>minMatchDist[cathode])continue;
- isMatch[cathode] = kTRUE;
- minMatchDist[cathode] = matchDist;
+ TIter next(digitStore.CreateIterator());
+ AliMUONVDigit* mDigit;
+
+ while ( ( mDigit = static_cast<AliMUONVDigit*>(next()) ) )
+ {
+ Int_t currDetElemId = mDigit->DetElemId();
+ Int_t currCh = AliMpDEManager::GetChamberId(currDetElemId);
+ if(currCh!=iChamber) continue;
+ 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);
+ Float_t matchDist = MinDistanceFromPad(xpad, ypad, zpad, dpx, dpy, trackParam);
+ if(matchDist>minMatchDist[cathode])continue;
+ isMatch[cathode] = kTRUE;
+ if(isMatch[0] && isMatch[1]) break;
+ minMatchDist[cathode] = matchDist;
}
-
- return;
}
//______________________________________________________________________________
-Float_t AliMUONTrackHitPattern::MinDistanceFromPad(Float_t xPad, Float_t yPad, Float_t zPad,
- Float_t dpx, Float_t dpy, AliMUONTrackParam *trackParam)
+Float_t
+AliMUONTrackHitPattern::MinDistanceFromPad(Float_t xPad, Float_t yPad, Float_t zPad,
+ Float_t dpx, Float_t dpy,
+ const AliMUONTrackParam& trackParam) const
{
//
/// Decides if the digit belongs to the track.
//
- Float_t xTrackAtPad = trackParam->GetNonBendingCoor();
- Float_t yTrackAtPad = trackParam->GetBendingCoor();
- Float_t sigmaX, sigmaY, sigmaMS;
- GetPosUncertainty(trackParam, zPad, sigmaX, sigmaY, sigmaMS);
+ AliMUONTrackParam trackParamAtPadZ(trackParam);
+ AliMUONTrackExtrap::ExtrapToZCov(&trackParamAtPadZ, zPad);
- Float_t maxDistX = 3.*(sigmaX + sigmaMS); // in cm
- Float_t maxDistY = 3.*(sigmaY + sigmaMS); // in cm
+ Float_t xTrackAtPad = trackParamAtPadZ.GetNonBendingCoor();
+ Float_t yTrackAtPad = trackParamAtPadZ.GetBendingCoor();
+
+ const Float_t kNSigma = AliMUONReconstructor::GetRecoParam()->GetSigmaCutForTrigger();
+
+ const TMatrixD& kCovParam = trackParamAtPadZ.GetCovariances();
+
+ Float_t sigmaX = TMath::Sqrt(kCovParam(0,0));
+ Float_t sigmaY = TMath::Sqrt(kCovParam(2,2));
+
+ Float_t maxDistX = kNSigma * sigmaX; // in cm
+ Float_t maxDistY = kNSigma * sigmaY; // in cm
Float_t deltaX = TMath::Abs(xPad-xTrackAtPad)-dpx;
Float_t deltaY = TMath::Abs(yPad-yTrackAtPad)-dpy;
Float_t matchDist = 99999.;
if(deltaX<=maxDistX && deltaY<=maxDistY) matchDist = TMath::Max(deltaX, deltaY);
+
return matchDist;
}
//______________________________________________________________________________
-void AliMUONTrackHitPattern::GetPosUncertainty(AliMUONTrackParam *trackParam, Float_t zChamber,
- Float_t &sigmaX, Float_t &sigmaY, Float_t &sigmaMS)
+void
+AliMUONTrackHitPattern::ApplyMCSCorrections(AliMUONTrackParam& trackParam) const
{
- //
- /// Returns uncertainties on extrapolated position.
- /// Takes into account Branson plane corrections in the iron wall.
- //
+ //
+ /// Returns uncertainties on extrapolated position.
+ /// Takes into account Branson plane corrections in the iron wall.
+ //
- const Float_t alpha = 0.1123; // GeV/c
-
- // Find a better way to get such parameters ???
- const Float_t kZFilterIn = 1471.; // From STRUCT/SHILConst2.h
- const Float_t kZFilterOut = kZFilterIn + 120.; // From STRUCT/SHILConst2.h
-
- const Float_t zBranson = - (kZFilterIn + (kZFilterOut - kZFilterIn)*2./3. ); // - sign because distance are positive
- Float_t zDistFromWall = TMath::Abs(zChamber - zBranson);
- Float_t zDistFromLastTrackCh = TMath::Abs(zChamber - AliMUONConstants::DefaultChamberZ(9));
+ const Float_t kZFilterOut = AliMUONConstants::MuonFilterZEnd();
+ const Float_t kFilterThickness = TMath::Abs(kZFilterOut-AliMUONConstants::MuonFilterZBeg()); // cm
- TMatrixD *covParam = trackParam->GetCovariances();
-
- sigmaX = (*covParam)(0,0);
- sigmaY = (*covParam)(2,2);
-
- // If covariance matrix is not extrapolated, use "reasonable" errors
- // (To be removed as soon as covariance matrix is correctly propagated).
- if (sigmaX==0.)sigmaX = 0.003 * zDistFromLastTrackCh;
- if (sigmaY==0.)sigmaY = 0.004 * zDistFromLastTrackCh;
-
- Float_t p = trackParam->P();
- Float_t thetaMS = alpha/p;
- sigmaMS = zDistFromWall * TMath::Tan(thetaMS);
-
- return;
+ AliMUONTrackExtrap::ExtrapToZCov(&trackParam, kZFilterOut);
+ AliMUONTrackExtrap::AddMCSEffect(&trackParam, kFilterThickness, AliMUONConstants::MuonFilterX0());
+ return;
}
-//____________________________________________________________________
-Bool_t AliMUONTrackHitPattern::TriggerDigits()
+//______________________________________________________________________________
+Bool_t
+AliMUONTrackHitPattern::TriggerDigits(const AliMUONVTriggerStore& triggerStore,
+ AliMUONVDigitStore& digitStore) const
{
- //
- /// make (S)Digit for trigger
- //
-
- Int_t nBoard;
-
- TList digitList;
-
- AliMUONDigitMaker* digitMaker = new AliMUONDigitMaker(); // should be put as member in class
-
- AliMUONLocalTrigger *locTrg = 0x0;
-
- fMUONData->SetTreeAddress("RC,TC");
- fMUONData->GetTrigger();
-
- TClonesArray *localTrigger = fMUONData->LocalTrigger();
- Int_t nLocTrig = (Int_t) localTrigger->GetEntriesFast();
-
- for(Int_t iLoc=0; iLoc<nLocTrig; iLoc++) {
- locTrg = (AliMUONLocalTrigger*)localTrigger->UncheckedAt(iLoc);
-
- TArrayS xyPattern[2];
- xyPattern[0].Set(4);
- xyPattern[1].Set(4);
-
- xyPattern[0].AddAt(locTrg->GetX1Pattern(),0);
- xyPattern[0].AddAt(locTrg->GetX2Pattern(),1);
- xyPattern[0].AddAt(locTrg->GetX3Pattern(),2);
- xyPattern[0].AddAt(locTrg->GetX4Pattern(),3);
-
- xyPattern[1].AddAt(locTrg->GetY1Pattern(),0);
- xyPattern[1].AddAt(locTrg->GetY2Pattern(),1);
- xyPattern[1].AddAt(locTrg->GetY3Pattern(),2);
- xyPattern[1].AddAt(locTrg->GetY4Pattern(),3);
-
- digitList.Clear();
- nBoard = locTrg->LoCircuit();
- digitMaker->TriggerDigits(nBoard, xyPattern, digitList);
-
-
- } // loop on localTriggers
-
- for (Int_t iEntry = 0; iEntry < digitList.GetEntries(); ++iEntry) {
- AliMUONDigit* digit = (AliMUONDigit*)digitList.At(iEntry);
- Int_t detElemId = digit->DetElemId();
- Int_t iChamber = detElemId/100 - 1; //FIXEME should be given by mapping
- fTriggerDigitsList[iChamber].Add(digit);
-
- }
-
- return kTRUE;
+ //
+ /// 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;
}