/**************************************************************************
* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
* *
* Author: The ALICE Off-line Project. *
* Contributors are mentioned in the code where appropriate. *
* *
* Permission to use, copy, modify and distribute this software and its *
* documentation strictly for non-commercial purposes is hereby granted *
* without fee, provided that the above copyright notice appears in all *
* copies and that both the copyright notice and this permission notice *
* appear in the supporting documentation. The authors make no claims *
* about the suitability of this software for any purpose. It is *
* provided "as is" without express or implied warranty. *
**************************************************************************/
/* $Id$ */
//-----------------------------------------------------------------------------
/// \class AliMUONTrackHitPattern
///
/// This class propagates tracks to trigger chambers
/// searching for fired strips.
///
/// To each track, a hit pattern for trigger chambers is set.
/// The hit pattern is a UShort_t with 8 bits used:
///
/// 1 1 0 1 1 1 0 1
/// | | |
/// ----------- ------------
/// chamber: 11 12 13 14 | 11 12 13 14
/// cathode: bending | non-bending
///
/// The main method is:
/// * GetHitPattern
///
/// \author Diego Stocco
//-----------------------------------------------------------------------------
#include "AliMUONTrackHitPattern.h"
#include "AliMUONConstants.h"
#include "AliMUONVDigit.h"
#include "AliMUONDigitMaker.h"
#include "AliMUONDigitStoreV1.h"
#include "AliMUONGeometryTransformer.h"
#include "AliMUONLocalTrigger.h"
#include "AliMUONLocalTriggerBoard.h"
#include "AliMUONTrack.h"
#include "AliMUONTrackExtrap.h"
#include "AliMUONTrackParam.h"
#include "AliMUONVTrackStore.h"
#include "AliMUONVTriggerStore.h"
#include "AliMpPad.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
#include
#include
#include
#include
/// \cond CLASSIMP
ClassImp(AliMUONTrackHitPattern) // Class implementation in ROOT context
/// \endcond
//______________________________________________________________________________
AliMUONTrackHitPattern::AliMUONTrackHitPattern(const AliMUONGeometryTransformer& transformer,
const AliMUONDigitMaker& digitMaker)
: TObject(),
fTransformer(transformer),
fDigitMaker(digitMaker)
{
/// Default constructor
// Set magnetic field
const AliMagF* kField = AliTracker::GetFieldMap();
if (!kField) AliFatal("No field available");
AliMUONTrackExtrap::SetField(kField);
}
//______________________________________________________________________________
AliMUONTrackHitPattern::~AliMUONTrackHitPattern(void)
{
/// Destructor
}
//______________________________________________________________________________
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 kMask[2][4]= {{0x80, 0x40, 0x20, 0x10},
{0x08, 0x04, 0x02, 0x01}};
Bool_t isMatch[2];
UShort_t pattern=0;
AliMUONDigitStoreV1 digitStore;
TriggerDigits(triggerStore,digitStore);
AliMUONTrack* muonTrack;
TIter next(trackStore.CreateIterator());
const Int_t kNTrackingCh = AliMUONConstants::NTrackingCh();
while ( ( muonTrack = static_cast(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);
}
}
//______________________________________________________________________________
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.;
}
TIter next(digitStore.CreateIterator());
AliMUONVDigit* mDigit;
while ( ( mDigit = static_cast(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;
}
}
//______________________________________________________________________________
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.
//
AliMUONTrackParam trackParamAtPadZ(trackParam);
AliMUONTrackExtrap::ExtrapToZCov(&trackParamAtPadZ, zPad);
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::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);
AliMUONTrackExtrap::AddMCSEffect(&trackParam, kFilterThickness, AliMUONConstants::MuonFilterX0());
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(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;
}