--- /dev/null
+/**
+ * @file AddTaskForwardQA.C
+ * @author Christian Holm Christensen <cholm@dalsgaard.hehi.nbi.dk>
+ * @date Wed Mar 23 12:14:03 2011
+ *
+ * @brief
+ *
+ *
+ * @ingroup pwg2_forward_scripts_tasks
+ */
+/**
+ * @defgroup pwg2_forward_eloss Energy Loss Fits
+ * @ingroup pwg2_forward_topical
+ */
+
+/**
+ * This is the macro to include the FMD energy fitter in a train.
+ *
+ * @ingroup pwg2_forward_eloss
+ */
+AliAnalysisTask*
+AddTaskForwardQA(Bool_t mc, Bool_t useCent)
+{
+ gSystem->Load("libPWG2forward2");
+
+ AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
+ if (!mgr) {
+ Error("AddTaskForwardQA", "No analysis manager to connect to.");
+ return NULL;
+ }
+
+ // --- Make the task and add it to the manager ---------------------
+ AliForwardQATask* task = new AliForwardQATask("forwardQA");
+ // task->SetBLow(blow);
+ // task->SetBLow(bhigh);
+ mgr->AddTask(task);
+
+ Double_t nXi = mc ? 2 : 2; //HHD test
+ Bool_t includeSigma = false; //true;
+
+ AliFMDMultCuts cDensity;
+ //c2.SetNXi(mc ? 1 : 1);
+ // c2.SetIncludeSigma(false);
+ //c2.SetMPVFraction(0.5);
+ //Double_t factor = 1.2;
+ cDensity.SetMultCuts(0.3, 0.3, 0.3, 0.3, 0.3);
+
+ // --- Set parameters on the algorithms ----------------------------
+ // Set the number of SPD tracklets for which we consider the event a
+ // low flux event
+ task->GetEventInspector().SetLowFluxCut(1000);
+ // Set the maximum error on v_z [cm]
+ task->GetEventInspector().SetMaxVzErr(0.2);
+
+ // --- Set parameters on energy loss fitter ------------------------
+ // Set the eta axis to use - note, this overrides whatever is used
+ // by the rest of the algorithms - but only for the energy fitter
+ // algorithm.
+ task->GetEnergyFitter().SetEtaAxis(200, -4, 6);
+ // Set maximum energy loss to consider
+ task->GetEnergyFitter().SetMaxE(15);
+ // Set number of energy loss bins
+ task->GetEnergyFitter().SetNEbins(500);
+ // Set whether to use increasing bin sizes
+ task->GetEnergyFitter().SetUseIncreasingBins(true);
+ // Set whether to do fit the energy distributions
+ task->GetEnergyFitter().SetDoFits(kTRUE);
+ // Set whether to make the correction object
+ task->GetEnergyFitter().SetDoMakeObject(kFALSE);
+ // Set the low cut used for energy
+ task->GetEnergyFitter().SetLowCut(0.4);
+ // Set the number of bins to subtract from maximum of distributions
+ // to get the lower bound of the fit range
+ task->GetEnergyFitter().SetFitRangeBinWidth(4);
+ // Set the minimum number of entries in the distribution before
+ // trying to fit to the data
+ task->GetEnergyFitter().SetMinEntries(1000);
+
+ // --- Sharing filter ----------------------------------------------
+ // Enable use of angle corrected signals in the algorithm
+ task->GetSharingFilter().SetUseAngleCorrectedSignals(true);
+ // Disable use of angle corrected signals in the algorithm
+ task->GetSharingFilter().SetZeroSharedHitsBelowThreshold(false);
+ // Enable use of angle corrected signals in the algorithm
+ task->GetSharingFilter().GetHCuts().SetMultCuts(-1);
+ // Set the number of xi's (width of landau peak) to stop at
+ task->GetSharingFilter().GetHCuts().SetNXi(nXi);
+ // Set whether or not to include sigma in cut
+ task->GetSharingFilter().GetHCuts().SetIncludeSigma(includeSigma);
+ // Enable use of angle corrected signals in the algorithm
+ task->GetSharingFilter().SetLCuts(cDensity);
+
+ // --- Density calculator ------------------------------------------
+ // Set the maximum number of particle to try to reconstruct
+ task->GetDensityCalculator().SetMaxParticles(10);
+ // Wet whether to use poisson statistics to estimate N_ch
+ task->GetDensityCalculator().SetUsePoisson(true);
+ // Set whether or not to include sigma in cut
+ task->GetDensityCalculator().SetCuts(cDensity);
+ // Set whether or not to use the phi acceptance
+ // AliFMDDensityCalculator::kPhiNoCorrect
+ // AliFMDDensityCalculator::kPhiCorrectNch
+ // AliFMDDensityCalculator::kPhiCorrectELoss
+ task->GetDensityCalculator()
+ .SetUsePhiAcceptance(AliFMDDensityCalculator::kPhiCorrectNch);
+ // --- Set limits on fits the energy -------------------------------
+ // Maximum relative error on parameters
+ AliFMDCorrELossFit::ELossFit::fgMaxRelError = .12;
+ // Least weight to use
+ AliFMDCorrELossFit::ELossFit::fgLeastWeight = 1e-5;
+ // Maximum value of reduced chi^2
+ AliFMDCorrELossFit::ELossFit::fgMaxChi2nu = 20;
+
+ // --- Make the output container and connect it --------------------
+ // TString outputfile = ;
+ // outputfile += ":PWG2forwardDnDeta";
+ // Form(":%s",pars->GetDndetaAnalysisName());
+ AliAnalysisDataContainer* histOut =
+ mgr->CreateContainer("Forward", TList::Class(),
+ AliAnalysisManager::kOutputContainer,
+ AliAnalysisManager::GetCommonFileName());
+ AliAnalysisDataContainer *output =
+ mgr->CreateContainer("ForwardResults", TList::Class(),
+ AliAnalysisManager::kParamContainer,
+ AliAnalysisManager::GetCommonFileName());
+ mgr->ConnectInput(task, 0, mgr->GetCommonInputContainer());
+ mgr->ConnectOutput(task, 1, histOut);
+ mgr->ConnectOutput(task, 2, output);
+
+
+ return task;
+}
--- /dev/null
+//
+// Calculate the multiplicity in the forward regions event-by-event
+//
+// Inputs:
+// - AliESDEvent
+//
+// Outputs:
+// - AliAODForwardMult
+//
+// Histograms
+//
+// Corrections used
+//
+#include "AliForwardQATask.h"
+#include "AliForwardUtil.h"
+#include "AliTriggerAnalysis.h"
+#include "AliPhysicsSelection.h"
+#include "AliLog.h"
+#include "AliESDEvent.h"
+#include "AliAODHandler.h"
+#include "AliMultiplicity.h"
+#include "AliInputEventHandler.h"
+#include "AliForwardCorrectionManager.h"
+#include "AliAnalysisManager.h"
+#include "AliAODForwardMult.h"
+#include <TH1.h>
+#include <TDirectory.h>
+#include <TTree.h>
+#include <TROOT.h>
+
+
+//====================================================================
+AliForwardQATask::AliForwardQATask()
+ : AliAnalysisTaskSE(),
+ fEnableLowFlux(false),
+ fFirstEvent(true),
+ fCorrManager(0),
+ fESDFMD(),
+ fHistos(),
+ fEventInspector(),
+ fEnergyFitter(),
+ fSharingFilter(),
+ fDensityCalculator(),
+ fList(0)
+{
+ //
+ // Constructor
+ //
+}
+
+//____________________________________________________________________
+AliForwardQATask::AliForwardQATask(const char* name)
+ : AliAnalysisTaskSE(name),
+ fEnableLowFlux(false),
+ fFirstEvent(true),
+ fCorrManager(0),
+ fESDFMD(),
+ fHistos(),
+ fEventInspector("event"),
+ fEnergyFitter("energy"),
+ fSharingFilter("sharing"),
+ fDensityCalculator("density"),
+ fList(0)
+{
+ //
+ // Constructor
+ //
+ // Parameters:
+ // name Name of task
+ //
+ DefineOutput(1, TList::Class());
+ DefineOutput(2, TList::Class());
+ fCorrManager = &AliForwardCorrectionManager::Instance();
+ fEnergyFitter.SetNParticles(1); // Just find the 1st peak
+ fEnergyFitter.SetDoMakeObject(false);
+ fEnergyFitter.SetUseIncreasingBins(true);
+ fEnergyFitter.SetDoFits(kTRUE);
+ fEnergyFitter.SetLowCut(0.4);
+ fEnergyFitter.SetFitRangeBinWidth(4);
+ fEnergyFitter.SetMinEntries(1000);
+}
+
+//____________________________________________________________________
+AliForwardQATask::AliForwardQATask(const AliForwardQATask& o)
+ : AliAnalysisTaskSE(o),
+ fEnableLowFlux(o.fEnableLowFlux),
+ fFirstEvent(o.fFirstEvent),
+ fCorrManager(o.fCorrManager),
+ fESDFMD(o.fESDFMD),
+ fHistos(o.fHistos),
+ fEventInspector(o.fEventInspector),
+ fEnergyFitter(o.fEnergyFitter),
+ fSharingFilter(o.fSharingFilter),
+ fDensityCalculator(o.fDensityCalculator),
+ fList(o.fList)
+{
+ //
+ // Copy constructor
+ //
+ // Parameters:
+ // o Object to copy from
+ //
+ DefineOutput(1, TList::Class());
+ DefineOutput(2, TList::Class());
+}
+
+//____________________________________________________________________
+AliForwardQATask&
+AliForwardQATask::operator=(const AliForwardQATask& o)
+{
+ //
+ // Assignment operator
+ //
+ // Parameters:
+ // o Object to assign from
+ //
+ // Return:
+ // Reference to this object
+ //
+ AliAnalysisTaskSE::operator=(o);
+
+ fEnableLowFlux = o.fEnableLowFlux;
+ fFirstEvent = o.fFirstEvent;
+ fCorrManager = o.fCorrManager;
+ fEventInspector = o.fEventInspector;
+ fEnergyFitter = o.fEnergyFitter;
+ fSharingFilter = o.fSharingFilter;
+ fDensityCalculator = o.fDensityCalculator;
+ fHistos = o.fHistos;
+ fList = o.fList;
+
+ return *this;
+}
+
+//____________________________________________________________________
+void
+AliForwardQATask::SetDebug(Int_t dbg)
+{
+ //
+ // Set debug level
+ //
+ // Parameters:
+ // dbg Debug level
+ //
+ fEventInspector.SetDebug(dbg);
+ fEnergyFitter.SetDebug(dbg);
+ fSharingFilter.SetDebug(dbg);
+ fDensityCalculator.SetDebug(dbg);
+}
+
+//____________________________________________________________________
+Bool_t
+AliForwardQATask::CheckCorrections(UInt_t what) const
+{
+ //
+ // Check if all needed corrections are there and accounted for. If not,
+ // do a Fatal exit
+ //
+ // Parameters:
+ // what Which corrections is needed
+ //
+ // Return:
+ // true if all present, false otherwise
+ //
+
+ AliForwardCorrectionManager& fcm = AliForwardCorrectionManager::Instance();
+ // Check that we have the energy loss fits, needed by
+ // AliFMDSharingFilter
+ // AliFMDDensityCalculator
+ if (what & AliForwardCorrectionManager::kELossFits && !fcm.GetELossFit()) {
+ AliFatal(Form("No energy loss fits"));
+ return false;
+ }
+ return true;
+}
+
+//____________________________________________________________________
+Bool_t
+AliForwardQATask::ReadCorrections(const TAxis*& pe,
+ const TAxis*& pv,
+ Bool_t mc)
+{
+ //
+ // Read corrections
+ //
+ //
+ UInt_t what = AliForwardCorrectionManager::kAll;
+ what ^= AliForwardCorrectionManager::kDoubleHit;
+ what ^= AliForwardCorrectionManager::kVertexBias;
+ what ^= AliForwardCorrectionManager::kAcceptance;
+ what ^= AliForwardCorrectionManager::kMergingEfficiency;
+
+ AliForwardCorrectionManager& fcm = AliForwardCorrectionManager::Instance();
+ if (!fcm.Init(GetEventInspector().GetCollisionSystem(),
+ GetEventInspector().GetEnergy(),
+ GetEventInspector().GetField(),
+ mc,
+ what)) return false;
+ if (!CheckCorrections(what)) return false;
+
+ // Sett our persistency pointer
+ // fCorrManager = &fcm;
+
+ // Get the eta axis from the secondary maps - if read in
+ if (!pe) {
+ pe = fcm.GetEtaAxis();
+ if (!pe) AliFatal("No eta axis defined");
+ }
+ // Get the vertex axis from the secondary maps - if read in
+ if (!pv) {
+ pv = fcm.GetVertexAxis();
+ if (!pv) AliFatal("No vertex axis defined");
+ }
+
+ return true;
+}
+
+//____________________________________________________________________
+AliESDEvent*
+AliForwardQATask::GetESDEvent()
+{
+ //
+ // Get the ESD event. IF this is the first event, initialise
+ //
+ AliESDEvent* esd = dynamic_cast<AliESDEvent*>(InputEvent());
+ if (!esd) {
+ AliWarning("No ESD event found for input event");
+ return 0;
+ }
+
+ // On the first event, initialize the parameters
+ if (fFirstEvent && esd->GetESDRun()) {
+ GetEventInspector().ReadRunDetails(esd);
+
+ AliInfo(Form("Initializing with parameters from the ESD:\n"
+ " AliESDEvent::GetBeamEnergy() ->%f\n"
+ " AliESDEvent::GetBeamType() ->%s\n"
+ " AliESDEvent::GetCurrentL3() ->%f\n"
+ " AliESDEvent::GetMagneticField()->%f\n"
+ " AliESDEvent::GetRunNumber() ->%d\n",
+ esd->GetBeamEnergy(),
+ esd->GetBeamType(),
+ esd->GetCurrentL3(),
+ esd->GetMagneticField(),
+ esd->GetRunNumber()));
+
+ fFirstEvent = false;
+
+ InitializeSubs();
+ }
+ return esd;
+}
+//____________________________________________________________________
+void
+AliForwardQATask::InitializeSubs()
+{
+ //
+ // Initialise the sub objects and stuff. Called on first event
+ //
+ //
+ const TAxis* pe = 0;
+ const TAxis* pv = 0;
+
+ if (!ReadCorrections(pe,pv)) return;
+
+ fHistos.Init(*pe);
+
+ fEventInspector.Init(*pv);
+ fEnergyFitter.Init(*pe);
+ fSharingFilter.Init();
+ fDensityCalculator.Init(*pe);
+
+ this->Print();
+}
+
+//____________________________________________________________________
+void
+AliForwardQATask::UserCreateOutputObjects()
+{
+ //
+ // Create output objects
+ //
+ //
+ fList = new TList;
+ fList->SetOwner();
+
+ fEventInspector.DefineOutput(fList);
+ fEnergyFitter.DefineOutput(fList);
+ fSharingFilter.DefineOutput(fList);
+ fDensityCalculator.DefineOutput(fList);
+
+ PostData(1, fList);
+}
+//____________________________________________________________________
+void
+AliForwardQATask::UserExec(Option_t*)
+{
+ //
+ // Process each event
+ //
+ // Parameters:
+ // option Not used
+ //
+
+ // static Int_t cnt = 0;
+ // cnt++;
+ // Get the input data
+ AliESDEvent* esd = GetESDEvent();
+
+ // Clear stuff
+ fHistos.Clear();
+ fESDFMD.Clear();
+
+ Bool_t lowFlux = kFALSE;
+ UInt_t triggers = 0;
+ UShort_t ivz = 0;
+ Double_t vz = 0;
+ Double_t cent = -1;
+ UShort_t nClusters = 0;
+ UInt_t found = fEventInspector.Process(esd, triggers, lowFlux,
+ ivz, vz, cent, nClusters);
+
+ if (found & AliFMDEventInspector::kNoEvent) return;
+ if (found & AliFMDEventInspector::kNoTriggers) return;
+ if (found & AliFMDEventInspector::kNoSPD) return;
+ if (found & AliFMDEventInspector::kNoFMD) return;
+ if (found & AliFMDEventInspector::kNoVertex) return;
+ if (triggers & AliAODForwardMult::kPileUp) return;
+ if (found & AliFMDEventInspector::kBadVertex) return;
+
+ // We we do not want to use low flux specific code, we disable it here.
+ if (!fEnableLowFlux) lowFlux = false;
+
+ // Get FMD data
+ AliESDFMD* esdFMD = esd->GetFMDData();
+
+ // Run the energy loss fitter
+ if (!fEnergyFitter.Accumulate(*esdFMD, cent,
+ triggers & AliAODForwardMult::kEmpty)) {
+ AliWarning("Energy fitter failed");
+ return;
+ }
+
+ // // Apply the sharing filter (or hit merging or clustering if you like)
+ if (!fSharingFilter.Filter(*esdFMD, lowFlux, fESDFMD)) {
+ AliWarning("Sharing filter failed!");
+ return;
+ }
+
+ // Calculate the inclusive charged particle density
+ if (!fDensityCalculator.Calculate(fESDFMD, fHistos, ivz, lowFlux)) {
+ // if (!fDensityCalculator.Calculate(*esdFMD, fHistos, ivz, lowFlux)) {
+ AliWarning("Density calculator failed!");
+ return;
+ }
+ PostData(1, fList);
+}
+
+//____________________________________________________________________
+void
+AliForwardQATask::Terminate(Option_t*)
+{
+ //
+ // End of job
+ //
+ // Parameters:
+ // option Not used
+ //
+
+ TList* list = dynamic_cast<TList*>(GetOutputData(1));
+ if (!list) {
+ AliError(Form("No output list defined (%p)", GetOutputData(1)));
+ if (GetOutputData(1)) GetOutputData(1)->Print();
+ return;
+ }
+
+ // Get our histograms from the container
+ TH1I* hEventsTr = 0;//static_cast<TH1I*>(list->FindObject("nEventsTr"));
+ TH1I* hEventsTrVtx = 0;//static_cast<TH1I*>(list->FindObject("nEventsTrVtx"));
+ TH1I* hTriggers = 0;
+ if (!fEventInspector.FetchHistograms(list, hEventsTr,
+ hEventsTrVtx, hTriggers)) {
+ AliError(Form("Didn't get histograms from event selector "
+ "(hEventsTr=%p,hEventsTrVtx=%p)",
+ hEventsTr, hEventsTrVtx));
+ return;
+ }
+
+ fEnergyFitter.Fit(list);
+
+ fSharingFilter.ScaleHistograms(list,Int_t(hEventsTr->Integral()));
+ fDensityCalculator.ScaleHistograms(list,Int_t(hEventsTrVtx->Integral()));
+
+ // Make a deep copy and post that as output 2
+ TList* list2 = static_cast<TList*>(list->Clone(Form("%sResults",
+ list->GetName())));
+ list2->SetOwner();
+ PostData(2, list2);
+
+}
+
+//____________________________________________________________________
+void
+AliForwardQATask::Print(Option_t* option) const
+{
+ //
+ // Print information
+ //
+ // Parameters:
+ // option Not used
+ //
+
+ std::cout << ClassName() << ": " << GetName() << "\n"
+ << " Enable low flux code: " << (fEnableLowFlux ? "yes" : "no")
+ << "\n"
+ << " Off-line trigger mask: 0x"
+ << std::hex << std::setfill('0')
+ << std::setw (8) << fOfflineTriggerMask
+ << std::dec << std::setfill (' ') << std::endl;
+ gROOT->IncreaseDirLevel();
+ if (fCorrManager) fCorrManager->Print();
+ else
+ std::cout << " Correction manager not set yet" << std::endl;
+ GetEventInspector() .Print(option);
+ GetEnergyFitter() .Print(option);
+ GetSharingFilter() .Print(option);
+ gROOT->DecreaseDirLevel();
+}
+
+//
+// EOF
+//
--- /dev/null
+//
+// Calculate the qa in the forward regions event-by-event
+//
+#ifndef ALIFORWARDQATASK_H
+#define ALIFORWARDQATASK_H
+/**
+ * @file AliForwardQATask.h
+ * @author Christian Holm Christensen <cholm@dalsgaard.hehi.nbi.dk>
+ * @date Wed Mar 23 14:06:42 2011
+ *
+ * @brief
+ *
+ *
+ * @ingroup pwg2_forward_aod
+ */
+#include <AliAnalysisTaskSE.h>
+#include "AliFMDEventInspector.h"
+#include "AliFMDSharingFilter.h"
+#include "AliFMDDensityCalculator.h"
+#include "AliFMDEnergyFitter.h"
+#include <AliESDFMD.h>
+class AliForwardCorrectionManager;
+class AliESDEvent;
+class TH2D;
+class TList;
+class TAxis;
+
+/**
+ * Calculate the QA in the forward regions
+ *
+ * @par Inputs:
+ * - AliESDEvent
+ *
+ * @par Outputs:
+ * - Histograms
+ *
+ * @par Histograms
+ *
+ * @par Corrections used
+ *
+ * @ingroup pwg2_forward_tasks
+ *
+ */
+class AliForwardQATask : public AliAnalysisTaskSE
+{
+public:
+ /**
+ * Constructor
+ *
+ * @param name Name of task
+ */
+ AliForwardQATask(const char* name);
+ /**
+ * Constructor
+ */
+ AliForwardQATask();
+ /**
+ * Copy constructor
+ *
+ * @param o Object to copy from
+ */
+ AliForwardQATask(const AliForwardQATask& o);
+ /**
+ * Assignment operator
+ *
+ * @param o Object to assign from
+ *
+ * @return Reference to this object
+ */
+ AliForwardQATask& operator=(const AliForwardQATask& o);
+ /**
+ * @{
+ * @name Interface methods
+ */
+ /**
+ * Create output objects
+ *
+ */
+ virtual void UserCreateOutputObjects();
+ /**
+ * Process each event
+ *
+ * @param option Not used
+ */
+ virtual void UserExec(Option_t* option);
+ /**
+ * End of job
+ *
+ * @param option Not used
+ */
+ virtual void Terminate(Option_t* option);
+ /**
+ * @}
+ */
+ /**
+ * @{
+ * @name Access to sub-algorithms
+ */
+ /**
+ * Get reference to the EventInspector algorithm
+ *
+ * @return Reference to AliFMDEventInspector object
+ */
+ AliFMDEventInspector& GetEventInspector() { return fEventInspector; }
+ /**
+ * Get reference to the EnergyFitter algorithm
+ *
+ * @return Reference to AliFMDEnergyFitter object
+ */
+ AliFMDEnergyFitter& GetEnergyFitter() { return fEnergyFitter; }
+ /**
+ * Get reference to the SharingFilter algorithm
+ *
+ * @return Reference to AliFMDSharingFilter object
+ */
+ AliFMDSharingFilter& GetSharingFilter() { return fSharingFilter; }
+ /**
+ * Get reference to the DensityCalculator algorithm
+ *
+ * @return Reference to AliFMDDensityCalculator object
+ */
+ AliFMDDensityCalculator& GetDensityCalculator() { return fDensityCalculator; }
+ /**
+ * Get reference to the EventInspector algorithm
+ *
+ * @return Reference to AliFMDEventInspector object
+ */
+ const AliFMDEventInspector& GetEventInspector() const { return fEventInspector; }
+ /**
+ * Get reference to the EnergyFitter algorithm
+ *
+ * @return Reference to AliFMDEnergyFitter object
+ */
+ const AliFMDEnergyFitter& GetEnergyFitter() const { return fEnergyFitter; }
+ /**
+ * Get reference to the SharingFilter algorithm
+ *
+ * @return Reference to AliFMDSharingFilter object
+ */
+ const AliFMDSharingFilter& GetSharingFilter() const { return fSharingFilter; }
+ /**
+ * Get reference to the DensityCalculator algorithm
+ *
+ * @return Reference to AliFMDDensityCalculator object
+ */
+ const AliFMDDensityCalculator& GetDensityCalculator() const { return fDensityCalculator; }
+ /**
+ * @}
+ */
+ /**
+ * Set debug level
+ *
+ * @param dbg Debug level
+ */
+ void SetDebug(Int_t dbg);
+ void Print(Option_t* option="") const;
+protected:
+ /**
+ * Check if all needed corrections are there and accounted for. If not,
+ * do a Fatal exit
+ *
+ * @param what Which corrections is needed
+ *
+ * @return true if all present, false otherwise
+ */
+ Bool_t CheckCorrections(UInt_t what) const;
+ /**
+ * Read corrections
+ *
+ */
+ virtual Bool_t ReadCorrections(const TAxis*& pe,
+ const TAxis*& pv,
+ Bool_t mc=false);
+ /**
+ * Get the ESD event. IF this is the first event, initialise
+ */
+ virtual AliESDEvent* GetESDEvent();
+ /**
+ * Initialise the sub objects and stuff. Called on first event
+ *
+ */
+ virtual void InitializeSubs();
+
+ Bool_t fEnableLowFlux;// Whether to use low-flux specific code
+ Bool_t fFirstEvent; // Whether the event is the first seen
+ /**
+ * A pointer to the corrections manager. This is here to make the
+ * corrections manager persistent - that is, when we write the
+ * analysis train to a file (as done in PROOF) we should also write
+ * down the corrections mananger. This pointer ensures that.
+ */
+ AliForwardCorrectionManager* fCorrManager; // Pointer to corrections manager
+
+ AliESDFMD fESDFMD; // Sharing corrected ESD object
+ AliForwardUtil::Histos fHistos; // Cache histograms
+
+ AliFMDEventInspector fEventInspector; // Algorithm
+ AliFMDEnergyFitter fEnergyFitter; // Algorithm
+ AliFMDSharingFilter fSharingFilter; // Algorithm
+ AliFMDDensityCalculator fDensityCalculator; // Algorithm
+
+ TList* fList; // Output list
+
+ ClassDef(AliForwardQATask,1) // Forward QA class
+};
+
+#endif
+// Local Variables:
+// mode: C++
+// End:
+
--- /dev/null
+#include "TrainSetup.C"
+
+//====================================================================
+/**
+ * Analysis train to do energy loss fits
+ *
+ * @ingroup pwg2_forward_trains
+ */
+class MakeQATrain : public TrainSetup
+{
+public:
+ /**
+ * Constructor. Date and time must be specified when running this
+ * in Termiante mode on Grid
+ *
+ * @param name Name of train
+ * @param useCent Whether to use centrality or not
+ * @param dateTime Append date and time to name
+ * @param year Year
+ * @param month Month
+ * @param day Day
+ * @param hour Hour
+ * @param min Minutes
+ */
+ MakeQATrain(const char* name = "Forward QA",
+ Bool_t useCent = false,
+ Bool_t dateTime = false,
+ UShort_t year = 0,
+ UShort_t month = 0,
+ UShort_t day = 0,
+ UShort_t hour = 0,
+ UShort_t min = 0)
+ : TrainSetup(name, dateTime, year, month, day, hour, min),
+ fUseCent(useCent)
+ {}
+ //__________________________________________________________________
+ /**
+ * Run this analysis
+ *
+ * @param mode Mode
+ * @param oper Operation
+ * @param nEvents Number of events (negative means all)
+ * @param mc If true, assume simulated events
+ * @param par IF true, use par files
+ */
+ void Run(const char* mode, const char* oper,
+ Int_t nEvents=-1, Bool_t mc=false, Bool_t par=false)
+ {
+ Exec("ESD", mode, oper, nEvents, mc, par);
+ }
+ //__________________________________________________________________
+ /**
+ * Run this analysis
+ *
+ * @param mode Mode
+ * @param oper Operation
+ * @param nEvents Number of events (negative means all)
+ * @param mc If true, assume simulated events
+ * @param par IF true, use par files
+ */
+ void Run(EMode mode, EOper oper, Int_t nEvents=-1, Bool_t mc=false,
+ Bool_t par=false)
+ {
+ Exec(kESD, mode, oper, nEvents, mc, par);
+ }
+protected:
+ //__________________________________________________________________
+ /**
+ * Create the tasks
+ *
+ * @param mode Processing mode
+ * @param par Whether to use par files
+ * @param mgr Analysis manager
+ */
+ void CreateTasks(EMode mode, Bool_t par, AliAnalysisManager* mgr)
+ {
+ // --- Output file name ------------------------------------------
+ AliAnalysisManager::SetCommonFileName("forward_eloss.root");
+
+ // --- Load libraries/pars ---------------------------------------
+ LoadLibrary("PWG2forward2", mode, par, true);
+
+ // --- Set load path ---------------------------------------------
+ gROOT->SetMacroPath(Form("%s:$(ALICE_ROOT)/PWG2/FORWARD/analysis2",
+ gROOT->GetMacroPath()));
+
+ // --- Check if this is MC ---------------------------------------
+ Bool_t mc = mgr->GetMCtruthEventHandler() != 0;
+
+ // --- Add the task ----------------------------------------------
+ gROOT->Macro(Form("AddTaskForwardQA.C(%d,%d)", mc, fUseCent));
+ }
+ /**
+ * Create entrality selection if enabled
+ *
+ * @param mc Whether this is MC or not
+ * @param mgr Analysis manager
+ */
+ virtual void CreateCentralitySelection(Bool_t mc, AliAnalysisManager* mgr)
+ {
+ if (!fUseCent) return;
+
+ gROOT->Macro("AddTaskCentrality.C");
+ AliCentralitySelectionTask* ctask =
+ dynamic_cast<AliCentralitySelectionTask*>(mgr->GetTask("CentralitySelection"));
+ if (!ctask) return;
+ ctask->SetPass(fESDPass);
+ if (mc) ctask->SetMCInput();
+ }
+ /**
+ * Crete output handler - we don't want one here.
+ *
+ * @return 0
+ */
+ AliVEventHandler* CreateOutputHandler(EType) { return 0; }
+ Bool_t fUseCent; // Whether to use centrality or not
+};
+
+//
+// EOF
+//