supports now several concurrent offline trigger selections. At present these are (defined in
AliVEvent.h --> EOfflineTriggerTypes):
1) AliVEvent::kMB: Minimum bias trigger (corresponding to the old behavior), all detectors
2) AliVEvent::kMBNoTRD: Same as kMB, but TRD not read out (this is a separate online trigger
class which became active now)
3) AliVEvent::kMUON: Muon trigger
4) AliVEvent::kHighMult: High-multiplicity trigger
For all those the (usual) offline SPD or V0 selection is performed. The available offline
triggers will be extended when needed.
To use this functionality you call for your task SetCollisionCandidates with a mask, composed
from the above flags. E.g. to select MB and MUON events:
myTask->SetCollisionCandidates(AliVEvent::kMB | AliVEvent::kMUON)
Doing that your task is only called for the requested events.
If in your UserExec you want to look at the decision of the physics selection, you can do that
in the same way as before with
UInt_t mask = fInputHandler->IsEventSelected()
and in mask the bits corresponding to the above offline triggers are set.
The output bit mask of the physics selection is stored in the AOD event header, and therefore
the AOD analysis can work in the same way as ESD analysis. I.e. you can use
myTask->SetCollisionCandidates and fInputHandler->IsEventSelected() in the exact same way.
Andrei & Jan Fiete
AliAODHeader* header = AODEvent()->GetHeader();\r
\r
header->SetRunNumber(esd->GetRunNumber());\r
+ header->SetOfflineTrigger(fInputHandler->IsEventSelected()); // propagate the decision of the physics selection\r
if (old) {\r
header->SetBunchCrossNumber(0);\r
header->SetOrbitNumber(0);\r
// Save PID object for candidate electrons\r
Bool_t pidSave = kFALSE;\r
if (fTrackFilter) {\r
- Bool_t selectInfo = fTrackFilter->IsSelected("Electrons");\r
+ Bool_t selectInfo = fTrackFilter->IsSelected((char*) "Electrons");\r
if (selectInfo) pidSave = kTRUE;\r
}\r
\r
fTreeA(0x0),
fCurrentRunNumber(-1),
fHistosQA(0x0),
- fSelectCollisions(0)
+ fOfflineTriggerMask(0)
{
// Default constructor
}
fTreeA(0x0),
fCurrentRunNumber(-1),
fHistosQA(0x0),
- fSelectCollisions(0)
+ fOfflineTriggerMask(0)
{
// Default constructor
DefineInput (0, TChain::Class());
fTreeA(0x0),
fCurrentRunNumber(-1),
fHistosQA(0x0),
- fSelectCollisions(0)
+ fOfflineTriggerMask(0)
{
// Copy constructor
fDebug = obj.fDebug;
fTreeA = other.fTreeA;
fCurrentRunNumber = other.fCurrentRunNumber;
fHistosQA = other.fHistosQA;
- fSelectCollisions = other.fSelectCollisions;
+ fOfflineTriggerMask = other.fOfflineTriggerMask;
return *this;
}
AliAODInputHandler* aodH = dynamic_cast<AliAODInputHandler*>(fInputHandler);
//
// Was event selected ?
- Bool_t isSelected = kTRUE;
- if( fInputHandler && fInputHandler->GetEventSelection() && fSelectCollisions) {
- isSelected = fInputHandler->IsEventSelected();
+ UInt_t isSelected = 0;
+ if( fInputHandler && fInputHandler->GetEventSelection() && fOfflineTriggerMask) {
+ isSelected = fInputHandler->IsEventSelected() & fOfflineTriggerMask;
}
if (handler) handler->SetFillAOD(isSelected);
mcH = (AliMCEventHandler*) ((AliAnalysisManager::GetAnalysisManager())->GetMCtruthEventHandler());
if (!mcH) {
- if (!fSelectCollisions || isSelected)
+ if (!fOfflineTriggerMask || isSelected)
UserExec(option);
} else {
- if ((!fSelectCollisions || isSelected) && (mcH->InitOk()))
+ if ((!fOfflineTriggerMask || isSelected) && (mcH->InitOk()))
UserExec(option);
}
/* $Id$ */
#include "AliAnalysisTask.h"
-class AliVEvent;
+#include "AliVEvent.h"
+
class AliAODEvent;
class AliAODHeader;
class AliAODTracklets;
// Helpers for adding branches to the AOD
virtual void AddAODBranch(const char* cname, void* addobj, const char *fname="");
// Event Selection
- virtual void SelectCollisionCandidates() {fSelectCollisions = kTRUE;}
+ virtual void SelectCollisionCandidates(UInt_t offlineTriggerMask = AliVEvent::kMB) {fOfflineTriggerMask = offlineTriggerMask;}
// Getters
virtual Int_t DebugLevel() {return fDebug; }
virtual AliVEvent* InputEvent() {return fInputEvent;}
static AliAODCaloCells* fgAODPhosCells; //! Phos Cell replication
static TClonesArray* fgAODDimuons; //! Dimuons replication
// Event Selection
- Bool_t fSelectCollisions; // Task processes collision candidates only
+ UInt_t fOfflineTriggerMask; // Task processes collision candidates only
- ClassDef(AliAnalysisTaskSE, 3); // Analysis task for standard jet analysis
+ ClassDef(AliAnalysisTaskSE, 4); // Analysis task for standard jet analysis
};
#endif
// the same order. We thus also have to sort the list (sorting is
// done by name in TList).
- AliInfo("Merging");
+ //AliInfo("Merging");
if (!list)
return 0;
while ((hist= iterlist->Next())){
if(!otherlist->FindObject(hist->GetName())){
- AliInfo(Form("Adding object %s",hist->GetName()));
+ //AliInfo(Form("Adding object %s",hist->GetName()));
foundDiffinThisIterStep = kTRUE;
TH1 * hclone = (TH1*) hist->Clone();
hclone->Reset();
AliESDtrackCuts(const Char_t* name = "AliESDtrackCuts", const Char_t* title = "");
virtual ~AliESDtrackCuts();
- Bool_t IsSelected(TObject* obj)
+ virtual Bool_t IsSelected(TObject* obj)
{return AcceptTrack((AliESDtrack*)obj);}
- Bool_t IsSelected(TList* /*list*/) {return kTRUE;}
+ virtual Bool_t IsSelected(TList* /*list*/) {return kTRUE;}
Bool_t AcceptTrack(AliESDtrack* esdTrack);
TObjArray* GetAcceptedTracks(AliESDEvent* esd, Bool_t bTPC = kFALSE);
}
-Bool_t AliPhysicsSelection::CheckTriggerClass(const AliESDEvent* aEsd, const char* trigger) const
+UInt_t AliPhysicsSelection::CheckTriggerClass(const AliESDEvent* aEsd, const char* trigger) const
{
// checks if the given trigger class(es) are found for the current event
- // format of trigger: +TRIGGER1 -TRIGGER2
+ // format of trigger: +TRIGGER1 -TRIGGER2 [#XXX] [&YY]
// requires TRIGGER1 and rejects TRIGGER2
+ // in bunch crossing XXX
+ // if successful, a word with bit YY set is returned (for association between entry in fCollTrigClasses and AliVEvent::EOfflineTriggerTypes)
Bool_t foundBCRequirement = kFALSE;
Bool_t foundCorrectBC = kFALSE;
+ UInt_t returnCode = AliVEvent::kUserDefined;
+
TString str(trigger);
TObjArray* tokens = str.Tokenize(" ");
AliDebug(AliLog::kDebug, Form("Found correct bunch crossing %d", bcNumber));
}
}
+ else if (str2[0] == '&' && !fUsingCustomClasses)
+ {
+ str2.Remove(0, 1);
+
+ returnCode = 1 << str2.Atoi();
+ }
else
AliFatal(Form("Invalid trigger syntax: %s", trigger));
}
if (foundBCRequirement && !foundCorrectBC)
return kFALSE;
- return kTRUE;
+ return returnCode;
}
-Bool_t AliPhysicsSelection::IsCollisionCandidate(const AliESDEvent* aEsd)
+UInt_t AliPhysicsSelection::IsCollisionCandidate(const AliESDEvent* aEsd)
{
// checks if the given event is a collision candidate
+ //
+ // returns a bit word describing the fired offline triggers (see AliVEvent::EOfflineTriggerTypes)
if (fCurrentRun != aEsd->GetRunNumber())
if (!Initialize(aEsd->GetRunNumber()))
AliFatal(Form("Invalid event type for MC: %d", esdHeader->GetEventType()));
}
- Bool_t accept = kFALSE;
+ UInt_t accept = 0;
Int_t count = fCollTrigClasses.GetEntries() + fBGTrigClasses.GetEntries();
for (Int_t i=0; i < count; i++)
triggerAnalysis->FillTriggerClasses(aEsd);
- if (CheckTriggerClass(aEsd, triggerClass))
+ UInt_t singleTriggerResult = CheckTriggerClass(aEsd, triggerClass);
+ if (singleTriggerResult)
{
triggerAnalysis->FillHistograms(aEsd);
fHistStatistics[iHistStat]->Fill(kStatAccepted, i);
if(iHistStat == kStatIdxAll) fHistBunchCrossing->Fill(aEsd->GetBunchCrossNumber(), i); // Fill only for all (avoid double counting)
if((i < fCollTrigClasses.GetEntries() || fSkipTriggerClassSelection) && (iHistStat==kStatIdxAll))
- accept = kTRUE; // only set for "all" (should not really matter)
+ accept |= singleTriggerResult; // only set for "all" (should not really matter)
}
}
else
}
if (accept)
- AliDebug(AliLog::kDebug, "Accepted event as collision candidate");
+ AliDebug(AliLog::kDebug, Form("Accepted event as collision candidate with bit mask %d", accept));
return accept;
}
AliError("Bin0 Callback not set: will not fill the statistics for the bin 0");
if (fMC) {
- // ovverride BX and bg options in case of MC
+ // override BX and bg options in case of MC
fComputeBG = kFALSE;
fUseBXNumbers = kFALSE;
}
switch (triggerScheme)
{
case 0:
- fCollTrigClasses.Add(new TObjString(""));
+ fCollTrigClasses.Add(new TObjString("&0"));
break;
case 1:
- { // need a new scope to avoid cross-initialization errors
-
- if (fUseMuonTriggers) {
- // Muon trigger have the same BXIDs of the corresponding CINT triggers
- fCollTrigClasses.Add(new TObjString(Form("%s%s ","+CMUS1B-ABCE-NOPF-MUON", GetBXIDs(runNumber,"CINT1B-ABCE-NOPF-ALL"))));
- fBGTrigClasses.Add (new TObjString(Form("%s%s ","+CMUS1A-ABCE-NOPF-MUON", GetBXIDs(runNumber,"CINT1A-ABCE-NOPF-ALL"))));
- fBGTrigClasses.Add (new TObjString(Form("%s%s ","+CMUS1C-ABCE-NOPF-MUON", GetBXIDs(runNumber,"CINT1C-ABCE-NOPF-ALL"))));
- fBGTrigClasses.Add (new TObjString(Form("%s%s ","+CMUS1-E-NOPF-MUON" , GetBXIDs(runNumber,"CINT1-E-NOPF-ALL"))));
- }
- TObjString * cint1b = new TObjString(Form("%s%s","+CINT1B-ABCE-NOPF-ALL", GetBXIDs(runNumber,"CINT1B-ABCE-NOPF-ALL")));
- TObjString * cint1a = new TObjString(Form("%s%s","+CINT1A-ABCE-NOPF-ALL", GetBXIDs(runNumber,"CINT1A-ABCE-NOPF-ALL")));
- TObjString * cint1c = new TObjString(Form("%s%s","+CINT1C-ABCE-NOPF-ALL", GetBXIDs(runNumber,"CINT1C-ABCE-NOPF-ALL")));
- TObjString * cint1e = new TObjString(Form("%s%s","+CINT1-E-NOPF-ALL", GetBXIDs(runNumber,"CINT1-E-NOPF-ALL")) );
- //
- fCollTrigClasses.Add(cint1b);
- fBGTrigClasses.Add(cint1a);
- fBGTrigClasses.Add(cint1c);
- fBGTrigClasses.Add(cint1e);
-
- }
+ fCollTrigClasses.Add(new TObjString(Form("%s%s &0","+CINT1B-ABCE-NOPF-ALL", GetBXIDs(runNumber,"CINT1B-ABCE-NOPF-ALL"))));
+ fBGTrigClasses.Add (new TObjString(Form("%s%s &0","+CINT1A-ABCE-NOPF-ALL", GetBXIDs(runNumber,"CINT1A-ABCE-NOPF-ALL"))));
+ fBGTrigClasses.Add (new TObjString(Form("%s%s &0","+CINT1C-ABCE-NOPF-ALL", GetBXIDs(runNumber,"CINT1C-ABCE-NOPF-ALL"))));
+ fBGTrigClasses.Add (new TObjString(Form("%s%s &0","+CINT1-E-NOPF-ALL", GetBXIDs(runNumber,"CINT1-E-NOPF-ALL"))));
+
+ // Muon trigger have the same BXIDs of the corresponding CINT triggers
+ fCollTrigClasses.Add(new TObjString(Form("%s%s &2","+CMUS1B-ABCE-NOPF-MUON", GetBXIDs(runNumber,"CINT1B-ABCE-NOPF-ALL"))));
+ fBGTrigClasses.Add (new TObjString(Form("%s%s &2","+CMUS1A-ABCE-NOPF-MUON", GetBXIDs(runNumber,"CINT1A-ABCE-NOPF-ALL"))));
+ fBGTrigClasses.Add (new TObjString(Form("%s%s &2","+CMUS1C-ABCE-NOPF-MUON", GetBXIDs(runNumber,"CINT1C-ABCE-NOPF-ALL"))));
+ fBGTrigClasses.Add (new TObjString(Form("%s%s &2","+CMUS1-E-NOPF-MUON" , GetBXIDs(runNumber,"CINT1-E-NOPF-ALL"))));
break;
case 2:
- fCollTrigClasses.Add(new TObjString("+CSMBB-ABCE-NOPF-ALL"));
- fBGTrigClasses.Add(new TObjString("+CSMBA-ABCE-NOPF-ALL -CSMBB-ABCE-NOPF-ALL"));
- fBGTrigClasses.Add(new TObjString("+CSMBC-ABCE-NOPF-ALL -CSMBB-ABCE-NOPF-ALL"));
+ fCollTrigClasses.Add(new TObjString("+CSMBB-ABCE-NOPF-ALL &0"));
+ fBGTrigClasses.Add(new TObjString("+CSMBA-ABCE-NOPF-ALL -CSMBB-ABCE-NOPF-ALL &0"));
+ fBGTrigClasses.Add(new TObjString("+CSMBC-ABCE-NOPF-ALL -CSMBB-ABCE-NOPF-ALL &0"));
+ break;
+
+ case 3:
+ //
break;
default:
triggerAnalysis->PrintTriggerClasses();
}
- if (fHistStatistics[kStatIdxAll] && fCollTrigClasses.GetEntries() > 0)
+ if (fHistStatistics[kStatIdxAll])
{
- Printf("\nSelection statistics for first collision trigger (%s):", ((TObjString*) fCollTrigClasses.First())->String().Data());
-
- Printf("Total events with correct trigger class: %d", (Int_t) fHistStatistics[kStatIdxAll]->GetBinContent(1, 1));
- Printf("Selected collision candidates: %d", (Int_t) fHistStatistics[kStatIdxAll]->GetBinContent(fHistStatistics[kStatIdxAll]->GetXaxis()->FindBin("Accepted"), 1));
+ for (Int_t i=0; i<fCollTrigClasses.GetEntries(); i++)
+ {
+ Printf("\nSelection statistics for collision trigger %s:", ((TObjString*) fCollTrigClasses.At(i))->String().Data());
+
+ Printf("Total events with correct trigger class: %d", (Int_t) fHistStatistics[kStatIdxAll]->GetBinContent(1, i+1));
+ Printf("Selected collision candidates: %d", (Int_t) fHistStatistics[kStatIdxAll]->GetBinContent(fHistStatistics[kStatIdxAll]->GetXaxis()->FindBin("Accepted"), i+1));
+ }
}
if (fHistBunchCrossing)
for (Int_t j=1; j<=fHistBunchCrossing->GetNbinsX(); j++)
{
- Int_t count = 0;
+ Int_t countColl = 0;
+ Int_t countBG = 0;
for (Int_t i=1; i<=fHistBunchCrossing->GetNbinsY(); i++)
{
if (fHistBunchCrossing->GetBinContent(j, i) > 0)
- count++;
+ {
+ if (fCollTrigClasses.FindObject(fHistBunchCrossing->GetYaxis()->GetBinLabel(i)))
+ countColl++;
+ if (fBGTrigClasses.FindObject(fHistBunchCrossing->GetYaxis()->GetBinLabel(i)))
+ countBG++;
+ }
}
- if (count > 1)
- Printf("WARNING: Bunch crossing %d has more than one trigger class active. Check BPTX functioning for this run!", (Int_t) fHistBunchCrossing->GetXaxis()->GetBinCenter(j));
+ if (countColl > 0 && countBG > 0)
+ Printf("WARNING: Bunch crossing %d has collision and BG trigger classes active. Check BPTX functioning for this run!", (Int_t) fHistBunchCrossing->GetXaxis()->GetBinCenter(j));
}
}
virtual ~AliPhysicsSelection();
// AliAnalysisCuts interface
- virtual Bool_t IsSelected(TObject* obj) { return IsCollisionCandidate((const AliESDEvent*) obj); }
+ virtual UInt_t GetSelectionMask(const TObject* obj) { return IsCollisionCandidate((const AliESDEvent*) obj); }
virtual Bool_t IsSelected(TList*) { return kFALSE; }
+ virtual Bool_t IsSelected(TObject*) {return kFALSE;}
- Bool_t IsCollisionCandidate(const AliESDEvent* aEsd);
+ UInt_t IsCollisionCandidate(const AliESDEvent* aEsd);
Bool_t Initialize(Int_t runNumber);
void SetAnalyzeMC(Bool_t flag = kTRUE) { fMC = flag; }
protected:
- Bool_t CheckTriggerClass(const AliESDEvent* aEsd, const char* trigger) const;
+ UInt_t CheckTriggerClass(const AliESDEvent* aEsd, const char* trigger) const;
Int_t GetTriggerScheme(UInt_t runNumber) const;
const char * GetBXIDs(UInt_t runNumber, const char * trigger ) ;
const char * GetFillingScheme(UInt_t runNumber) ;
TH2F * BookHistStatistics(const char * tag) ;
-
Int_t fCurrentRun; // run number for which the object is initialized
Bool_t fMC; // flag if MC is analyzed
TList fCollTrigClasses; // trigger class identifying collision candidates
AliAnalysisTaskESDMuonFilter *esdmuonfilter = new AliAnalysisTaskESDMuonFilter("ESD Muon Filter");
mgr->AddTask(esdmuonfilter);
if(usePhysicsSelection){
- esdfilter->SelectCollisionCandidates();
- esdmuonfilter->SelectCollisionCandidates();
+ esdfilter->SelectCollisionCandidates(AliVEvent::kAny);
+ esdmuonfilter->SelectCollisionCandidates(AliVEvent::kAny);
}
// Filtering of MC particles (decays conversions etc)
fBunchCrossNumber(0),
fTriggerCluster(0),
fDiamondZ(0.),
- fDiamondSig2Z(0.)
+ fDiamondSig2Z(0.),
+ fOfflineTrigger(0)
{
// default constructor
fBunchCrossNumber(nBunchX),
fTriggerCluster(0),
fDiamondZ(0.),
- fDiamondSig2Z(0.)
+ fDiamondSig2Z(0.),
+ fOfflineTrigger(0)
{
// constructor
fOrbitNumber(nOrbit),
fPeriodNumber(nPeriod),
fBunchCrossNumber(nBunchX),
- fTriggerCluster(trigClus),
+ fTriggerCluster(trigClus),
fDiamondZ(0.),
- fDiamondSig2Z(0.)
-
+ fDiamondSig2Z(0.),
+ fOfflineTrigger(0)
{
// constructor
fBunchCrossNumber(hdr.fBunchCrossNumber),
fTriggerCluster(hdr.fTriggerCluster),
fDiamondZ(hdr.fDiamondZ),
- fDiamondSig2Z(hdr.fDiamondSig2Z)
-
+ fDiamondSig2Z(hdr.fDiamondSig2Z),
+ fOfflineTrigger(hdr.fOfflineTrigger)
{
// Copy constructor.
fTriggerCluster = hdr.fTriggerCluster;
fNMuons = hdr.fNMuons;
fNDimuons = hdr.fNDimuons;
+ fDiamondZ = hdr.fDiamondZ;
+ fDiamondSig2Z = hdr.fDiamondSig2Z;
+ fOfflineTrigger = hdr.fOfflineTrigger;
SetName(hdr.fName);
printf("ref. Multiplicity (neg) : %d\n", fRefMultNeg);
printf("number of muons : %d\n", fNMuons);
printf("number of dimuons : %d\n", fNDimuons);
+ printf("offline trigger : %u\n", fOfflineTrigger);
if (fQTheta) {
for (UInt_t i = 0; i<(UInt_t)fNQTheta; i++) {
return ((i >= 0) && (i < kNEMCALMatrix)) ? fEMCALMatrix[i] : NULL;
}
+ UInt_t GetOfflineTrigger() { return fOfflineTrigger; }
+ void SetOfflineTrigger(UInt_t trigger) { fOfflineTrigger = trigger; }
+
enum {kNPHOSMatrix = 5};
enum {kNEMCALMatrix = 12};
Double32_t fDiamondSig2Z; // Interaction diamond sigma^2 (z) in RUN
TGeoHMatrix* fPHOSMatrix[kNPHOSMatrix]; //PHOS module position and orientation matrices
TGeoHMatrix* fEMCALMatrix[kNEMCALMatrix]; //EMCAL supermodule position and orientation matrices
+ UInt_t fOfflineTrigger; // fired offline triggers for this event
- ClassDef(AliAODHeader,11);
+ ClassDef(AliAODHeader,12);
};
#endif
if (mcParticles) fMCEvent->SetParticleArray(mcParticles);
if (fTreeToMerge) fTreeToMerge->GetEntry(entry + fMergeOffset);
+ fIsSelectedResult = fEvent->GetHeader()->GetOfflineTrigger();
+
return kTRUE;
}
// Event selection
//
if (fEventCuts)
- fIsSelected = fEventCuts->IsSelected((AliESDEvent*)fEvent);
+ fIsSelectedResult = fEventCuts->GetSelectionMask((AliESDEvent*)fEvent);
//
// Friends
((AliESDEvent*)fEvent)->SetESDfriend(fFriend);
fBranchesOn(""),
fNewEvent(kTRUE),
fEventCuts(0),
- fIsSelected(kFALSE)
+ fIsSelectedResult(0)
{
// default constructor
}
fBranchesOn(""),
fNewEvent(kTRUE),
fEventCuts(0),
- fIsSelected(kFALSE)
+ fIsSelectedResult(0)
{
}
virtual Long64_t GetReadEntry() const;
virtual Bool_t NewEvent()
{Bool_t ne = fNewEvent; fNewEvent = kFALSE; return ne;}
- virtual Bool_t IsEventSelected()
- {return fIsSelected;}
+ virtual UInt_t IsEventSelected()
+ {return fIsSelectedResult;}
protected:
void SwitchOffBranches() const;
void SwitchOnBranches() const;
TString fBranchesOn; // List of branches to be switched on (separated by space)
Bool_t fNewEvent; // New event flag
AliVCuts* fEventCuts; // Cuts on the event level
- Bool_t fIsSelected; // Selection result
- ClassDef(AliInputEventHandler, 3);
+ UInt_t fIsSelectedResult; // Selection result
+ ClassDef(AliInputEventHandler, 4);
};
#endif
AliVCuts(const AliVCuts& evt);
AliVCuts& operator=(const AliVCuts& evt);
virtual Bool_t IsSelected(TObject* /* obj */) = 0;
+ virtual UInt_t GetSelectionMask(const TObject* /* obj */) { return 0; }
ClassDef(AliVCuts,1);
};
class AliVEvent : public TObject {
public:
+ enum EOfflineTriggerTypes {
+ kMB = BIT(0), // Minimum bias trigger (interaction trigger, offline SPD or V0 selection, all detectors read out)
+ kMBNoTRD = BIT(1), // Same as kMB, but TRD not read out (i.e. no TRD pretrigger)
+ kMUON = BIT(2), // Muon trigger, offline SPD or V0 selection
+ kHighMult = BIT(3), // High-multiplicity trigger (threshold defined online), offline SPD or V0 selection
+ kUserDefined = BIT(31), // Set when custom trigger classes are set in AliPhysicsSelection, offline SPD or V0 selection
+ kAny = 0xffffffff // to accept any trigger
+ };
AliVEvent() { }
virtual ~AliVEvent() { }