#include "AliLog.h"
#include "AliVTrack.h"
#include "AliVEvent.h"
+#include "AliESDEvent.h"
+#include "AliAODEvent.h"
#include "AliVTrdTrack.h"
+#include "AliESDTrdTrigger.h"
#include "AliTRDTriggerAnalysis.h"
AliTRDTriggerAnalysis::AliTRDTriggerAnalysis() :
TObject(),
- fTriggerFlags(0),
+ fTriggerFlags(),
fTriggerInputs(0),
fTriggerClasses(0),
+ fVerbosity(0),
fRequireMatch(kFALSE),
- fRequireMatchElectron(kTRUE),
- fRequireInTime(kFALSE),
+ fRequireMatchElectron(kFALSE),
+ fRequireInTime(kTRUE),
+ fTRDlayerMaskEl(0x1),
+ fTRDnTrackletsEl(5),
fTRDptHSE(3.),
fTRDpidHSE(144),
fTRDptHQU(2.),
fTRDnHJT(3)
{
// ctor
+
+ memset(fTriggerFlags, 0, sizeof(fTriggerFlags));
}
AliTRDTriggerAnalysis::~AliTRDTriggerAnalysis()
// dtor
}
+void AliTRDTriggerAnalysis::ResetTriggers()
+{
+ // reset internal cache of trigger status
+
+ memset(fTriggerFlags, 0, sizeof(fTriggerFlags));
+ fTriggerInputs = fTriggerClasses = 0;
+}
+
Bool_t AliTRDTriggerAnalysis::CalcTriggers(const AliVEvent *event)
{
// evaluate the TRD trigger conditions,
return kFALSE;
}
- TString trgClasses = event->GetFiredTriggerClasses();
- // UInt_t trgInputs = event->GetHeader()->GetL1TriggerInputs();
+ // GTU information
+ UInt_t header = 0x0;
+
+ if (fVerbosity > 0)
+ printf("******************************************************************\n");
+ const AliESDEvent *esdEvent = dynamic_cast<const AliESDEvent*> (event);
+ if (esdEvent) {
+ AliESDTrdTrigger* trdTriggerInfo = esdEvent->GetTrdTrigger();
+
+ for (Int_t iSector = 0; iSector < 18; ++iSector) {
+ UInt_t trgFlags = trdTriggerInfo->GetFlags(iSector);
+
+ UInt_t trgContribs = fTriggerContribs[iSector] = trgFlags & 0xfff;
+ header |= trgContribs;
+ if (fVerbosity > 0)
+ printf("sector %2i: %5s %5s %5s %5s %5s %5s %5s %5s (0x%03x)\n", iSector,
+ trgContribs & (1 << 7) ? "TO" : "--",
+ trgContribs & (1 << 6) ? "E2" : "--",
+ trgContribs & (1 << 5) ? "E1" : "--",
+ trgContribs & (1 << 4) ? "J1" : "--",
+ trgContribs & (1 << 3) ? "H2" : "--",
+ trgContribs & (1 << 2) ? "H1" : "--",
+ trgContribs & (1 << 1) ? "E3" : "--",
+ trgContribs & (1 << 0) ? "M1" : "--",
+ trgContribs);
+
+ // trackingDoneTimeSMU = ((trgFlags >> 12) & 0x3ff) * 1./120.;
+
+ // for (Int_t iStack = 0; iStack < 5; ++iStack) {
+ // trackingDoneTMU = ((trgFlags >> 27) & (1 << iStack)) ? kTRUE : kFALSE; // TMU-level tracking done flag
+ // trackingDoneSMUStack = ((trgFlags >> 22) & (1 << iStack)) ? kTRUE : kFALSE; // SMU-level stack-related tracking done flag
+
+ // lmeFlags = trdTriggerInfo->GetLME(iStack) & 0xffffff;
+ // crcErrorFlags = (~(trdTriggerInfo->GetLME(iStack) >> 24)) & 0x3;
+ // }
+ }
+ if (fVerbosity > 0) {
+ printf("------------------------------------------------------------------\n");
+ printf("total : %5s %5s %5s %5s %5s %5s %5s %5s (0x%03x)\n",
+ header & (1 << 7) ? "TO" : "--",
+ header & (1 << 6) ? "E2" : "--",
+ header & (1 << 5) ? "E1" : "--",
+ header & (1 << 4) ? "J1" : "--",
+ header & (1 << 3) ? "H2" : "--",
+ header & (1 << 2) ? "H1" : "--",
+ header & (1 << 1) ? "E3" : "--",
+ header & (1 << 0) ? "M1" : "--",
+ header);
+ }
+ }
+ // evaluate trigger classes
+ TString trgClasses = event->GetFiredTriggerClasses();
+ if (trgClasses.Contains("TRDCO2"))
+ MarkClass(kHCO);
+ if (trgClasses.Contains("WUHJT"))
+ MarkClass(kHJT);
+ if (trgClasses.Contains("WUHSE"))
+ MarkClass(kHSE);
+ if (trgClasses.Contains("WUHQU"))
+ MarkClass(kHQU);
+ if (trgClasses.Contains("WUHEE"))
+ MarkClass(kHEE);
+
+ // evaluate trigger inputs
+ UInt_t trgInputs = 0;
+ if (esdEvent)
+ trgInputs = esdEvent->GetHeader()->GetL1TriggerInputs();
+ else if (const AliAODEvent *aodEvent = dynamic_cast<const AliAODEvent*> (event))
+ trgInputs = aodEvent->GetHeader()->GetL1TriggerInputs();
+ else
+ AliError("failed to retrieve L1 trigger inputs");
+
+ if (trgInputs & (1 << 8))
+ MarkInput(kHCO);
+ if (trgInputs & (1 << 9))
+ MarkInput(kHJT);
+ if (trgInputs & (1 << 10))
+ MarkInput(kHSE);
+ if (trgInputs & (1 << 12))
+ MarkInput(kHQU);
+ if (trgInputs & (1 << 13))
+ MarkInput(kHEE);
+
+ // evaluate TRD GTU tracks
Int_t nTracks[90] = { 0 }; // stack-wise counted number of tracks above pt threshold
Int_t nTrdTracks = event->GetNumberOfTrdTracks();
- if (nTrdTracks > 0)
- Fire(kHCO);
-
for (Int_t iTrack = 0; iTrack < nTrdTracks; ++iTrack) {
AliVTrdTrack *trdTrack = event->GetTrdTrack(iTrack);
- if (!trdTrack)
+ if (!trdTrack) {
+ AliError(Form("Failed to get track %i", iTrack));
continue;
+ }
+
+ Int_t globalStack = 5*trdTrack->GetSector() + trdTrack->GetStack();
+
+ MarkCondition(kHCO, globalStack);
+
+ for (Int_t iLayer = 0; iLayer < 6; ++iLayer) {
+ if (trdTrack->GetLayerMask() & (1 << iLayer)) {
+ AliVTrdTracklet *trkl = trdTrack->GetTracklet(iLayer);
+ if (!trkl) {
+ AliError(Form("no tracklet in layer %i where one should be for track %i",
+ iLayer, iTrack));
+ }
+ }
+ }
// ignore the track if it was not in time
// (if required)
if (fRequireMatch && !match)
continue;
- Int_t globalStack = 5*trdTrack->GetSector() + trdTrack->GetStack();
-
// stack-wise counting of tracks above pt threshold for jet trigger
- if (TMath::Abs(trdTrack->GetPt()) >= fTRDptHJT) {
+ if (TMath::Abs(trdTrack->Pt()) >= fTRDptHJT) {
++nTracks[globalStack];
}
if (fRequireMatchElectron && !match)
continue;
- if ((TMath::Abs(trdTrack->Pt()) > fTRDptHQU) && (trdTrack->GetPID() > fTRDpidHQU))
- Fire(kHQU);
+ // ignore the track for the electron triggers
+ // if it does not fulfill the tracklet requirement
+ if (trdTrack->GetNTracklets() < fTRDnTrackletsEl)
+ continue;
+ if ((trdTrack->GetLayerMask() & fTRDlayerMaskEl) != fTRDlayerMaskEl)
+ continue;
+
+ if ((TMath::Abs(trdTrack->Pt()) >= fTRDptHQU) && (trdTrack->GetPID() >= fTRDpidHQU))
+ MarkCondition(kHQU, globalStack);
- if ((TMath::Abs(trdTrack->Pt()) > fTRDptHSE) && (trdTrack->GetPID() > fTRDpidHSE))
- Fire(kHSE);
+ if ((TMath::Abs(trdTrack->Pt()) >= fTRDptHSE) && (trdTrack->GetPID() >= fTRDpidHSE))
+ MarkCondition(kHSE, globalStack);
if ((trdTrack->GetSector() >= fTRDminSectorHEE) && (trdTrack->GetSector() <= fTRDmaxSectorHEE) &&
- (TMath::Abs(trdTrack->Pt()) > fTRDptHSE) && (trdTrack->GetPID() > fTRDpidHSE))
- Fire(kHEE);
+ (TMath::Abs(trdTrack->Pt()) >= fTRDptHEE) && (trdTrack->GetPID() >= fTRDpidHEE))
+ MarkCondition(kHEE, globalStack);
}
// check if HJT condition is fulfilled in any stack
for (Int_t iStack = 0; iStack < 90; ++iStack) {
if (nTracks[iStack] >= fTRDnHJT) {
- Fire(kHJT);
+ MarkCondition(kHJT, iStack);
break;
}
}
AliTRDTriggerAnalysis();
~AliTRDTriggerAnalysis();
- enum TRDTrigger_t { kHCO = 0, kHJT, kHSE, kHQU, kHEE };
+ enum TRDTrigger_t { kHCO = 0, kHJT, kHSE, kHQU, kHEE, kHlast };
- void ResetTriggers() { fTriggerFlags = fTriggerInputs = fTriggerClasses = 0; }
+ void ResetTriggers();
Bool_t CalcTriggers(const AliVEvent* event);
- Bool_t IsFired(TRDTrigger_t trg) const { return (fTriggerFlags & (1 << trg)); }
+ Bool_t IsFired(TRDTrigger_t trg) const {
+ Obsolete("IsFired(...) is deprecated, use CheckCondition instead",
+ "now", "asap");
+ return CheckCondition(trg);
+ }
+
+ Bool_t HasTriggeredConfirmed(TRDTrigger_t trg) const {
+ return (HasTriggered(trg) && CheckCondition(trg));
+ }
+ Bool_t HasTriggered(TRDTrigger_t trg) const {
+ return (fTriggerClasses & (1 << trg));
+ }
+ Bool_t HasFired(TRDTrigger_t trg) const {
+ return (fTriggerInputs & (1 << trg));
+ }
+ Bool_t CheckCondition(TRDTrigger_t trg) const {
+ return (fTriggerFlags[2 * trg] | fTriggerFlags[2 * trg + 1]);
+ }
+ Bool_t CheckCondition(TRDTrigger_t trg, Int_t stack) const {
+ Int_t idx = 2 * trg + (stack / 64);
+ Int_t bit = stack % 64;
+ return (fTriggerFlags[idx] & (1ULL << bit));
+ }
+
+ Bool_t CheckTrgFlags(Int_t bit, Int_t sector) const {
+ return (fTriggerContribs[sector] & (1 << bit));
+ }
+
+ void SetRequireMatch(Bool_t val) { fRequireMatch = val; }
+ Bool_t GetRequireMatch() const { return fRequireMatch; }
+
+ void SetRequireMatchElectron(Bool_t val) { fRequireMatchElectron = val; }
+ Bool_t GetRequireMatchElectron() const { return fRequireMatchElectron; }
+
+ void SetRequireInTime(Bool_t val) { fRequireInTime = val; }
+ Bool_t GetRequireInTime() const { return fRequireInTime; }
+
+ void SetVerbosity(UChar_t val) { fVerbosity = val; }
+ UChar_t GetVerbosity() const { return fVerbosity; }
protected:
- void Fire(TRDTrigger_t trg) { fTriggerFlags |= (1 << trg); }
+ void MarkClass(TRDTrigger_t trg) { fTriggerClasses |= (1 << trg); }
+ void MarkInput(TRDTrigger_t trg) { fTriggerInputs |= (1 << trg); }
+ void MarkCondition(TRDTrigger_t trg, Int_t stack)
+ {
+ Int_t idx = 2 * trg + (stack / 64);
+ Int_t bit = stack % 64;
+ fTriggerFlags[idx] |= (1ULL << bit);
+ }
+
+
+ static const Int_t fgkNstacks = 90; // no. of TRD stacks (global)
+ ULong64_t fTriggerFlags[2 * kHlast]; //! internal representation of condition checks
+ UChar_t fTriggerInputs; //! internal representation of trigger inputs
+ UChar_t fTriggerClasses; //! internal representation of trigger classes
// configuration
- UChar_t fTriggerFlags; // internal representation of trigger decisions
- UChar_t fTriggerInputs; // internal representation of trigger decisions
- UChar_t fTriggerClasses; // internal representation of trigger decisions
+ UChar_t fVerbosity; // verbosity level
Bool_t fRequireMatch; // require a matched global track
// for all conditions
Bool_t fRequireMatchElectron; // require a matched global track
Bool_t fRequireInTime; // require the tracks to be in time
// trigger thresholds
+ UChar_t fTRDlayerMaskEl; // mask for tracklet requirements
+ UChar_t fTRDnTrackletsEl; // min. number of tracklets
Float_t fTRDptHSE; // pt threshold for HSE trigger
UChar_t fTRDpidHSE; // PID threshold for HSE trigger
Float_t fTRDptHQU; // pt threshold for HQU trigger
Float_t fTRDptHJT; // pt threshold for HJT trigger
UChar_t fTRDnHJT; // no of track threshold for HJT trigger
+ UInt_t fTriggerContribs[18]; // temporary for debugging !!!
+
ClassDef(AliTRDTriggerAnalysis, 1);
};