#include "AliMUONTrackParam.h"
#include "AliMUONTriggerTrack.h"
#include "AliMUONVTriggerTrackStore.h"
+#include "AliMUONTriggerStoreV1.h"
+#include "AliMUONLocalTrigger.h"
#include "AliMCEventHandler.h"
#include "AliMCEvent.h"
#include "AliStack.h"
#include "AliLog.h"
#include "AliESDEvent.h"
#include "AliESDMuonTrack.h"
+#include "AliMUONDigitStoreV2S.h"
+#include "AliMUONVDigit.h"
+#include "AliMpVSegmentation.h"
+#include "AliMpSegmentation.h"
+#include "AliMpPad.h"
#include "AliGeomManager.h"
+#include "AliCDBManager.h"
#include "AliMpCDB.h"
#include "AliMpDDLStore.h"
#include "AliMUONCDB.h"
#include "AliMUONTriggerCircuit.h"
#include "AliMUONVTrackReconstructor.h"
#include "AliMUONVTriggerStore.h"
+#include "AliMUONCalibrationData.h"
+#include "AliMUONTriggerElectronics.h"
+
#include "TGeoManager.h"
fRecoTriggerTrackStore(0x0),
fGeometryTransformer(0x0),
fTriggerCircuit(0x0),
+fCalibrationData(0x0),
+fTriggerElectronics(0x0),
fESDEventOwner(kTRUE)
{
/// Normal ctor
fRecoTriggerTrackStore(0x0),
fGeometryTransformer(0x0),
fTriggerCircuit(0x0),
+fCalibrationData(0x0),
+fTriggerElectronics(0x0),
fESDEventOwner(kFALSE)
{
/// Normal ctor
ResetStores();
delete fGeometryTransformer;
delete fTriggerCircuit;
+ delete fTriggerElectronics;
+ delete fCalibrationData;
}
//_____________________________________________________________________________
//_____________________________________________________________________________
Bool_t AliMUONRecoCheck::InitCircuit()
{
-
+
if ( fTriggerCircuit ) return kTRUE;
-
- if ( !AliMUONCDB::CheckOCDB() ) return kFALSE;
-
- if ( !AliGeomManager::GetGeometry() )
- AliGeomManager::LoadGeometry();
-
- if ( !AliMpDDLStore::Instance(false) )
- AliMpCDB::LoadDDLStore();
-
- fGeometryTransformer = new AliMUONGeometryTransformer();
- fGeometryTransformer->LoadGeometryData();
- fTriggerCircuit = new AliMUONTriggerCircuit(fGeometryTransformer);
-
+ if ( ! InitGeometryTransformer() ) return kFALSE;
+
// reset tracker for local trigger to trigger track conversion
- if ( ! AliMUONESDInterface::GetTracker() )
- AliMUONESDInterface::ResetTracker();
+ if ( ! AliMUONESDInterface::GetTracker() ) AliMUONESDInterface::ResetTracker();
+
+ fTriggerCircuit = new AliMUONTriggerCircuit(fGeometryTransformer);
return kTRUE;
}
//_____________________________________________________________________________
-AliMUONVTrackStore* AliMUONRecoCheck::ReconstructibleTracks(Int_t event, UInt_t requestedStationMask, Bool_t request2ChInSameSt45)
+AliMUONVTrackStore* AliMUONRecoCheck::ReconstructibleTracks(Int_t event, UInt_t requestedStationMask,
+ Bool_t request2ChInSameSt45, Bool_t hitInFrontOfPad)
{
/// Return a track store containing the reconstructible tracks for a given event,
/// according to the mask of requested stations and the minimum number of chambers hit in stations 4 & 5.
if (!fESDEventOwner) {
if (fRecoTrackRefStore == 0x0) {
if (TrackRefs(event) == 0x0) return 0x0;
- MakeReconstructibleTracks(requestedStationMask, request2ChInSameSt45);
+ MakeReconstructibleTracks(requestedStationMask, request2ChInSameSt45, hitInFrontOfPad);
}
return fRecoTrackRefStore;
}
if (fRecoTrackRefStore != 0x0) return fRecoTrackRefStore;
else {
if (TrackRefs(event) == 0x0) return 0x0;
- MakeReconstructibleTracks(requestedStationMask, request2ChInSameSt45);
+ MakeReconstructibleTracks(requestedStationMask, request2ChInSameSt45, hitInFrontOfPad);
return fRecoTrackRefStore;
}
}
if (esdTrack->ContainTriggerData()) AliMUONESDInterface::Add(*esdTrack, *tmpTriggerStore);
}
- if ( ! InitCircuit() ) return;
+ if ( InitCircuit() ) {
- AliMUONVTrackReconstructor* tracker = AliMUONESDInterface::GetTracker();
- tracker->EventReconstructTrigger(*fTriggerCircuit, *tmpTriggerStore, *fRecoTriggerTrackStore);
+ AliMUONVTrackReconstructor* tracker = AliMUONESDInterface::GetTracker();
+ tracker->EventReconstructTrigger(*fTriggerCircuit, *tmpTriggerStore, *fRecoTriggerTrackStore);
+ }
delete tmpTriggerStore;
}
//_____________________________________________________________________________
-void AliMUONRecoCheck::TriggerToTrack(const AliMUONLocalTrigger& locTrg, AliMUONTriggerTrack& triggerTrack)
+Bool_t AliMUONRecoCheck::TriggerToTrack(const AliMUONLocalTrigger& locTrg, AliMUONTriggerTrack& triggerTrack)
{
/// Make trigger track from local trigger info
- if ( ! InitCircuit() ) return;
+ if ( ! InitCircuit() ) return kFALSE;
AliMUONVTrackReconstructor* tracker = AliMUONESDInterface::GetTracker();
- tracker->TriggerToTrack(*fTriggerCircuit, locTrg, triggerTrack);
+ return tracker->TriggerToTrack(*fTriggerCircuit, locTrg, triggerTrack);
}
TParticle* particle;
TClonesArray* trackRefs;
Int_t nTrackRef = fMCEventHandler->MCEvent()->GetNumberOfTracks();
- AliMUONVClusterStore* cStore = AliMUONESDInterface::NewClusterStore();
- if (!cStore) return;
- AliMUONVCluster* hit = cStore->CreateCluster(0,0,0);
+ AliMUONVCluster* hit = AliMUONESDInterface::NewCluster();
// loop over simulated tracks
for (Int_t iTrackRef = 0; iTrackRef < nTrackRef; ++iTrackRef) {
CleanMuonTrackRef(tmpTrackRefStore);
delete hit;
- delete cStore;
delete tmpTrackRefStore;
}
if (!(fRecoTriggerRefStore = AliMUONESDInterface::NewTriggerTrackStore()))
return;
- Double_t x, y, z, slopeX, slopeY, pZ;
+ Double_t x, y, z, slopeX, slopeY, pZ, xLoc, yLoc, zLoc;
TParticle* particle;
TClonesArray* trackRefs;
Int_t nTrackRef = fMCEventHandler->MCEvent()->GetNumberOfTracks();
if (nHits < 1) continue;
AliMUONTriggerTrack track;
+ AliMUONDigitStoreV2S digitStore;
Int_t hitsOnTrigger = 0;
Int_t currCh = -1;
Int_t detElemId = trackReference->UserId();
Int_t chamberId = detElemId / 100 - 1;
if (chamberId < AliMUONConstants::NTrackingCh() || chamberId >= AliMUONConstants::NCh() ) continue;
-
-
+
+ // Get track parameters of current hit
+ x = trackReference->X();
+ y = trackReference->Y();
+ z = trackReference->Z();
+
+ if ( InitTriggerResponse() ) {
+ fGeometryTransformer->Global2Local(detElemId, x, y, z, xLoc, yLoc, zLoc);
+
+ Int_t nboard = 0;
+ for ( Int_t cath = AliMp::kCath0; cath <= AliMp::kCath1; ++cath )
+ {
+ const AliMpVSegmentation* seg
+ = AliMpSegmentation::Instance()
+ ->GetMpSegmentation(detElemId,AliMp::GetCathodType(cath));
+
+ AliMpPad pad = seg->PadByPosition(xLoc,yLoc,kFALSE);
+ Int_t ix = pad.GetIx();
+ Int_t iy = pad.GetIy();
+
+ if ( !pad.IsValid() ) continue;
+
+ if ( cath == AliMp::kCath0 ) nboard = pad.GetLocalBoardId(0);
+
+ AliMUONVDigit* digit = digitStore.Add(detElemId, nboard, pad.GetLocalBoardChannel(0),
+ cath, AliMUONVDigitStore::kDeny);
+ if (digit) {
+ digit->SetPadXY(ix,iy);
+ digit->SetCharge(1.);
+ }
+ }
+ }
+
if ( hitsOnTrigger == 0 ) {
- // Get track parameters of current hit
- x = trackReference->X();
- y = trackReference->Y();
- z = trackReference->Z();
pZ = trackReference->Pz();
slopeX = ( pZ == 0. ) ? 99999. : trackReference->Px() / pZ;
slopeY = ( pZ == 0. ) ? 99999. : trackReference->Py() / pZ;
}
} // loop on hits
-
- if ( hitsOnTrigger >= 3 ){
- // store the track
- track.SetUniqueID(iTrackRef);
- fRecoTriggerRefStore->Add(track);
+
+ if ( hitsOnTrigger < 3 ) continue;
+
+ // Check if the track passes the trigger algorithm
+ if ( InitTriggerResponse() ) {
+ AliMUONTriggerStoreV1 triggerStore;
+ fTriggerElectronics->Digits2Trigger(digitStore,triggerStore);
+
+ TIter next(triggerStore.CreateIterator());
+ AliMUONLocalTrigger* locTrg(0x0);
+
+ Int_t ptCutLevel = 0;
+
+ while ( ( locTrg = static_cast<AliMUONLocalTrigger*>(next()) ) )
+ {
+ if ( locTrg->IsTrigX() && locTrg->IsTrigY() )
+ {
+ ptCutLevel = TMath::Max(ptCutLevel, 1);
+ if ( locTrg->LoHpt() ) ptCutLevel = TMath::Max(ptCutLevel, 3);
+ else if ( locTrg->LoLpt() ) ptCutLevel = TMath::Max(ptCutLevel, 2);
+ } // board is fired
+ } // end of loop on Local Trigger
+ track.SetPtCutLevel(ptCutLevel);
}
+ track.SetUniqueID(iTrackRef);
+ fRecoTriggerRefStore->Add(track);
}
}
Double_t maxGasGap = 1.; // cm
Double_t x, y, z, pX, pY, pZ, x1, y1, z1, pX1, pY1, pZ1, z2;
Double_t bendingSlope,nonBendingSlope,inverseBendingMomentum;
- AliMUONVClusterStore* cStore = AliMUONESDInterface::NewClusterStore();
- if (!cStore) return;
- AliMUONVCluster* hit = cStore->CreateCluster(0,0,0);
+ AliMUONVCluster* hit = AliMUONESDInterface::NewCluster();
// create iterator
TIter next(tmpTrackRefStore->CreateIterator());
}
delete hit;
- delete cStore;
}
//_____________________________________________________________________________
-void AliMUONRecoCheck::MakeReconstructibleTracks(UInt_t requestedStationMask, Bool_t request2ChInSameSt45)
+void AliMUONRecoCheck::MakeReconstructibleTracks(UInt_t requestedStationMask, Bool_t request2ChInSameSt45,
+ Bool_t hitInFrontOfPad)
{
/// Isolate the reconstructible tracks
if (!(fRecoTrackRefStore = AliMUONESDInterface::NewTrackStore())) return;
+ // need geometry transformer and segmentation to check if trackrefs are located in front of pad(s)
+ if (hitInFrontOfPad) {
+ if (!InitGeometryTransformer()) return;
+ if (!AliMpSegmentation::Instance(kFALSE) && !AliMUONCDB::LoadMapping(kTRUE)) return;
+ }
+
// create iterator on trackRef
TIter next(fTrackRefStore->CreateIterator());
// loop over trackRef and add reconstructible tracks to fRecoTrackRefStore
AliMUONTrack* track;
while ( ( track = static_cast<AliMUONTrack*>(next()) ) ) {
- if (track->IsValid(requestedStationMask, request2ChInSameSt45)) fRecoTrackRefStore->Add(*track);
+
+ // check if the track is valid as it is
+ if (track->IsValid(requestedStationMask, request2ChInSameSt45)) {
+
+ if (hitInFrontOfPad) {
+
+ AliMUONTrack trackTmp(*track);
+
+ // loop over clusters and remove those which are not in front of pad(s)
+ AliMUONTrackParam *param = static_cast<AliMUONTrackParam*>(trackTmp.GetTrackParamAtCluster()->First());
+ while (param) {
+ AliMUONTrackParam *nextParam = static_cast<AliMUONTrackParam*>(trackTmp.GetTrackParamAtCluster()->After(param));
+ if (!IsHitInFrontOfPad(param)) trackTmp.RemoveTrackParamAtCluster(param);
+ param = nextParam;
+ }
+
+ // add the track if it is still valid
+ if (trackTmp.IsValid(requestedStationMask, request2ChInSameSt45)) fRecoTrackRefStore->Add(trackTmp);
+
+ } else {
+
+ // add the track
+ fRecoTrackRefStore->Add(*track);
+
+ }
+
+ }
+
}
}
TIter next(triggerTrackStore.CreateIterator());
AliMUONTriggerTrack* track2;
while ( ( track2 = static_cast<AliMUONTriggerTrack*>(next()) ) ) {
-
// check compatibility
if (track.Match(*track2, sigmaCut)) {
matchedTrack = track2;
}
+
+//____________________________________________________________________________
+Bool_t AliMUONRecoCheck::InitTriggerResponse()
+{
+ /// Initialize trigger electronics
+ /// for building of triggerable tracks from MC
+
+ if ( fTriggerElectronics ) return kTRUE;
+
+ if ( ! InitGeometryTransformer() ) return kFALSE;
+
+ if ( ! AliMpDDLStore::Instance(false) && ! AliMpCDB::LoadDDLStore()) return kFALSE;
+
+ if ( ! InitCalibrationData() ) return kFALSE;
+
+ fTriggerElectronics = new AliMUONTriggerElectronics(fCalibrationData);
+
+ return kTRUE;
+}
+
+
+//____________________________________________________________________________
+Bool_t AliMUONRecoCheck::InitCalibrationData()
+{
+ /// Initialize calibration data
+ if ( ! fCalibrationData ) {
+ if ( !AliMUONCDB::CheckOCDB() ) return kFALSE;
+ fCalibrationData = new AliMUONCalibrationData(AliCDBManager::Instance()->GetRun());
+ }
+ return kTRUE;
+}
+
+
+//____________________________________________________________________________
+Bool_t AliMUONRecoCheck::InitGeometryTransformer()
+{
+ /// Return geometry transformer
+ /// (create it if necessary)
+ if ( ! fGeometryTransformer ) {
+
+ if ( !AliMUONCDB::CheckOCDB() ) return kFALSE;
+
+ if (!AliGeomManager::GetGeometry()) {
+ AliGeomManager::LoadGeometry();
+ if (!AliGeomManager::GetGeometry()) return kFALSE;
+ if (!AliGeomManager::ApplyAlignObjsFromCDB("MUON")) return kFALSE;
+ }
+
+ fGeometryTransformer = new AliMUONGeometryTransformer();
+ fGeometryTransformer->LoadGeometryData();
+ }
+
+ return kTRUE;
+}
+
+//________________________________________________________________________
+Bool_t AliMUONRecoCheck::IsHitInFrontOfPad(AliMUONTrackParam *param) const
+{
+ /// Return kTRUE if the hit is located in front of at least 1 pad
+
+ Int_t deId = param->GetClusterPtr()->GetDetElemId();
+
+ Double_t xL, yL, zL;
+ fGeometryTransformer->Global2Local(deId, param->GetNonBendingCoor(), param->GetBendingCoor(), param->GetZ(), xL, yL, zL);
+
+ const AliMpVSegmentation* seg1 = AliMpSegmentation::Instance()->GetMpSegmentation(deId, AliMp::kCath0);
+ const AliMpVSegmentation* seg2 = AliMpSegmentation::Instance()->GetMpSegmentation(deId, AliMp::kCath1);
+ if (!seg1 || !seg2) return kFALSE;
+
+ AliMpPad pad1 = seg1->PadByPosition(xL, yL, kFALSE);
+ AliMpPad pad2 = seg2->PadByPosition(xL, yL, kFALSE);
+
+ return (pad1.IsValid() || pad2.IsValid());
+}
+