#include "AliRun.h"
#include <TList.h>
+#include <TArrayS.h>
/// \cond CLASSIMP
// Make SDigit
digitList.Clear();
-
- if( TriggerDigits(localBoard, localStruct, digitList) ) {
+ //FIXEME should find something better than a TArray
+ TArrayS xyPattern[2];
+ xyPattern[0].Set(4);
+ xyPattern[1].Set(4);
+
+ xyPattern[0].AddAt(localStruct->GetX1(),0);
+ xyPattern[0].AddAt(localStruct->GetX2(),1);
+ xyPattern[0].AddAt(localStruct->GetX3(),2);
+ xyPattern[0].AddAt(localStruct->GetX4(),3);
+
+ xyPattern[1].AddAt(localStruct->GetY1(),0);
+ xyPattern[1].AddAt(localStruct->GetY2(),1);
+ xyPattern[1].AddAt(localStruct->GetY3(),2);
+ xyPattern[1].AddAt(localStruct->GetY4(),3);
+
+ if( TriggerDigits(loCircuit, xyPattern, digitList) ) {
for (Int_t iEntry = 0; iEntry < digitList.GetEntries(); iEntry++) {
return kTRUE;
}
+
//____________________________________________________________________
-void AliMUONDigitMaker::GetTriggerChamber(AliMUONLocalStruct* localStruct, Int_t& xyPattern,
- Int_t& iChamber, Int_t& iCath, Int_t icase)
-{
- /// get chamber & cathode number, (chamber starts at 0 !)
-
- switch(icase) {
- case 0:
- xyPattern = localStruct->GetX1();
- iCath = 0;
- iChamber = 10;
- break;
- case 1:
- xyPattern = localStruct->GetX2();
- iCath = 0;
- iChamber = 11;
- break;
- case 2:
- xyPattern = localStruct->GetX3();
- iCath = 0;
- iChamber = 12;
- break;
- case 3:
- xyPattern = localStruct->GetX4();
- iCath = 0;
- iChamber = 13;
- break;
- case 4:
- xyPattern = localStruct->GetY1();
- iCath = 1;
- iChamber = 10;
- break;
- case 5:
- xyPattern = localStruct->GetY2();
- iCath = 1;
- iChamber = 11;
- break;
- case 6:
- xyPattern = localStruct->GetY3();
- iCath = 1;
- iChamber = 12;
- break;
- case 7:
- xyPattern = localStruct->GetY4();
- iCath = 1;
- iChamber = 13;
- break;
- }
-}
-//____________________________________________________________________
-Int_t AliMUONDigitMaker::TriggerDigits(AliMUONLocalTriggerBoard* localBoard,
- AliMUONLocalStruct* localStruct,
+Int_t AliMUONDigitMaker::TriggerDigits(Int_t nBoard,
+ TArrayS* xyPattern,
TList& digitList)
{
/// make (S)Digit for trigger
Int_t detElemId;
- Int_t nBoard;
- Int_t iCath = -1;
- Int_t iChamber = 0;
- Int_t xyPattern = 0;
+ Int_t previousDetElemId[4] = {0};
+ Int_t previousBoard[4] = {0};
// loop over x1-4 and y1-4
- for (Int_t icase = 0; icase < 8; icase++) {
-
- // get chamber, cathode and associated trigger response pattern
- GetTriggerChamber(localStruct, xyPattern, iChamber, iCath, icase);
+ for(Int_t iChamber = 0; iChamber < 4; ++iChamber){
+ for(Int_t iCath = 0; iCath < 2; ++iCath){
- if (!xyPattern) continue;
+ Int_t pattern = (Int_t)xyPattern[iCath].At(iChamber);
+ if (!pattern) continue;
+
+ // get detElemId
+ AliMUONTriggerCircuit triggerCircuit;
+ AliMUONLocalTriggerBoard* localBoard = fCrateManager->LocalBoard(nBoard);
+ detElemId = triggerCircuit.DetElemId(iChamber+10, localBoard->GetName());//FIXME +/-10 (should be ok with new mapping)
+
- // get detElemId
- AliMUONTriggerCircuit triggerCircuit;
- detElemId = triggerCircuit.DetElemId(iChamber, localBoard->GetName());
- nBoard = localBoard->GetNumber();
+ if(iCath == 1){ // FIXME should find a more elegant way
+ // Don't save twice the same digit
+ // (since strips in non bending plane can cross several boards)
+ Int_t prevDetElemId = previousDetElemId[iChamber];
+ Int_t prevBoard = previousBoard[iChamber];
+ previousDetElemId[iChamber] = detElemId;
+ previousBoard[iChamber] = nBoard;
+
+ if(detElemId == prevDetElemId){
+ if(nBoard-prevBoard==1) continue;
+ }
+ }
- const AliMpVSegmentation* seg
- = AliMpSegmentation::Instance()
- ->GetMpSegmentation(detElemId, AliMp::GetCathodType(iCath));
+ const AliMpVSegmentation* seg
+ = AliMpSegmentation::Instance()
+ ->GetMpSegmentation(detElemId, AliMp::GetCathodType(iCath));
- // loop over the 16 bits of pattern
- for (Int_t ibitxy = 0; ibitxy < 16; ibitxy++) {
+ // loop over the 16 bits of pattern
+ for (Int_t ibitxy = 0; ibitxy < 16; ++ibitxy) {
- if ((xyPattern >> ibitxy) & 0x1) {
-
- // not quite sure about this
- Int_t offset = 0;
- if (iCath && localBoard->GetSwitch(6)) offset = -8;
-
- AliMpPad pad = seg->PadByLocation(AliMpIntPair(nBoard,ibitxy+offset),kTRUE);
-
- AliMUONDigit* digit = new AliMUONDigit();
- if (!pad.IsValid()) {
- AliWarning(Form("No pad for detElemId: %d, nboard %d, ibitxy: %d\n",
- detElemId, nBoard, ibitxy));
- continue;
- } //
-
- Int_t padX = pad.GetIndices().GetFirst();
- Int_t padY = pad.GetIndices().GetSecond();
-
- // file digit
- digit->SetPadX(padX);
- digit->SetPadY(padY);
- digit->SetSignal(1.);
- digit->SetCathode(iCath);
- digit->SetDetElemId(detElemId);
- digit->SetElectronics(nBoard, ibitxy);
- digitList.Add(digit);
+ if ((pattern >> ibitxy) & 0x1) {
+
+ // not quite sure about this
+ Int_t offset = 0;
+ if (iCath && localBoard->GetSwitch(6)) offset = -8;
+
+ AliMpPad pad = seg->PadByLocation(AliMpIntPair(nBoard,ibitxy+offset),kTRUE);
+
+ AliMUONDigit* digit = new AliMUONDigit();
+ if (!pad.IsValid()) {
+ AliWarning(Form("No pad for detElemId: %d, nboard %d, ibitxy: %d\n",
+ detElemId, nBoard, ibitxy));
+ continue;
+ } //
+
+ Int_t padX = pad.GetIndices().GetFirst();
+ Int_t padY = pad.GetIndices().GetSecond();
+
+ // file digit
+ digit->SetPadX(padX);
+ digit->SetPadY(padY);
+ digit->SetSignal(1.);
+ digit->SetCathode(iCath);
+ digit->SetDetElemId(detElemId);
+ digit->SetElectronics(nBoard, ibitxy);
+ digitList.Add(digit);
- }// xyPattern
- }// ibitxy
- }// case
+ }// xyPattern
+ }// ibitxy
+ }// cath
+ } // ichamber
return kTRUE;
}
#include "TStopwatch.h"
class TList;
+class TArrayS;
class AliRawReader;
class AliMUONData;
class AliMUONGlobalTrigger;
class AliMUONLocalTrigger;
class AliMUONTriggerCrateStore;
-class AliMUONLocalTriggerBoard;
class AliMUONLocalStruct;
class AliMUONRawStreamTracker;
Int_t GetMapping(Int_t buspatchId, UShort_t manuId,
UChar_t channelId, AliMUONDigit* digit );
- Int_t TriggerDigits(AliMUONLocalTriggerBoard* localBoard,
- AliMUONLocalStruct* localStruct, TList& digitList );
-
- void GetTriggerChamber(AliMUONLocalStruct* localStruct,
- Int_t& xyPattern, Int_t& iChamber, Int_t& iCath, Int_t iCase );
+ Int_t TriggerDigits(Int_t nBoard, TArrayS* xyPattern, TList& digitList );
/// Set flag to generates scaler event
void SetScalerEvent() {fScalerEvent = kTRUE;}
// AliDebug(1,Form("Making Digit Container for event %d",iEvent));
// loader->MakeDigitsContainer();
// }
- // Digits are not stored on disk and created on flight from rawdata.
- // In order to write digits on disk the following lines should be uncommented
- // fMUONData->MakeBranch("D,GLT");
- // fMUONData->SetTreeAddress("D,GLT");
- fMUONData->SetDataContainer("D, GLT");
+ // Write digits from raw data on disk
+ if (strstr(GetOption(),"SAVEDIGITS")) {
+ if (!loader->TreeD())fMUONData->GetLoader()->MakeDigitsContainer();
+ fMUONData->MakeBranch("D,GLT");
+ fMUONData->SetTreeAddress("D,GLT");
+ AliInfo("Digits from raw data will be stored.");
+ }
+ else {
+ fMUONData->SetDataContainer("D, GLT");
+ }
rawTimer.Start(kFALSE);
fDigitMaker->Raw2Digits(rawReader);
rawTimer.Stop();
calibration->ExecuteTask();
calibTimer.Stop();
}
- // Digits are not stored on disk and created on flight from rawdata.
- // In order to write digits on disk the following lines should be uncommented
- // fMUONData->Fill("D,GLT");
- // loader->WriteDigits("OVERWRITE");
+
+ // Write digits from raw data on disk
+ if (strstr(GetOption(),"SAVEDIGITS")) {
+ fMUONData->Fill("D,GLT");
+ loader->WriteDigits("OVERWRITE");
+ }
//----------------------- digit2cluster & Trigger2Trigger -------------------
clusterTimer.Start(kFALSE);
Double_t fitFmin, chi2MatchTrigger;
Double_t xRec, yRec, zRec, bendingSlope, nonBendingSlope, inverseBendingMomentum;
Double_t xVtx, yVtx, zVtx, bendingSlopeAtVtx, nonBendingSlopeAtVtx, inverseBendingMomentumAtVtx;
- Bool_t matchTrigger;
+ Int_t matchTrigger;
+ UShort_t hitsPatternInTrigCh;
// setting pointer for tracks, triggertracks & trackparam at vertex
AliMUONTrack* recTrack = 0;
fitFmin = recTrack->GetFitFMin();
matchTrigger = recTrack->GetMatchTrigger();
chi2MatchTrigger = recTrack->GetChi2MatchTrigger();
+ hitsPatternInTrigCh = recTrack->GetHitsPatternInTrigCh();
// setting data member of ESD MUON
// at first station
theESDTrack->SetNHit(nTrackHits);
theESDTrack->SetMatchTrigger(matchTrigger);
theESDTrack->SetChi2MatchTrigger(chi2MatchTrigger);
+ theESDTrack->SetHitsPatternInTrigCh(hitsPatternInTrigCh);
// storing ESD MUON Track into ESD Event
if (nRecTracks != 0)
fFitWithVertex(kFALSE),
fVertex(0x0),
fFitFMin(-1.),
- fMatchTrigger(kFALSE),
+ fMatchTrigger(-1),
floTrgNum(-1),
fChi2MatchTrigger(0.),
- fTrackID(0)
+ fTrackID(0),
+ fHitsPatternInTrigCh(0)
{
/// Default constructor
}
fFitWithVertex(kFALSE),
fVertex(0x0),
fFitFMin(-1.),
- fMatchTrigger(kFALSE),
+ fMatchTrigger(-1),
floTrgNum(-1),
fChi2MatchTrigger(0.),
- fTrackID(0)
+ fTrackID(0),
+ fHitsPatternInTrigCh(0)
{
/// Constructor from thw hitForRec's
fMatchTrigger(theMUONTrack.fMatchTrigger),
floTrgNum(theMUONTrack.floTrgNum),
fChi2MatchTrigger(theMUONTrack.fChi2MatchTrigger),
- fTrackID(theMUONTrack.fTrackID)
+ fTrackID(theMUONTrack.fTrackID),
+ fHitsPatternInTrigCh(theMUONTrack.fHitsPatternInTrigCh)
{
///copy constructor
Int_t maxIndex = 0;
fMatchTrigger = theMUONTrack.fMatchTrigger;
floTrgNum = theMUONTrack.floTrgNum;
fChi2MatchTrigger = theMUONTrack.fChi2MatchTrigger;
- fTrackID = theMUONTrack.fTrackID;
+ fTrackID = theMUONTrack.fTrackID;
+ fHitsPatternInTrigCh = theMUONTrack.fHitsPatternInTrigCh;
return *this;
}
Double_t GetFitFMin(void) const {return fFitFMin;}
/// set the minimum value of the function minimized by the fit
void SetFitFMin(Double_t chi2) { fFitFMin = chi2; }
- /// return kTrue if track matches with trigger track, kFalse if not
- Bool_t GetMatchTrigger(void) const {return fMatchTrigger;}
+ /// return 0,1,2 if track matches with trigger track, -1 if not
+ Int_t GetMatchTrigger(void) const {return fMatchTrigger;}
/// returns the local trigger number corresponding to the trigger track
Int_t GetLoTrgNum(void) const {return floTrgNum;}
/// set the flag telling whether track matches with trigger track or not
- void SetMatchTrigger(Bool_t matchTrigger) {fMatchTrigger = matchTrigger;}
+ void SetMatchTrigger(Int_t matchTrigger) {fMatchTrigger = matchTrigger;}
/// set the local trigger number corresponding to the trigger track
void SetLoTrgNum(Int_t loTrgNum) {floTrgNum = loTrgNum;}
/// return the chi2 of trigger/track matching
/// set track number in TrackRefs
void SetTrackID(Int_t trackID) {fTrackID = trackID;}
+ /// set word telling which trigger chambers where hit by track
+ UShort_t GetHitsPatternInTrigCh() const {return fHitsPatternInTrigCh;}
+ /// set word telling which trigger chambers where hit by track
+ void SetHitsPatternInTrigCh(UShort_t hitsPatternInTrigCh) {fHitsPatternInTrigCh = hitsPatternInTrigCh;}
+
Double_t TryOneHitForRec(AliMUONHitForRec* hitForRec);
Double_t TryTwoHitForRec(AliMUONHitForRec* hitForRec1, AliMUONHitForRec* hitForRec2);
AliMUONHitForRec *fVertex; //!< Vertex used during the tracking procedure if required
Double_t fFitFMin; ///< minimum value of the function minimized by the fit
- Bool_t fMatchTrigger; ///< 1 if track matches with trigger track, 0 if not
+ Int_t fMatchTrigger; ///< -1 track does not match trigger
+ ///< 0 track match but does not pass pt cut
+ ///< 1 track match Low pt cut
+ ///< 2 track match High pt cut
Int_t floTrgNum; ///< the number of the corresponding loTrg, -1 if no matching
Double_t fChi2MatchTrigger; ///< chi2 of trigger/track matching
Int_t fTrackID; ///< track ID = track number in TrackRefs
+ UShort_t fHitsPatternInTrigCh; ///< Word containing info on the hits left in trigger chambers
- ClassDef(AliMUONTrack, 4) // Reconstructed track in ALICE dimuon spectrometer
+ ClassDef(AliMUONTrack, 5) // Reconstructed track in ALICE dimuon spectrometer
};
#endif
--- /dev/null
+/**************************************************************************
+ * 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. *
+ **************************************************************************/
+
+////////////////////////////////////
+///
+/// \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 "AliMUONData.h"
+#include "AliMUONTrack.h"
+#include "AliMUONTrackParam.h"
+#include "AliMUONTrackExtrap.h"
+#include "AliMUONConstants.h"
+#include "AliMUONGeometryTransformer.h"
+#include "AliMUONDigit.h"
+#include "AliMUONLocalTrigger.h"
+#include "AliMUONTriggerCrateStore.h"
+#include "AliMUONLocalTriggerBoard.h"
+#include "AliMUONTriggerCircuit.h"
+#include "AliMUONDigitMaker.h"
+
+#include "AliMpPad.h"
+#include "AliMpVSegmentation.h"
+#include "AliMpSegmentation.h"
+
+#include "AliLog.h"
+#include "AliTracker.h"
+#include "AliMagF.h"
+
+#include <Riostream.h>
+#include <TClonesArray.h>
+#include <TMath.h>
+#include <TMatrixD.h>
+#include <TArrayS.h>
+
+/// \cond CLASSIMP
+ClassImp(AliMUONTrackHitPattern) // Class implementation in ROOT context
+/// \endcond
+
+
+//______________________________________________________________________________
+AliMUONTrackHitPattern::AliMUONTrackHitPattern(AliMUONData *data)
+ : TObject(),
+ fMUONData(data),
+ fTransformer(new AliMUONGeometryTransformer(kTRUE)),
+ fCrateManager(new AliMUONTriggerCrateStore())
+{
+ /// Default constructor
+
+ // Set magnetic field
+ 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;
+}
+
+
+//______________________________________________________________________________
+void AliMUONTrackHitPattern::GetHitPattern(TClonesArray *recTracksPtr)
+{
+ //
+ /// 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}};
+ 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];
+ }
+ }
+ muonTrack->SetHitsPatternInTrigCh(pattern);
+ }
+ return;
+}
+
+
+//______________________________________________________________________________
+void AliMUONTrackHitPattern::FindPadMatchingTrack(AliMUONTrackParam *trackParam,
+ Bool_t isMatch[2], Int_t iChamber)
+{
+ //
+ /// 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.;
+ }
+
+ 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;
+ }
+
+ return;
+}
+
+
+//______________________________________________________________________________
+Float_t AliMUONTrackHitPattern::MinDistanceFromPad(Float_t xPad, Float_t yPad, Float_t zPad,
+ Float_t dpx, Float_t dpy, AliMUONTrackParam *trackParam)
+{
+ //
+ /// 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);
+
+ Float_t maxDistX = 3.*(sigmaX + sigmaMS); // in cm
+ Float_t maxDistY = 3.*(sigmaY + sigmaMS); // 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)
+{
+ //
+ /// 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));
+
+ 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;
+}
+
+
+//____________________________________________________________________
+Bool_t AliMUONTrackHitPattern::TriggerDigits()
+{
+ //
+ /// 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;
+}
--- /dev/null
+#ifndef ALIMUONTRACKHITPATTERN_H
+#define ALIMUONTRACKHITPATTERN_H
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice */
+
+/// \ingroup rec
+/// \class AliMUONTrackHitPattern
+/// \brief Class for the MUON track hit pattern
+///
+// Author: Diego Stocco
+
+#include <TObject.h>
+#include <TList.h>
+
+class AliMUONData;
+class AliMUONLocalStruct;
+class AliMUONLocalTriggerBoard;
+class AliMUONTrackParam;
+class AliMUONTriggerCrateStore;
+
+class AliMUONGeometryTransformer;
+
+class TClonesArray;
+
+class AliMUONTrackHitPattern : public TObject {
+public:
+ AliMUONTrackHitPattern(AliMUONData *MUONData); // Default Constructor
+ virtual ~AliMUONTrackHitPattern(); // Destructor
+
+ void GetHitPattern(TClonesArray *recTracksArray);
+
+ void FindPadMatchingTrack(AliMUONTrackParam *trackParam, Bool_t isMatch[2], Int_t iChamber);
+ Float_t MinDistanceFromPad(Float_t xPad, Float_t yPad, Float_t zPad,
+ Float_t dpx, Float_t dpy, AliMUONTrackParam *trackParam);
+ void GetPosUncertainty(AliMUONTrackParam *trackParm, Float_t zChamber,
+ Float_t &sigmaX, Float_t &sigmaY, Float_t &sigmaMS);
+
+ Bool_t TriggerDigits();
+
+private:
+ AliMUONData *fMUONData; ///< Data container for MUON subsystem
+ TList fTriggerDigitsList[4]; ///< List of trigger digits, one per chamber
+ AliMUONGeometryTransformer *fTransformer; //!< pointer to transformation
+ AliMUONTriggerCrateStore *fCrateManager; ///< pointer to crate manager
+
+ ClassDef(AliMUONTrackHitPattern, 0) // MUON track hit pattern
+};
+
+#endif
#include "AliMUONTrack.h"
#include "AliMUONTrackParam.h"
#include "AliMUONTrackExtrap.h"
+#include "AliMUONTrackHitPattern.h"
#include "AliLog.h"
#include "AliTracker.h"
const AliMagF* kField = AliTracker::GetFieldMap();
if (!kField) AliFatal("No field available");
AliMUONTrackExtrap::SetField(kField);
+
+ fTrackHitPattern = new AliMUONTrackHitPattern(fMUONData);
}
//__________________________________________________________________________
delete [] fIndexOfFirstHitForRecPerChamber;
delete fTriggerTrack;
delete fHitsForRecPtr;
+ delete fTrackHitPattern;
}
//__________________________________________________________________________
MakeTracks();
if (fMUONData->IsTriggerTrackBranchesInTree())
ValidateTracksWithTrigger();
-
+
+ fTrackHitPattern->GetHitPattern(fRecTracksPtr);
+
// Add tracks to MUON data container
for(Int_t i=0; i<fNRecTracks; i++) {
AliMUONTrack * track = (AliMUONTrack*) fRecTracksPtr->At(i);
AliMUONTrack *track;
AliMUONTrackParam trackParam;
AliMUONTriggerTrack *triggerTrack;
+ AliMUONLocalTrigger *locTrg;
fMUONData->SetTreeAddress("RL");
fMUONData->GetRecTriggerTracks();
TClonesArray *recTriggerTracks = fMUONData->RecTriggerTracks();
-
- Bool_t matchTrigger;
+
+ fMUONData->SetTreeAddress("TC");
+ fMUONData->GetTrigger();
+ TClonesArray *localTrigger = fMUONData->LocalTrigger();
+
+ Int_t matchTrigger;
Int_t loTrgNum;
Double_t distTriggerTrack[3];
Double_t xTrack, yTrack, ySlopeTrack, chi2MatchTrigger, minChi2MatchTrigger, chi2;
track = (AliMUONTrack*) fRecTracksPtr->First();
while (track) {
- matchTrigger = kFALSE;
+ matchTrigger = -1;
chi2MatchTrigger = 0.;
loTrgNum = -1;
+ Int_t doubleMatch=-1; // Check if track matches 2 trigger tracks
+ Double_t doubleChi2 = -1.;
trackParam = *((AliMUONTrackParam*) (track->GetTrackParamAtHit()->Last()));
AliMUONTrackExtrap::ExtrapToZ(&trackParam, AliMUONConstants::DefaultChamberZ(10)); // extrap to 1st trigger chamber
chi2 = 0.;
for (Int_t iVar = 0; iVar < 3; iVar++) chi2 += distTriggerTrack[iVar]*distTriggerTrack[iVar];
chi2 /= 3.; // Normalized Chi2: 3 degrees of freedom (X,Y,slopeY)
- if (chi2 < minChi2MatchTrigger && chi2 < fMaxNormChi2MatchTrigger) {
- minChi2MatchTrigger = chi2;
- matchTrigger = kTRUE;
- chi2MatchTrigger = chi2;
- loTrgNum=triggerTrack->GetLoTrgNum();
+ if (chi2 < fMaxNormChi2MatchTrigger) {
+ Bool_t isDoubleTrack = (TMath::Abs(chi2 - minChi2MatchTrigger)<1.);
+ if (chi2 < minChi2MatchTrigger && chi2 < fMaxNormChi2MatchTrigger) {
+ if(isDoubleTrack){
+ doubleMatch = loTrgNum;
+ doubleChi2 = chi2MatchTrigger;
+ }
+ minChi2MatchTrigger = chi2;
+ chi2MatchTrigger = chi2;
+ loTrgNum=triggerTrack->GetLoTrgNum();
+ locTrg = (AliMUONLocalTrigger*)localTrigger->UncheckedAt(loTrgNum);
+ matchTrigger=0;
+ if(locTrg->LoLpt()>0)matchTrigger=1;
+ if(locTrg->LoHpt()>0)matchTrigger=2;
+ }
+ else if(isDoubleTrack) {
+ doubleMatch = triggerTrack->GetLoTrgNum();
+ doubleChi2 = chi2;
+ }
}
triggerTrack = (AliMUONTriggerTrack*) recTriggerTracks->After(triggerTrack);
}
+ 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 = (AliMUONLocalTrigger*)localTrigger->UncheckedAt(doubleMatch);
+ if((locTrg1->LoLpt()>0 && matchTrigger<1) || (locTrg1->LoHpt() && matchTrigger<2)){
+ if(locTrg1->LoHpt()>0)matchTrigger=2;
+ else matchTrigger=1;
+ loTrgNum = doubleMatch;
+ chi2MatchTrigger=doubleChi2;
+ }
+ }
track->SetMatchTrigger(matchTrigger);
track->SetLoTrgNum(loTrgNum);
class TClonesArray;
class AliMUONData;
class AliMUONTriggerTrack;
+class AliMUONTrackHitPattern;
class AliMUONVTrackReconstructor : public TObject {
/// \todo add comment
virtual void FillMUONTrack(void) = 0;
+ AliMUONTrackHitPattern *fTrackHitPattern; ///< Pointer to class for hit pattern recognition
+
private:
AliMUONTriggerTrack* fTriggerTrack; ///< Trigger track structure
// Use the following to disconnect the status map creation (only for debug!)
// as this speeds up startup a bit...
//MuonRec.SetOption("MUON","NOSTATUSMAP");
+// Use the following to write to disk the digits (from raw data)
+//MuonRec.SetOption("MUON","SAVEDIGITS");
MuonRec.Run();
.q
EOF
-echo "Moving Digits files back ..."
-mv MUON.Digits/MUON.Digits.root .
+if [ ! -e MUON.Digits.root ]; then
+ echo "Moving Digits files back ..."
+ mv MUON.Digits/MUON.Digits.root .
+fi
echo "Running Trigger efficiency ..."
aliroot -b >& testTriggerResults.out << EOF
#pragma link C++ class AliMUONClusterFinderCOG+;
#pragma link C++ class AliMUONClusterFinderMLEM+;
#pragma link C++ class AliMUONClusterSplitterMLEM+;
+#pragma link C++ class AliMUONTrackHitPattern+;
// calibration
#pragma link C++ class AliMUONDigitCalibrator+;
AliMUONCluster.cxx \
AliMUONPadStatusMaker.cxx \
AliMUONPadStatusMapMaker.cxx \
- AliMUONHVNamer.cxx
+ AliMUONHVNamer.cxx \
+ AliMUONTrackHitPattern.cxx
HDRS:= $(SRCS:.cxx=.h)