* @param outlierCutFMD Cut to remove events with outliers
* @param outlierCutSPD Cut to remove events with outliers
* @param etaGap Size of @f$\eta@f$ gap
- * @param useTPCForRef Use TPC tracks for reference flow
+ * @param useTracksForRef Use TPC tracks for reference flow
* @param useCent Whether to use centrality or impact parameter for MC
* @param useMCVtx Whether to use vertex info from MC header
* @param satVtx Use satellite interactions
*
* @ingroup pwglf_forward_flow
*/
-void AddTaskForwardFlowQC(Int_t maxMom = 5,
- TString fwdDet = "FMD",
- Bool_t useEtaGap = kFALSE,
- Bool_t use3cor = kFALSE,
- Bool_t mc = kFALSE,
- Double_t outlierCutFMD = 4.0,
- Double_t outlierCutSPD = 4.0,
- Double_t etaGap = 2.0,
- Bool_t useTPCForRef = kFALSE,
- Bool_t useCent = kFALSE,
- Bool_t useMCVtx = kFALSE,
- Bool_t satVtx = kFALSE,
- TString addFlow = "",
- Int_t addFType = 0,
- Int_t addFOrder = 0)
+void AddTaskForwardFlowQC(Int_t maxMom = 5,
+ TString fwdDet = "FMD",
+ Bool_t useEtaGap = kFALSE,
+ Bool_t use3cor = kFALSE,
+ Bool_t mc = kFALSE,
+ Double_t outlierCutFMD = 4.0,
+ Double_t outlierCutSPD = 4.0,
+ Double_t etaGap = 2.0,
+ UInt_t useTracksForRef = 0,
+ Bool_t useCent = kFALSE,
+ Bool_t useMCVtx = kFALSE,
+ Bool_t satVtx = kFALSE,
+ TString addFlow = "",
+ Int_t addFType = 0,
+ Int_t addFOrder = 0)
{
// --- Get analysis manager ----------------------------------------
AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
if (fwdDet.Contains("FMD")) flags |= AliForwardFlowTaskQC::kNUAcorr;
if (fwdDet.Contains("FMD")) flags |= AliForwardFlowTaskQC::kFMD;
else if (fwdDet.Contains("VZERO")) flags |= AliForwardFlowTaskQC::kVZERO;
- if (useTPCForRef) flags |= AliForwardFlowTaskQC::kTPC;
+ if (useTracksForRef == 1) flags |= AliForwardFlowTaskQC::kTPC;
+ if (useTracksForRef == 2) flags |= AliForwardFlowTaskQC::kHybrid;
const char* name = Form("ForwardFlowQC%s%s", fwdDet.Data(), AliForwardFlowTaskQC::GetQCType(flags, false));
AliForwardFlowTaskQC* task = 0;
// --- Set eta gap value -----------------------------------------
if (useEtaGap) {
- if (useTPCForRef) task->SetEtaGapValue(0.4);
+ if (useTracksForRef) task->SetEtaGapValue(0.4);
else task->SetEtaGapValue(etaGap);
}
- else if (useTPCForRef && fwdDet.Contains("FMD")) task->SetEtaGapValue(0.1);
+ else if (useTracksForRef && fwdDet.Contains("FMD")) task->SetEtaGapValue(0.0);
// --- Check which harmonics to calculate --------------------------
task->SetMaxFlowMoment(maxMom);
// --- Set sigma cuts for outliers ---------------------------------
task->SetDetectorCuts(outlierCutFMD, outlierCutSPD);
+ // --- Setup track cuts --------------------------------------------
+ if (useTracksForRef > 0) {
+ AliAnalysisFilter* trackCuts = new AliAnalysisFilter("trackFilter");
+ if (useTracksForRef == 1) { // tpc tracks
+ AliESDtrackCuts* tpcTrackCuts = AliESDtrackCuts::GetStandardTPCOnlyTrackCuts();
+ tpcTrackCuts->SetPtRange(0.2, 5.0);
+ tpcTrackCuts->SetEtaRange(-0.8, 0.8);
+ tpcTrackCuts->SetMinNClustersTPC(70);
+ trackCuts->AddCuts(tpcTrackCuts);
+ task->SetTrackCuts(trackCuts);
+ } else if (useTracksForRef == 2) { // hybrid tracks
+ // Basic cuts for global tracks - working for 10h!
+ AliESDtrackCuts* baseCuts = new AliESDtrackCuts("base");
+ TFormula *f1NClustersTPCLinearPtDep = new TFormula("f1NClustersTPCLinearPtDep","70.+30./20.*x");
+ baseCuts->SetMinNClustersTPCPtDep(f1NClustersTPCLinearPtDep,20.);
+ baseCuts->SetMinNClustersTPC(70);
+ baseCuts->SetMaxChi2PerClusterTPC(4);
+ baseCuts->SetRequireTPCStandAlone(kTRUE); //cut on NClustersTPC and chi2TPC Iter1
+ baseCuts->SetAcceptKinkDaughters(kFALSE);
+ baseCuts->SetRequireTPCRefit(kTRUE);
+ baseCuts->SetMaxFractionSharedTPCClusters(0.4);
+ // ITS
+ baseCuts->SetRequireITSRefit(kTRUE);
+ //accept secondaries
+ baseCuts->SetMaxDCAToVertexXY(2.4);
+ baseCuts->SetMaxDCAToVertexZ(3.2);
+ baseCuts->SetDCAToVertex2D(kTRUE);
+ //reject fakes
+ baseCuts->SetMaxChi2PerClusterITS(36);
+ baseCuts->SetMaxChi2TPCConstrainedGlobal(36);
+ baseCuts->SetRequireSigmaToVertex(kFALSE);
+// baseCuts->SetEtaRange(-0.9,0.9);
+// baseCuts->SetPtRange(0.15, 1E+15.);
+ baseCuts->SetEtaRange(-0.8, 0.8);
+ baseCuts->SetPtRange(0.2, 5.);
+
+ // Good global tracks
+ AliESDtrackCuts* globalCuts = baseCuts->Clone("global");
+ globalCuts->SetClusterRequirementITS(AliESDtrackCuts::kSPD, AliESDtrackCuts::kAny);
+
+ // tracks with vertex constraint
+ AliESDtrackCuts* constrainedCuts = baseCuts->Clone("vertexConstrained");
+ constrainedCuts->SetRequireITSRefit(kFALSE);
+
+ // Add
+ trackCuts->AddCuts(globalCuts);
+ trackCuts->AddCuts(constrainedCuts);
+ task->SetTrackCuts(trackCuts);
+ }
+ }
+
// --- Create containers for output --------------------------------
const char* sumName = Form("FlowQCSums%s%s", fwdDet.Data(), AliForwardFlowTaskQC::GetQCType(flags, false));
const char* resName = Form("FlowQCResults%s%s", fwdDet.Data(), AliForwardFlowTaskQC::GetQCType(flags, false));
// fExtraDead(0),
fXtraDead(0),
fInvalidIsEmpty(false),
- fMergingDisabled(false)
+ fMergingDisabled(false),
+ fIgnoreESDForAngleCorrection(false)
{
//
// Default Constructor - do not use
// fExtraDead(51200),
fXtraDead(AliFMDStripIndex::Pack(3,'O',19,511)+1),
fInvalidIsEmpty(false),
- fMergingDisabled(false)
+ fMergingDisabled(false),
+ fIgnoreESDForAngleCorrection(false)
{
//
// Constructor
// just return read value
if (mult == AliESDFMD::kInvalidMult ||
mult == 0 ||
- (fCorrectAngles && input.IsAngleCorrected()) ||
- (!fCorrectAngles && !input.IsAngleCorrected()))
+ (fCorrectAngles && (fIgnoreESDForAngleCorrection || input.IsAngleCorrected())) ||
+ (!fCorrectAngles && !fIgnoreESDForAngleCorrection && !input.IsAngleCorrected()))
return mult;
// If we want angle corrected data, correct it,
* @param flag If true, count invalids as empty
*/
void SetInvalidIsEmpty(Bool_t flag) { fInvalidIsEmpty = flag; }
+ /**
+ * Set whether to ignore the ESD info when angle correcting, this
+ * is to counter a known issue where the info in the ESD is incorrect
+ *
+ * @param use ignore the ESD info
+ */
+ void SetIgnoreESDWhenAngleCorrecting(Bool_t use) { fIgnoreESDForAngleCorrection = use; }
/* @} */
/**
Bool_t fRecalculateEta; // Whether to recalc eta and angle cor (disp vtx)
TBits fXtraDead;
Bool_t fInvalidIsEmpty; // Consider kInvalidMult as zero
- Bool_t fMergingDisabled; // If true, do not merge
- ClassDef(AliFMDSharingFilter,9); //
+ Bool_t fMergingDisabled; // If true, do not merge
+ Bool_t fIgnoreESDForAngleCorrection; // Ignore ESD information when angle correcting
+ ClassDef(AliFMDSharingFilter,10); //
};
#endif
#include "AliCentrality.h"
#include "AliESDEvent.h"
#include "AliVTrack.h"
-#include "AliESDtrackCuts.h"
+#include "AliESDtrack.h"
#include "AliAODTrack.h"
+#include "AliAnalysisFilter.h"
ClassImp(AliForwardFlowTaskQC)
#if 0
fSumList(0), // Event sum list
fOutputList(0), // Result output list
fAOD(0), // AOD input event
- fESDTrackCuts(0), // ESD track cuts
+ fTrackCuts(0), // ESD track cuts
fMaxMoment(0), // Max flow moment
fVtx(1111), // Z vertex coordinate
fCent(-1), // Centrality
fSumList(0), // Event sum list
fOutputList(0), // Result output list
fAOD(0), // AOD input event
- fESDTrackCuts(0), // ESD track cuts
+ fTrackCuts(0), // ESD track cuts
fMaxMoment(4), // Max flow moment
fVtx(1111), // Z vertex coordinate
fCent(-1), // Centrality
fSumList(o.fSumList), // Event sum list
fOutputList(o.fOutputList), // Result output list
fAOD(o.fAOD), // AOD input event
- fESDTrackCuts(o.fESDTrackCuts), // ESD track cuts
+ fTrackCuts(o.fTrackCuts), // ESD track cuts
fMaxMoment(o.fMaxMoment), // Flow moments
fVtx(o.fVtx), // Z vertex coordinate
fCent(o.fCent), // Centrality
fSumList = o.fSumList;
fOutputList = o.fOutputList;
fAOD = o.fAOD;
- fESDTrackCuts = o.fESDTrackCuts;
+ fTrackCuts = o.fTrackCuts;
fMaxMoment = o.fMaxMoment;
fVtx = o.fVtx;
fCent = o.fCent;
//
InitVertexBins();
InitHists();
- if (fFlowFlags & kTPC) {
- fESDTrackCuts = AliESDtrackCuts::GetStandardTPCOnlyTrackCuts();
- fESDTrackCuts->SetPtRange(0.2, 5.0);
- fESDTrackCuts->SetEtaRange(-0.8, 0.8);
- fESDTrackCuts->SetMinNClustersTPC(70);
- }
+ if ((fFlowFlags & kTracks) && !fTrackCuts) AliFatal("No track cuts set!");
PrintFlowSetup();
PostData(1, fSumList);
}
else if ((fFlowFlags & kVZERO)) {
fBinsForward.Add(new VertexBin(vL, vH, fMaxMoment, "VZERO", fFlowFlags, 0, fEtaGap));
- if ((fFlowFlags & kEtaGap) && !(fFlowFlags & kTPC))
+ if ((fFlowFlags & kEtaGap) && !(fFlowFlags & kTracks))
fBinsCentral.Add(new VertexBin(vL, vH, fMaxMoment, "SPD-VZERO", fFlowFlags|kNUAcorr|kSPD, fSPDCut, fEtaGap));
}
}
while ((bin = static_cast<VertexBin*>(list.At(vtx+(nVtxBins*i))))) {
// If no tracks do things normally
- if (!(fFlowFlags & kTPC) && !bin->FillHists(h, fCent, kFillBoth|flags|kReset)) return;
+ if (!(fFlowFlags & kTracks) && !bin->FillHists(h, fCent, kFillBoth|flags|kReset)) return;
// if tracks things are more complicated
- else if ((fFlowFlags & kTPC)) {
- TObjArray* trList = GetTracks();
- if (!trList) return;
- Bool_t useEvent = bin->FillTracks(trList, kFillRef|kReset|flags);
- // If esd input trList is a new object owned by this task and should be cleaned up
- if (AliForwardUtil::CheckForAOD() == 2) delete trList;
- if (!useEvent) return;
+ else if ((fFlowFlags & kTracks)) {
+ if (!FillTracks(bin, kFillRef|kReset|flags)) return;
if (!bin->FillHists(h, fCent, kFillDiff|kReset|flags)) return;
}
bin->CumulantsAccumulate(fCent);
Int_t nVtxBins = fVtxAxis->GetNbins();
while ((bin = static_cast<VertexBin*>(list.At(vtx+(nVtxBins*i))))) {
- if (!(fFlowFlags & kTPC) && !bin->FillHists(href, fCent, kFillRef|flags|kReset)) return;
- else if ((fFlowFlags & kTPC)) {
- TObjArray* trList = GetTracks();
- if (!trList) return;
- Bool_t useEvent = bin->FillTracks(trList, kFillRef|kReset|flags);
- // If esd input trList is a new object owned by this task and should be cleaned up
- if (AliForwardUtil::CheckForAOD() == 2) delete trList;
- if (!useEvent) return;
+ if (!(fFlowFlags & kTracks) && !bin->FillHists(href, fCent, kFillRef|flags|kReset)) return;
+ else if ((fFlowFlags & kTracks)) {
+ if (!FillTracks(bin, kFillRef|kReset|flags)) return;
}
- bin->FillHists(hdiff, fCent, kFillDiff|kReset);
+ if (!bin->FillHists(hdiff, fCent, kFillDiff|kReset)) return;
bin->CumulantsAccumulate(fCent);
i++;
}
return fHistdNdedp3Cor;
}
//_____________________________________________________________________
-TObjArray* AliForwardFlowTaskQC::GetTracks() const
+Bool_t AliForwardFlowTaskQC::FillTracks(VertexBin* bin, UShort_t mode) const
{
//
// Get TPC tracks to use for reference flow.
// Return: TObjArray with tracks
//
TObjArray* trList = 0;
- // Get input type
- UShort_t input = AliForwardUtil::CheckForAOD();
- switch (input) {
- // If AOD input, simply get the track array from the event
- case 1: trList = static_cast<TObjArray*>(fAOD->GetTracks());
- break;
- case 2: {
- // If ESD input get event, apply track cuts
- AliESDEvent* esd = dynamic_cast<AliESDEvent*>(InputEvent());
- if (!esd) return 0;
- // Warning! trList is now a new array, we need to delete it after use
- // this is not a very good implementation!
- trList = fESDTrackCuts->GetAcceptedTracks(esd, kTRUE);
- break;
- }
- default: AliFatal("Neither ESD or AOD input. This should never happen");
- break;
- }
- return trList;
+ AliESDEvent* esdEv = 0;
+ if (AliForwardUtil::CheckForAOD() == 1) // AOD tracks
+ trList = static_cast<TObjArray*>(fAOD->GetTracks());
+ else
+ esdEv = dynamic_cast<AliESDEvent*>(InputEvent());
+
+ Bool_t useEvent = bin->FillTracks(trList, esdEv, fTrackCuts, mode);
+ return useEvent;
}
//_____________________________________________________________________
void AliForwardFlowTaskQC::Terminate(Option_t */*option*/)
fOutputList->SetName("Results");
fOutputList->SetOwner();
- if ((fFlowFlags & kEtaGap) || (fFlowFlags & kTPC)) {
+ if ((fFlowFlags & kEtaGap) || (fFlowFlags & kTracks)) {
TParameter<Double_t>* etaGap = new TParameter<Double_t>("EtaGap", fEtaGap);
fOutputList->Add(etaGap);
}
Int_t nRefBins = nEtaBins; // needs to be something as default
if ((fFlags & kStdQC)) {
- if ((fFlags & kSymEta) && !((fFlags & kTPC) && (fFlags & kSPD))) nRefBins = 1;
+ if ((fFlags & kSymEta) && !((fFlags & kTracks) && (fFlags & kSPD))) nRefBins = 1;
else nRefBins = 2;
} else if ((fFlags & kEtaGap )) {
nRefBins = 2;
return useEvent;
}
//_____________________________________________________________________
-Bool_t AliForwardFlowTaskQC::VertexBin::FillTracks(TObjArray* trList, UShort_t mode)
+Bool_t AliForwardFlowTaskQC::VertexBin::FillTracks(TObjArray* trList, AliESDEvent* esd,
+ AliAnalysisFilter* trFilter, UShort_t mode)
{
//
// Fill reference and differential eta-histograms
// mode: filling mode: kFillRef/kFillDiff/kFillBoth
//
if (!fCumuRef) AliFatal("You have not called AddOutput() - Terminating!");
+ if (!trList && !esd) {
+ AliError("FillTracks: No AOD track list or ESD event - something might be wrong!");
+ return kFALSE;
+ }
// Fist we reset histograms
if ((mode & kReset)) {
if ((mode & kFillDiff)) fCumuDiff->Reset();
}
- UShort_t input = AliForwardUtil::CheckForAOD();
// Then we loop over the input and calculate sum cos(k*n*phi)
// and fill it in the reference and differential histograms
- Int_t nTr = trList->GetEntries();
+ Int_t nTr = 0;
+ if (trList) nTr = trList->GetEntries();
+ if (esd) nTr = esd->GetNumberOfTracks();
if (nTr == 0) return kFALSE;
AliVTrack* tr = 0;
- AliAODTrack* aodTr = 0;
// Cuts for AOD tracks (have already been applied to ESD tracks) - except dEdx
- const Double_t pTMin = 0.2, pTMax = 5., etaMin = -0.8, etaMax = 0.8, minNCl = 70, tpcdEdx = 10.;
+// const tpcdEdx = 10;
for (Int_t i = 0; i < nTr; i++) { // track loop
- tr = (AliVTrack*)trList->At(i);
+ tr = (trList ? (AliVTrack*)trList->At(i) : (AliVTrack*)esd->GetTrack(i));
if (!tr) continue;
- if (input == 1) { // If AOD input
- // A dynamic cast would be more safe here, but this is faster...
- aodTr = (AliAODTrack*)tr;
+ if (esd) {
+ AliESDtrack* esdTr = (AliESDtrack*)tr;
+ if (!trFilter->IsSelected(esdTr)) continue;
+ }
+ else if (trList) { // If AOD input
+ Double_t pTMin = 0, pTMax = 0, etaMin = 0, etaMax = 0, minNCl = 0, bit = 0;
+ if ((fFlags & kTPC) == kTPC) pTMin = 0.2, pTMax = 5., etaMin = -0.8, etaMax = 0.8, minNCl = 70, bit = 128;
+ if ((fFlags & kHybrid) == kHybrid) pTMin = 0.2, pTMax = 5., etaMin = -0.8, etaMax = 0.8, minNCl = 70, bit = 272;
+
+ AliAODTrack* aodTr = (AliAODTrack*)tr;
if (aodTr->GetID() > -1) continue;
- if (!aodTr->TestFilterBit(128) || !aodTr->Pt() > pTMax || aodTr->Pt() < pTMin ||
+ if (!aodTr->TestFilterBit(bit) || !aodTr->Pt() > pTMax || aodTr->Pt() < pTMin ||
aodTr->Eta() > etaMax || aodTr->Eta() < etaMin || aodTr->GetTPCNcls() < minNCl) continue;
}
- if (tr->GetTPCsignal() < tpcdEdx) continue;
+
+// if (tr->GetTPCsignal() < tpcdEdx) continue;
// Track accepted
Double_t eta = tr->Eta();
if (((fFlags & kSPD) || (fFlags & kEtaGap)) && TMath::Abs(eta) < fEtaGap) continue;
for (Int_t etaBin = 1; etaBin <= fCumuRef->GetNbinsX(); etaBin++) {
Double_t eta = fCumuRef->GetXaxis()->GetBinCenter(etaBin);
if (fCumuRef->GetBinContent(etaBin, 0) == 0) continue;
- if ((fFlags & kTPC) && (fFlags && kSPD) && !(fFlags & kEtaGap)) eta = -eta;
+ if ((fFlags & kTracks) && (fFlags && kSPD) && !(fFlags & kEtaGap)) eta = -eta;
for (Int_t qBin = 0; qBin <= fCumuRef->GetNbinsY(); qBin++) {
fCumuNUARef->Fill(eta, cent, Double_t(qBin), fCumuRef->GetBinContent(etaBin, qBin));
}
for (Int_t etaBin = 1; etaBin <= fCumuDiff->GetNbinsX(); etaBin++) {
Double_t eta = fCumuDiff->GetXaxis()->GetBinCenter(etaBin);
Double_t refEta = eta;
- if ((fFlags & kTPC) && (fFlags && kSPD) && !(fFlags & kEtaGap)) refEta = -eta;
+ if ((fFlags & kTracks) && (fFlags && kSPD) && !(fFlags & kEtaGap)) refEta = -eta;
Int_t refEtaBinA = fCumuRef->GetXaxis()->FindBin(refEta);
if ((fFlags & kEtaGap)) refEta = -eta;
Int_t refEtaBinB = fCumuRef->GetXaxis()->FindBin(refEta);
// Differential flow calculations for each eta bin is done:
// 2-particle differential flow
- if ((fFlags & kStdQC) && !(fFlags & kTPC)) {
+ if ((fFlags & kStdQC) && !(fFlags & kTracks)) {
mq = mp;
qnRe = pnRe;
qnIm = pnIm;
TString type = "Standard QC{2} and QC{4} calculations.";
if ((fFlowFlags & kEtaGap)) type = "QC{2} with a rapidity gap.";
if ((fFlowFlags & k3Cor)) type = "QC{2} with 3 correlators.";
- if ((fFlowFlags & kTPC)) type.ReplaceAll(".", " with TPC tracks for reference.");
+ if ((fFlowFlags & kTPC) == kTPC) type.ReplaceAll(".", " with TPC tracks for reference.");
+ if ((fFlowFlags & kHybrid) == kHybrid) type.ReplaceAll(".", " with hybrid tracks for reference.");
Printf("QC calculation type :\t%s", type.Data());
Printf("Symmetrize ref. flow wrt. eta = 0 :\t%s", ((fFlowFlags & kSymEta) ? "true" : "false"));
Printf("Apply NUA correction terms :\t%s", ((fFlowFlags & kNUAcorr) ? "true" : "false"));
Printf("Satellite vertex flag :\t%s", ((fFlowFlags & kSatVtx) ? "true" : "false"));
Printf("FMD sigma cut: :\t%f", fFMDCut);
Printf("SPD sigma cut: :\t%f", fSPDCut);
- if ((fFlowFlags & kEtaGap) || (fFlowFlags & kTPC))
+ if ((fFlowFlags & kEtaGap) || (fFlowFlags & kTracks))
Printf("Eta gap: :\t%f", fEtaGap);
Printf("=======================================================");
}
else if ((flags & k3Cor)) type = "3Cor";
else type = "UNKNOWN";
if (prependUS) type.Prepend("_");
- if ((flags & kTPC)) type.Append("TPCTr");
+ if ((flags & kTPC) == kTPC) type.Append("TPCTr");
+ if ((flags & kHybrid) == kHybrid) type.Append("HybTr");
+
return type.Data();
}
//_____________________________________________________________________
class TH2D;
class TH3D;
class TAxis;
-class AliESDtrackCuts;
+class AliAnalysisFilter;
+class AliESDEvent;
/**
* @defgroup pwglf_forward_tasks_flow Flow tasks
*
* @param eg gap value
*/
void SetEtaGapValue(Double_t eg) { fEtaGap = eg; }
+ void SetTrackCuts(AliAnalysisFilter* trCuts) { fTrackCuts = trCuts; }
/**
* Enum for flow flags
*/
enum EFlowFlags {
- kStdQC = 0x001, // Standard QC{2} and QC{4} calculations
- kEtaGap = 0x002, // QC{2} w/ an eta-gap
- k3Cor = 0x004, // 3 correlator method for QC{2} w/ an eta-gap
- kSymEta = 0x008, // Symmetrize ref flow in std. QC{2} and QC{4} around eta = 0
- kSatVtx = 0x010, // Do satellite vertex input (currently not implemented)
- kNUAcorr = 0x020, // Apply full NUA correction
- kFMD = 0x040, // Use FMD for forward flow
- kVZERO = 0x080, // Use VZERO for forward flow
- kTPC = 0x100, // Use TPC tracks for reference flow
- kSPD = 0x200, // SPD object flag
- kMC = 0x400 // MC object flag
+ kStdQC = 0x0001, // Standard QC{2} and QC{4} calculations
+ kEtaGap = 0x0002, // QC{2} w/ an eta-gap
+ k3Cor = 0x0004, // 3 correlator method for QC{2} w/ an eta-gap
+ kSymEta = 0x0008, // Symmetrize ref flow in std. QC{2} and QC{4} around eta = 0
+ kSatVtx = 0x0010, // Do satellite vertex input (currently not implemented)
+ kNUAcorr = 0x0020, // Apply full NUA correction
+ kFMD = 0x0040, // Use FMD for forward flow
+ kVZERO = 0x0080, // Use VZERO for forward flow
+ kSPD = 0x0100, // SPD object flag
+ kMC = 0x0200, // MC object flag
+ kTracks = 0x1000, // Use tracks for reference flow
+ kTPC = 0x3000, // Use TPC tracks
+ kHybrid = 0x5000 // Use hybrid tracks
};
/**
* struct to handle cumulant calculations and control histograms
*
* @return false if bad event (det. hotspot)
*/
- Bool_t FillTracks(TObjArray* trList, UShort_t mode);
+ Bool_t FillTracks(TObjArray* trList, AliESDEvent* esd, AliAnalysisFilter* trFilter, UShort_t mode);
/**
* Do cumulants calculations for current event with
* centrality cent
*/
TH2D& CombineHists(TH2D& hcent, TH2D& hfwd);
/**
- * Get TPC tracks from ESD or AOD input event
+ * Get Fill tracks from ESD or AOD input event
*
- * @return array of tracks
+ * @return true on success
*/
- TObjArray* GetTracks() const;
+ Bool_t FillTracks(VertexBin* bin, UShort_t mode) const;
/**
* Loops over VertexBin list and calls terminate on each
*
*/
void PrintFlowSetup() const;
- TAxis* fVtxAxis; // Axis to control vertex binning
- TAxis* fCentAxis; // Axis to control centrality/multiplicity binning
- Double_t fFMDCut; // FMD sigma cut for outlier events
- Double_t fSPDCut; // SPD sigma cut for outlier events
- UShort_t fFlowFlags; // Flow flags, e.g., eta-gap, sat. vtx.
- Double_t fEtaGap; // Eta gap value
- TList fBinsForward; // List with forward VertexBin objects
- TList fBinsCentral; // List with central VertexBin objects
- TList* fSumList; // Sum list
- TList* fOutputList; // Output list
- AliAODEvent* fAOD; // AOD event
- AliESDtrackCuts* fESDTrackCuts; // ESD track cuts
- Int_t fMaxMoment; // Calculate v_{n} flag
- Float_t fVtx; // Z vertex bin
- Double_t fCent; // Centrality
- TH2D fHistdNdedpV0; // VZERO d^2N/detadphi histogram
- TH2D fHistdNdedp3Cor;// VZERO d^2N/detadphi histogram
- TH2D* fHistFMDSPDCorr;// Diagnostics hist for multiplicity correlations between FMD and SPD
- TH1D* fHistCent; // Diagnostics hist for centrality
- TH1D* fHistVertexSel; // Diagnostics hist for selected vertices
- TH1I* fHistEventSel; // Diagnostics hist for event selection
+ TAxis* fVtxAxis; // Axis to control vertex binning
+ TAxis* fCentAxis; // Axis to control centrality/multiplicity binning
+ Double_t fFMDCut; // FMD sigma cut for outlier events
+ Double_t fSPDCut; // SPD sigma cut for outlier events
+ UShort_t fFlowFlags; // Flow flags, e.g., eta-gap, sat. vtx.
+ Double_t fEtaGap; // Eta gap value
+ TList fBinsForward; // List with forward VertexBin objects
+ TList fBinsCentral; // List with central VertexBin objects
+ TList* fSumList; // Sum list
+ TList* fOutputList; // Output list
+ AliAODEvent* fAOD; // AOD event
+ AliAnalysisFilter* fTrackCuts; // ESD track cuts
+ Int_t fMaxMoment; // Calculate v_{n} flag
+ Float_t fVtx; // Z vertex bin
+ Double_t fCent; // Centrality
+ TH2D fHistdNdedpV0; // VZERO d^2N/detadphi histogram
+ TH2D fHistdNdedp3Cor;// 3 correlator d^2N/detadphi histogram
+ TH2D* fHistFMDSPDCorr;// Diagnostics hist for multiplicity correlations between FMD and SPD
+ TH1D* fHistCent; // Diagnostics hist for centrality
+ TH1D* fHistVertexSel; // Diagnostics hist for selected vertices
+ TH1I* fHistEventSel; // Diagnostics hist for event selection
- ClassDef(AliForwardFlowTaskQC, 4); // Analysis task for flow analysis
+ ClassDef(AliForwardFlowTaskQC, 5); // Analysis task for flow analysis
};
#endif
// task->GetSharingFilter().SetDisableMerging(true);
// Enable use of angle corrected signals in the algorithm
task->GetSharingFilter().SetUseAngleCorrectedSignals(true);
+ // Ignore the ESD information when angle correcting.
+ //
+ // *IMPORTANT*
+ //
+ // This is to counter a known issue with AliESDFMD with ClassDef
+ // version < 4, where the angle correction flag is incorrectly set.
+ // A fix is coming to AliESDFMD to handle it directly in the class.
+ // Only set the flag below to true if you know it to be necessary for
+ // your data set.
+ task->GetSharingFilter().SetIgnoreESDWhenAngleCorrecting(false);
// Disable use of angle corrected signals in the algorithm
task->GetSharingFilter().SetZeroSharedHitsBelowThreshold(false);
// Whether to use simple merging algorithm
fOptions.Add("afterburner", "[eta,phi,b,pid]", "What to afterburn", "");
fOptions.Add("ab-type", "1|2|3|4", "Type of afterburner", "");
fOptions.Add("ab-order", "2|3|4|5|6", "Order of afterburner", "");
- fOptions.Add("fwd-dets", "[fmd,vzero]", "Forward detectors", "");
+ fOptions.Add("fwd-dets", "[fmd,vzero]", "Forward detectors", "fmd+vzero");
fOptions.Set("type", "AOD");
fOptions.Show(std::cout);
// QC specific options
fOptions.Add("QC", "Add QC tasks (requires AODs with FMD and SPD objects)");
- fOptions.Add("qc-type", "[std,eta-gap,3cor,all]", "Which types of QC's to do", "both");
+ fOptions.Add("qc-type", "[std,eta-gap,3cor,all]", "Which types of QC's to do", "all");
fOptions.Add("eg-value", "EGVALUE", "Set value in |eta| of the eta gap", "2.0");
- fOptions.Add("tpc-tracks", "Whether to use TPC tracks for reference flow");
+ fOptions.Add("tracks", "[tpc,hybrid,only]", "Whether or only to use tracks for reference flow", "tpc+hybrid");
fOptions.Add("sat-vtx", "Whether to use satellite interactions");
fOptions.Add("outlier-fmd", "NSIGMA", "Outlier cut for FMD", "4.0");
fOptions.Add("outlier-spd", "NSIGMA", "Outlier cut for SPD", "4.0");
TString fwdDets = fOptions.Get("fwd-dets");
TString types = fOptions.Get("qc-type");
Double_t egValue = fOptions.AsDouble("eg-value");
- Bool_t tpcTr = fOptions.AsBool("tpc-tracks");
Bool_t useCent = fOptions.AsBool("use-cent");
+ TString tracks = fOptions.Get("tracks");
Bool_t useMCVtx = fOptions.AsBool("mc-vtx");
TString addFlow = fOptions.Get("afterburner");
Int_t abType = fOptions.AsInt("ab-type");
fwdDets.ToUpper();
Bool_t doFMD = fwdDets.Contains("FMD");
Bool_t doVZERO = fwdDets.Contains("VZERO");
+ tracks.ToLower();
+ Bool_t onlyTr = tracks.Contains("only");
+ Bool_t tpcTr = tracks.Contains("tpc");
+ Bool_t hybridTr = tracks.Contains("hybrid");
TString args(TString::Format("AddTaskForwardFlowQC.C(%d,\"%%s\",%%d,%%d,%d,%f,%f,%f,%%d,%d,%d,%d,\"%s\",%d,%d)",
moment,
// --- Add the task ----------------------------------------------
if (doFMD) {
if (types.Contains("std") || types.Contains("all")) {
- gROOT->Macro(Form(args.Data(), "FMD", false, false, false));
+ if (!onlyTr)
+ gROOT->Macro(Form(args.Data(), "FMD", false, false, 0));
if (tpcTr)
- gROOT->Macro(Form(args.Data(), "FMD", false, false, true));
+ gROOT->Macro(Form(args.Data(), "FMD", false, false, 1));
+ if (hybridTr)
+ gROOT->Macro(Form(args.Data(), "FMD", false, false, 2));
}
if (types.Contains("eta-gap") || types.Contains("all")) {
- gROOT->Macro(Form(args.Data(), "FMD", true, false, false));
+ if (!onlyTr)
+ gROOT->Macro(Form(args.Data(), "FMD", true, false, 0));
if (tpcTr)
- gROOT->Macro(Form(args.Data(), "FMD", true, false, true));
+ gROOT->Macro(Form(args.Data(), "FMD", true, false, 1));
+ if (hybridTr)
+ gROOT->Macro(Form(args.Data(), "FMD", true, false, 2));
+ }
+ if (types.Contains("3cor") || types.Contains("all")) {
+ if (!onlyTr)
+ gROOT->Macro(Form(args.Data(), "FMD", false, true, 0));
}
- if (types.Contains("3cor") || types.Contains("all"))
- gROOT->Macro(Form(args.Data(), "FMD", false, true, false));
}
if (doVZERO) {
if (types.Contains("std") || types.Contains("all")) {
- gROOT->Macro(Form(args.Data(), "VZERO", false, false, false));
+ if (!onlyTr)
+ gROOT->Macro(Form(args.Data(), "VZERO", false, false, 0));
if (tpcTr)
- gROOT->Macro(Form(args.Data(), "VZERO", false, false, true));
+ gROOT->Macro(Form(args.Data(), "VZERO", false, false, 1));
+ if (hybridTr)
+ gROOT->Macro(Form(args.Data(), "VZERO", false, false, 2));
}
if (types.Contains("eta-gap") || types.Contains("all")) {
- gROOT->Macro(Form(args.Data(), "VZERO", true, false, false));
+ if (!onlyTr)
+ gROOT->Macro(Form(args.Data(), "VZERO", true, false, 0));
if (tpcTr)
- gROOT->Macro(Form(args.Data(), "VZERO", true, false, true));
+ gROOT->Macro(Form(args.Data(), "VZERO", true, false, 1));
+ if (hybridTr)
+ gROOT->Macro(Form(args.Data(), "VZERO", true, false, 2));
+ }
+ if (types.Contains("3cor") || types.Contains("all")) {
+ if (!onlyTr)
+ gROOT->Macro(Form(args.Data(), "VZERO", false, true, 0));
}
- if (types.Contains("3cor") || types.Contains("all"))
- gROOT->Macro(Form(args.Data(), "VZERO", false, true, false));
}
}
//__________________________________________________________________