--- /dev/null
+/**
+ * @file AAFHelper.C
+ * @author Christian Holm Christensen <cholm@master.hehi.nbi.dk>
+ * @date Tue Oct 16 19:02:14 2012
+ *
+ * @brief AAF analysis helper
+ *
+ * @ingroup pwglf_forward_trains_helper
+ *
+ */
+#ifndef AAFHELPER_C
+#define AAFHELPER_C
+#include "ProofHelper.C"
+#ifndef __CINT__
+# include "AvailableSoftware.C"
+# include <TUrl.h>
+# include <TString.h>
+# include <TProof.h>
+# include <AliAnalysisManager.h>
+#else
+class TUrl;
+class AliAnalysisAlien;
+#endif
+
+// ===================================================================
+/**
+ * Handle analysis on an Alice Analysis Facility (AAF)
+ *
+ * This helper is triggered by a URL of the form
+ *
+ * @code
+ * proof://[<user>@]<host>[:<port>]/<dsname>[?<options>][#<treename>]
+ * @endcode
+ * where <host@gt; is a known AAF (e.g., <tt>alice-caf.cern.ch</tt>)
+ * <dl>
+ * <dt><user@gt;</dt>
+ * <dd>Optional user name</dd>
+ * <dt><host@gt;</dt>
+ * <dd>PROOF cluster master host</dd>
+ * <dt><port@gt;</dt>
+ * <dd>Optional PROOF cluster port on master host</dd>
+ * <dt><dsname@gt;</dt>
+ * <dd>Data set name</dd>
+ * <dt><treename@gt;</dt>
+ * <dd>Optional tree name in data set, often <tt>esdTree</tt> or
+ * <tt>aodTree</tt></dd>
+ * <dt><options@gt;</dt>
+ * <dd>List of options separated by an &
+ * <dl>
+ * <dt><tt>dsname</tt>[=<output dataset>]</dt>
+ * <dd>Register tree output (e.g., AOD) as a new data set on the
+ * PROOF cluster. If <output dataset> is not specified, take
+ * the name of the train.</dd>
+ * <dt><tt>storage=<url></tt></dt>
+ * <dd>Specify a non-default storage location for special output
+ * (e.g., AOD trees). <url> should be a valid XRootd
+ * server URI accessible to the slaves - e.g.,
+ * <tt>root://lxplus.cern.ch:10930//tmp</tt>.</dd>
+ * <dt><tt>mode=[default,rec,sim,train,custom]</tt></dt>
+ * <dd>Set the AliROOT mode. If not specified <tt>default</tt>
+ * is assumed</tt>. See also CreateAliROOTPar</dd>
+ * <dt><tt>par</tt></dt>
+ * <dd> Use par files </dd>
+ * </dl>
+ * </dd>
+ * </dl>
+ *
+ * Note, this helper does not use the AliAnalysisAlien plugin
+ *
+ * @ingroup pwglf_forward_trains_helper
+ */
+struct AAFHelper : public ProofHelper
+{
+ /**
+ * Constructor
+ *
+ * @param url Url
+ * @param opts Options
+ */
+ AAFHelper(const TUrl& url, Int_t verbose)
+ : ProofHelper(url, verbose)
+ {
+ fOptions.Add("aliroot", "VERSION", "AliROOT version", "last");
+ fOptions.Add("root", "VERISON", "ROOT version", "last");
+ }
+ virtual ~AAFHelper() {}
+ /**
+ * Get the name of the AliROOT par file to use
+ *
+ * @return String
+ */
+ virtual const char* AliROOTParName() const
+ {
+ return Form("VO_ALICE@AliRoot::%s", fOptions.Get("aliroot").Data());
+ }
+ virtual Bool_t CreateAliROOTPar()
+ {
+ return true;
+ }
+ /**
+ * Set-up done before task set-ups. Overload ProofHelper::PreSetup
+ * to specify the ROOT version using TProofMgr::SetROOTVersion
+ *
+ * @return true on success
+ */
+ virtual Bool_t PreSetup()
+ {
+ TString aliroot("last");
+ TString root("last");
+ if (fOptions.Has("aliroot")) aliroot = fOptions.Get("aliroot");
+ if (fOptions.Has("root")) root = fOptions.Get("root");
+
+ AvailableSoftware::Check(aliroot, root);
+ fOptions.Set("aliroot", aliroot);
+ fOptions.Set("root", root);
+
+ fBasePars = false;
+
+ TProof::Mgr(fUrl.GetHost())
+ ->SetROOTVersion(Form("VO_ALICE@ROOT::%s", root.Data()));
+
+ return ProofHelper::PreSetup();
+ }
+ /**
+ * @return URI help string
+ */
+ virtual const Char_t* UrlHelp() const
+ {
+ return "proof://<host>/<dataset>?[&<options>][#<treename>]";
+ }
+ /**
+ * @return short description
+ */
+ virtual const char* Desc() const { return "AAF"; }
+};
+#endif
+//
+// EOF
+//
--- /dev/null
+/**
+ * @file AAFPluginHelper.C
+ * @author Christian Holm Christensen <cholm@master.hehi.nbi.dk>
+ * @date Tue Oct 16 19:01:45 2012
+ *
+ * @brief AAF (using AliAnalysisAlien) analysis helper
+ *
+ * @ingroup pwglf_forward_trains_helper
+ *
+ */
+#ifndef AAFPLUGINHELPER_C
+#define AAFPLUGINHELPER_C
+#include "PluginHelper.C"
+#ifndef __CINT__
+# include <TUrl.h>
+# include <TString.h>
+# include <AliAnalysisManager.h>
+# include <AliAnalysisAlien.h>
+#else
+class TUrl;
+class AliAnalysisAlien;
+#endif
+
+// ===================================================================
+/**
+ * Handle analysis on an Alice Analysis Facility (AAF)
+ *
+ * This helper is triggered by a URL of the form
+ *
+ * @code
+ * proof://[<user>@]<host>[:<port>]/<dsname>[?<options>][#<treename>]
+ * @endcode
+ * where <host@gt; is a known AAF (e.g., <tt>alice-caf.cern.ch</tt>),
+ * and the <options> contains <tt>plugin</tt>
+ * <dl>
+ * <dt><user@gt;</dt>
+ * <dd>Optional user name</dd>
+ * <dt><host@gt;</dt>
+ * <dd>PROOF cluster master host</dd>
+ * <dt><port@gt;</dt>
+ * <dd>Optional PROOF cluster port on master host</dd>
+ * <dt><dsname@gt;</dt>
+ * <dd>Data set name</dd>
+ * <dt><treename@gt;</dt>
+ * <dd>Optional tree name in data set, often <tt>esdTree</tt> or
+ * <tt>aodTree</tt></dd>
+ * <dt><options@gt;</dt>
+ * <dd>List of options separated by an &
+ * <dl>
+ * <dt><tt>dsname</tt>[=<output dataset>]</dt>
+ * <dd>Register tree output (e.g., AOD) as a new data set on the
+ * PROOF cluster. If <output dataset> is not specified, take
+ * the name of the train.</dd>
+ * <dt><tt>storage=<url></tt></dt>
+ * <dd>Specify a non-default storage location for special output
+ * (e.g., AOD trees). <url> should be a valid XRootd
+ * server URI accessible to the slaves - e.g.,
+ * <tt>root://lxplus.cern.ch:10930//tmp</tt>.</dd>
+ * <dt><tt>mode=[default,rec,sim,train,custom]</tt></dt>
+ * <dd>Set the AliROOT mode. If not specified <tt>default</tt>
+ * is assumed</tt>. See also CreateAliROOTPar</dd>
+ * <dt><tt>par</tt></dt>
+ * <dd> Use PAR files</dd>
+ * <dt><tt>workers=</tt><i>N</i><tt>[x]</tt></dt>
+ * <dd>Set the number of workers to use. If <tt>x</tt> is appended,
+ * then it's maximum number of workers per slave</dd>
+ * </dl>
+ * </dd>
+ * </dl>
+ *
+ * @ingroup pwglf_forward_trains_helper
+ */
+struct AAFPluginHelper : public PluginHelper
+{
+ /**
+ * Constructor
+ *
+ * @param url Url
+ * @param opts Options
+ */
+ AAFPluginHelper(const TUrl& url, Int_t verbose)
+ : PluginHelper(url, verbose)
+ {
+ fOptions.Add("workers", "N[x]", "Number of workers to use", "0");
+ fOptions.Add("dsname", "NAME", "Make output dataset", "");
+
+ }
+ /**
+ * Destructor
+ */
+ virtual ~AAFPluginHelper() {}
+ /**
+ * Called before setting up
+ *
+ * @return true on success
+ */
+ virtual Bool_t PreSetup()
+ {
+ TString root = fOptions.Get("root");
+ fHandler->SetRootVersionForProof(Form("VO_ALICE@ROOT::%s", root.Data()));
+ fHandler->SetProofCluster(fUrl.GetHost());
+ fHandler->SetProofDataSet(fUrl.GetFile());
+ if (fOptions.Has("workers")) {
+ TString nwork = fOptions.Get("workers");
+ if (nwork.EndsWith("x"))
+ fHandler->SetNproofWorkersPerSlave(nwork.Atoi());
+ else
+ fHandler->SetNproofWorkers(nwork.Atoi());
+ }
+ return PluginHelper::PreSetup();
+ }
+ /**
+ * Set-up done after the task set-ups
+ *
+ * @return true on success
+ */
+ virtual Bool_t PostSetup()
+ {
+ if (!PluginHelper::PostSetup()) return false;
+ if (fOptions.Has("dsname"))
+ OutputUtilities::RegisterDataset(fOptions.Get("dsname"));
+
+ return true;
+ };
+ /**
+ * Get the mode identifier
+ *
+ * @return Always kProof
+ */
+ virtual UShort_t Mode() const { return kProof; }
+ /**
+ * Get the mode string used for AliAnalysisManager::StartAnalysis
+ */
+ virtual const char* ModeString() const { return "proof"; }
+ /**
+ * Start the analysis
+ *
+ * @param nEvents Number of events to analyse
+ *
+ * @return The return value of AliAnalysisManager::StartAnalysis
+ */
+ virtual Long64_t Run(Long64_t nEvents=-1)
+ {
+ AliAnalysisManager* mgr = AliAnalysisManager::GetAnalysisManager();
+
+ TString dsName(fUrl.GetFile());
+ if (fUrl.GetAnchor() && fUrl.GetAnchor()[0] != '\0')
+ dsName.Append(Form("#%s", fUrl.GetAnchor()));
+ return mgr->StartAnalysis(fUrl.GetProtocol(), dsName, nEvents);
+ }
+ /**
+ * @return URI help string
+ */
+ virtual const Char_t* UrlHelp() const
+ {
+ return "proof://<host>/<dataset>?plugin[&<options>][#<treename>]";
+ }
+ /**
+ * @return Short description
+ */
+ virtual const char* Desc() const { return "CAF w/plugin"; }
+};
+#endif
+//
+// EOF
+//
--- /dev/null
+/**
+ * @file AvailableSoftware.C
+ * @author Christian Holm Christensen <cholm@master.hehi.nbi.dk>
+ * @date Tue Oct 16 17:54:11 2012
+ *
+ * @brief Find available packages
+ *
+ * @ingroup pwglf_forward_trains_util
+ */
+
+#ifndef AVAILABLESOFTWARE_C
+#define AVAILABLESOFTWARE_C
+#ifndef __CINT__
+# include <TString.h>
+# include <TSystem.h>
+# include <TError.h>
+# include <TObjArray.h>
+#else
+class TString;
+#endif
+
+/**
+ * Helper code to find available packages on Grid
+ *
+ *
+ * @ingroup pwglf_forward_trains_util
+ */
+struct AvailableSoftware
+{
+ static Bool_t Check(TString& aliroot, TString& root)
+ {
+ // Figure out what to do.
+ // If mode == 0, then do nothing.
+ // If bit 0 is set in mode (0x1), then list and exit
+ // If bit 1 is set in mode (0x2), select last AliROOT/ROOT version
+ // If bit 2 is set in mode (0x4), select ROOT corresponding to AliROOT
+ UShort_t mode = 0;
+
+ TString c("wget -q http://alimonitor.cern.ch/packages/ -O - | "
+ "sed -n -e '/<tr/,/<\\/tr>/ p' | "
+ "sed -n '/<a.*VO_ALICE@AliRoot::/,/VO_ALICE@ROOT::/ p' | "
+ "sed -n -e 's/.*VO_ALICE@AliRoot::\\([-0-9a-zA-Z]*\\).*/%\\1%/p' "
+ " -e 's/.*VO_ALICE@ROOT::\\([-0-9a-zA-Z]*\\).*/\\1@/p' | "
+ "tr -d '\\n' | tr '@' '\\n' | tr '%' '\\t' ");
+
+ if (aliroot.EqualTo("list", TString::kIgnoreCase) ||
+ root.EqualTo("list", TString::kIgnoreCase) ||
+ aliroot.IsNull()) {
+ Warning("AvaliableSoftware::Check", "No AliROOT/ROOT version specified, "
+ "available packages are:\n"
+ "\tAliROOT \tROOT:");
+ gSystem->Exec(c);
+ return false;
+ }
+
+ if (aliroot.EqualTo("last", TString::kIgnoreCase))
+ mode |= 0x2;
+ else if (!aliroot.IsNull())
+ mode |= 0x4;
+
+ // Nothing to do
+ if (mode == 0) return true;
+
+
+ TString values = gSystem->GetFromPipe(c);
+ TObjArray* tokens = values.Tokenize(" \t\n");
+ Int_t n = tokens->GetEntries();
+
+ // If we asked to select the last possible version, do so here and get out
+ if (mode & 0x2) {
+ aliroot = tokens->At(n-2)->GetName();
+ root = tokens->At(n-1)->GetName();
+ Info("AvaliableSoftware::Check",
+ "Selecting lastest possible AliROOT/ROOT: %s/%s",
+ aliroot.Data(), root.Data());
+ delete tokens;
+ return true;
+ }
+
+ // We get here if we're asked to find a ROOT version compatible
+ // with the selected AliROOT version.
+ for (Int_t i = 0; i < n; i += 2) {
+ if (aliroot.EqualTo(tokens->At(i)->GetName(),
+ TString::kIgnoreCase)) {
+ root = tokens->At(i+1)->GetName();
+ Info("AvaliableSoftware::Check",
+ "Found ROOT version compatible with AliROOT %s: %s",
+ aliroot.Data(), root.Data());
+ delete tokens;
+ return true;
+ }
+ }
+ // If we get here, then we didn't find a ROOT version compatible
+ // with the selected AliROOT, and we should fail.
+ Warning("AvaliableSoftware::Check",
+ "Didn't find a ROOT version compatible with AliROOT %s",
+ aliroot.Data());
+ delete tokens;
+ return false;
+ }
+};
+#endif
--- /dev/null
+/**
+ * @file ChainBuilder.C
+ * @author Christian Holm Christensen <cholm@master.hehi.nbi.dk>
+ * @date Tue Oct 16 17:54:26 2012
+ *
+ * @brief Build a chain
+ *
+ * @ingroup pwglf_forward_trains_util
+ */
+
+#ifndef CHAINBUILDER_C
+#define CHAINBUILDER_C
+#ifndef __CINT__
+# include <TString.h>
+# include <TChain.h>
+# include <TSystemDirectory.h>
+# include <TSystem.h>
+# include <TFile.h>
+# include <TList.h>
+# include <TError.h>
+# include <TROOT.h>
+# include <TGridCollection.h>
+# include <TFileCollection.h>
+# include <THashList.h>
+# include <TKey.h>
+# include <fstream>
+#else
+class TString;
+class TChain;
+class TSystemDirectory;
+#endif
+
+// ===================================================================
+/**
+ * Build a chain
+ *
+ * @ingroup pwglf_forward_trains_util
+ */
+struct ChainBuilder
+{
+ enum {
+ kInvalid,
+ kDirectory,
+ kXML,
+ kAscii,
+ kROOT
+ };
+ //------------------------------------------------------------------
+ static UShort_t CheckSource(TString& src)
+ {
+ // Local copy
+ TString tmp(src);
+
+ // --- Normalize the path ----------------------------------------
+ if (tmp == ".") tmp = "";
+ if (!tmp.BeginsWith("/")) tmp.Prepend("../");
+ if (gSystem->ExpandPathName(tmp)) {
+ Error("ChainBuilder::CheckSource",
+ "Failed to expand source %s", src.Data());
+ return kInvalid;
+ }
+
+ // --- Stat the file ---------------------------------------------
+ FileStat_t stat;
+ if (gSystem->GetPathInfo(tmp, stat)) return kInvalid;
+ src = tmp;
+
+ // --- Check if directory or file --------------------------------
+ if (R_ISDIR(stat.fMode)) return kDirectory;
+
+ // --- check file type -------------------------------------------
+ TString type(gSystem->GetFromPipe(Form("file -b %s", src.Data())));
+ if (type.Contains("ROOT")) return kROOT;
+ else if (type.Contains("XML")) return kXML;
+ else if (type.Contains("ASCII")) return kAscii;
+
+ Error("ChainBuilder::CheckSource",
+ "Do not now how to process %s of type %s",
+ src.Data(), type.Data());
+ return kInvalid;
+ }
+ //------------------------------------------------------------------
+ /**
+ * Create the chain. User is owner.
+ *
+ * @return Null in case of problems, chain otherwise
+ */
+ static TChain* Create(const TString& src,
+ const TString& treeName,
+ const TString& pattern,
+ Bool_t mc,
+ Bool_t recursive)
+ {
+ TString tmp(src);
+ UShort_t type = CheckSource(tmp);
+
+ return Create(type, tmp, treeName, pattern, mc, recursive);
+ }
+ //------------------------------------------------------------------
+ /**
+ * Create the chain. User is owner.
+ *
+ * @return Null in case of problems, chain otherwise
+ */
+ static TChain* Create(UShort_t type,
+ const TString& src,
+ const TString& treeName,
+ const TString& pattern,
+ Bool_t mc,
+ Bool_t recursive)
+ {
+ // --- check input -----------------------------------------------
+ if (type == kInvalid) {
+ Error("ChainBuilder::Create", "Source %s isn't a file or directory",
+ src.Data());
+ return 0;
+ }
+ TString tN(treeName);
+ if (tN.IsNull())
+ Warning("ChainBuilder::Create", "No tree name specified, assuming T");
+
+ TString pat(pattern);
+ if (pat.IsNull()) {
+ if (tN.EqualTo("esdTree")) pat = "AliESD";
+ else if (tN.EqualTo("aodTree")) pat = "AliAOD";
+ }
+
+ // --- Create output ---------------------------------------------
+ TChain* chain = new TChain(tN);
+
+ // --- execute based on type
+ Bool_t ret = true;
+ switch (type) {
+ case kROOT: ret = CreateFromFile(chain, src); break;
+ case kXML: ret = CreateFromXML(chain, src); break;
+ case kAscii: ret = CreateFromList(chain, src); break;
+ case kDirectory: ret = CreateFromDirectory(chain, src,
+ pat, mc,
+ recursive); break;
+ default: ret = false;
+ }
+
+ // --- Clean-up --------------------------------------------------
+ if (chain->GetListOfFiles()->GetEntries() <= 0) ret = false;
+ if (!ret) {
+ delete chain;
+ chain = 0;
+ }
+ return chain;
+ }
+ //------------------------------------------------------------------
+ /**
+ * Create a chain consiting of a single file
+ *
+ * @param fn File name.
+ *
+ * @return Chain or null
+ */
+ static Bool_t CreateFromFile(TChain* chain, const TString& src)
+ {
+ // Info("CreateFromFile", "Making from single file %s", src.Data());
+ if (!CheckFile(src, chain)) return false;
+ return true;
+ }
+ //------------------------------------------------------------------
+ /**
+ * Create a chain from an XML containing an collection
+ *
+ * @return Newly allocated chain or null
+ */
+ static Bool_t CreateFromXML(TChain* chain, const TString& src)
+ {
+ Long_t ret = gROOT->ProcessLine(Form("TAlienCollection(\"%s\")",
+ src.Data()));
+ if (!ret) {
+ Error("ChainBuilder::CreateFromXML",
+ "Cannot create AliEn collection from XML file %s", src.Data());
+ return false;
+ }
+
+ TGridCollection* collection = reinterpret_cast<TGridCollection*>(ret);
+ if (!collection) {
+ Error("ChainBuilder::CreateFromXML",
+ "Cannot create AliEn collection from XML file %s", src.Data());
+ return false;
+ }
+
+ collection->Reset();
+ while (collection->Next()) chain->Add(collection->GetTURL(""));
+
+ return true;
+ }
+ //------------------------------------------------------------------
+ /**
+ * Create a chain from a file containing a list of files
+ *
+ * @return Newly allocated chain or null
+ */
+ static Bool_t CreateFromList(TChain* chain, const TString& src)
+ {
+ std::ifstream in(src.Data());
+ if (!in) {
+ Error("ChainBuilder::CreateFromList",
+ "Failed to open list %s", src.Data());
+ return false;
+ }
+
+ while (in.good()) {
+ TString line;
+ line.ReadToDelim(in);
+ TString l(line.Strip(TString::kBoth));
+ if (l.IsWhitespace() || l.BeginsWith("#")) continue;
+
+ if (!CheckFile(l, chain))
+ Warning("ChainBuilder::CreateFromList",
+ "Failed to add %s to chain", l.Data());
+ }
+ return true;
+ }
+ //------------------------------------------------------------------
+ /**
+ * Make a chain from a base directory, pattern, and treename -
+ * possibly recursively
+ *
+ * @return true on success
+ */
+ static Bool_t CreateFromDirectory(TChain* chain,
+ const TString& src,
+ const TString& pattern,
+ Bool_t mc,
+ Bool_t recursive)
+ {
+ // Info("", "Scanning src=%s, pattern=%s, mc=%d recursive=%d",
+ // src.Data(), pattern.Data(), mc, recursive);
+ // Save current directory
+ TString savdir(gSystem->WorkingDirectory());
+ TSystemDirectory d(gSystem->BaseName(src.Data()), src.Data());
+ // Info("", "Will scan %s", d.GetTitle());
+ if (!ScanDirectory(chain, &d, pattern, mc, recursive)) return false;
+ // Go back to the saved directory
+ gSystem->ChangeDirectory(savdir);
+
+ return true;
+ }
+ //------------------------------------------------------------------
+ /**
+ * Check if we can add a file to the chain
+ *
+ * @param path Full path to file
+ * @param chain Chain
+ *
+ * @return true on success, false otherwise
+ */
+ static Bool_t CheckFile(const TString& path, TChain* chain)
+ {
+ // Info("", "Checking %s", path.Data());
+ gSystem->RedirectOutput("/dev/null", "w");
+ TFile* test = TFile::Open(path, "READ");
+ gSystem->RedirectOutput(0);
+ if (!test) {
+ Warning("ChainBuilder::CheckFile", "Failed to open %s", path.Data());
+ return false;
+ }
+
+ TObject* o = test->Get(chain->GetName());
+ if (!o) {
+ // Let's try to find a TFileCollection
+ TList* l = test->GetListOfKeys();
+ TIter next(l);
+ TKey* k = 0;
+ Bool_t ok = false;
+ while ((k = static_cast<TKey*>(next()))) {
+ TString cl(k->GetClassName());
+ if (!cl.EqualTo("TFileCollection")) continue;
+ TFileCollection* fc = dynamic_cast<TFileCollection*>(k->ReadObj());
+ Info("", "Adding file collection");
+ chain->AddFileInfoList(fc->GetList());
+ ok = true;
+ }
+ if (ok) {
+ test->Close();
+ return true;
+ }
+ }
+ else if (dynamic_cast<TTree*>(o)) {
+ test->Close();
+ chain->Add(path);
+ return true;
+ }
+
+ Warning("ChainBuilder::CheckFile",
+ "The file %s does not contain the tree %s or a file collection",
+ path.Data(), chain->GetName());
+
+ return false;
+ }
+ //------------------------------------------------------------------
+ /**
+ * Scan directory @a dir (possibly recursive) for tree files to add
+ * to the chain. This does not follow sym-links
+ *
+ * @param dir Directory to scan
+ * @param chain Chain to add to
+ *
+ * @return true if any files where added
+ */
+ static Bool_t ScanDirectory(TChain* chain,
+ TSystemDirectory* dir,
+ const TString& pattern,
+ Bool_t mc,
+ Bool_t recursive)
+ {
+ // Assume failure
+ Bool_t ret = false;
+
+ // Get list of files, and go back to old working directory
+ TString oldDir(gSystem->WorkingDirectory());
+ TList* files = dir->GetListOfFiles();
+ if (!gSystem->ChangeDirectory(oldDir)) {
+ Error("ChainBuilder::ScanDirectory", "Failed to go back to %s",
+ oldDir.Data());
+ return false;
+ }
+ if (!files) {
+ Warning("ChainBuilder::ScanDirectory", "No files");
+ return false;
+ }
+
+ TList toAdd;
+ toAdd.SetOwner();
+ Bool_t hasGAlice = (!(mc) ? true : false);
+ Bool_t hasKine = (!(mc) ? true : false);
+ Bool_t hasTrRef = (!(mc) ? true : false);
+
+ // Sort list of files and check if we should add it
+ files->Sort();
+ TIter next(files);
+ TSystemFile* file = 0;
+ while ((file = static_cast<TSystemFile*>(next()))) {
+ TString name(file->GetName());
+ TString title(file->GetTitle());
+ TString full(gSystem->ConcatFileName(file->GetTitle(), name.Data()));
+ // Info("", "Got file %s", full.Data());
+ if (file->IsA()->InheritsFrom(TSystemDirectory::Class())) full = title;
+ // Ignore special links
+ if (name == "." || name == "..") {
+ // Info("ChainBuilder::ScanDirectory", "Ignoring %s", name.Data());
+ continue;
+ }
+ // Info("", "Got file %s", full.Data());
+
+ FileStat_t fs;
+ if (gSystem->GetPathInfo(full.Data(), fs)) {
+ Warning("ChainBuilder::ScanDirectory", "Cannot stat %s (%s)",
+ full.Data(), gSystem->WorkingDirectory());
+ continue;
+ }
+ // Check if this is a directory
+ if (file->IsDirectory(full)) {
+ // Info("", "Recursive scan of %s", full.Data());
+ if (recursive) {
+ // if (title[0] == '/')
+ TSystemDirectory* d = new TSystemDirectory(file->GetName(),
+ full.Data());
+ if (ScanDirectory(chain, d, pattern, mc, recursive))
+ ret = true;
+ delete d;
+ }
+ continue;
+ }
+
+ // If this is not a root file, ignore
+ if (!name.EndsWith(".root")) {
+ // Info("ScanDirectory", "File %s does not end in .root", name.Data());
+ continue;
+ }
+
+ // If this file does not contain AliESDs, ignore
+ if (!name.Contains(pattern)) {
+ // Info("ChainBuilder::ScanDirectory", "%s does not match pattern %s",
+ // name.Data(), pattern.Data());
+ if (mc) {
+ if (name.CompareTo("galice.root") == 0) hasGAlice = true;
+ if (name.CompareTo("Kinematics.root") == 0) hasKine = true;
+ if (name.CompareTo("TrackRefs.root") == 0) hasTrRef = true;
+ }
+ continue;
+ }
+
+ // Add
+ // Info("ChainBuilder::ScanDirectory", "Adding %s", full.Data());
+ toAdd.Add(new TObjString(full));
+ }
+
+ if (mc && toAdd.GetEntries() > 0 &&
+ (!hasGAlice || !hasKine || !hasTrRef)) {
+ Warning("ChainBuilder::ScanDirectory",
+ "one or more of {galice,Kinematics,TrackRefs}.root missing from "
+ "%s, not adding anything from this directory",
+ dir->GetTitle());
+ toAdd.Delete();
+ }
+
+ TIter nextAdd(&toAdd);
+ TObjString* s = 0;
+ Int_t added = 0;
+ while ((s = static_cast<TObjString*>(nextAdd()))) {
+ // Info("ChainBuilder::ScanDirectory",
+ // "Adding %s", s->GetString().Data());
+ TString fn = s->GetString();
+ if (!CheckFile(fn, chain)) continue;
+
+ added++;
+ }
+ if (added > 0) ret = true;
+
+ gSystem->ChangeDirectory(oldDir);
+ return ret;
+ }
+};
+#endif
--- /dev/null
+void
+CreateFileCollection(const TString& dir="/data/alice/data/ppb/LHC12g/pass1/188359/",
+ const TString& tN="esdTree",
+ const TString& pa="AliESD",
+ Bool_t mc=false,
+ Bool_t recursive=false)
+)
+{
+ gROOT->LoadMacro("ChainBuilder.C+");
+
+ UShort_t type = ChainBuilder::CheckSource(dir);
+ Info("", "type=%d", type);
+ TChain* chain = ChainBuilder::Create(dir, tN, pa, mc, recursive);
+ if (!chain) {
+ Error("CreateFileCollection", "Failed to make chain");
+ return;
+ }
+ Int_t port;
+ TString host;
+ {
+ TUrl u(Form("root://%s//foo", gSystem->HostName()));
+ port = u.GetPort() * 10;
+ host = u.GetHostFQDN();
+ }
+
+
+ TFileCollection* fc = new TFileCollection("files");
+ TObjArray* cEs = chain->GetListOfFiles();
+ TChainElement* cE = 0;
+ TIter next(cEs);
+ while ((cE= static_cast<TChainElement*>(next()))) {
+ TString fN(cE->GetTitle());
+ TFile* f = TFile::Open(fN, "READ");
+ TTree* t = static_cast<TTree*>(f->Get(tN));
+
+ fN.Prepend(Form("root://%s:%d/", host.Data(), port));
+ TFileInfo* fi = new TFileInfo(Form("%s tree:%s,%d",
+ fN.Data(), tN.Data(), t->GetEntries()),
+ f->GetSize());
+ f->Close();
+ fc->Add(fi);
+ }
+ fc->Print("F");
+
+ TFile* files = TFile::Open("files.root", "RECREATE");
+ fc->Write();
+ files->Close();
+
+}
--- /dev/null
+/**
+ * @file GridHelper.C
+ * @author Christian Holm Christensen <cholm@master.hehi.nbi.dk>
+ * @date Tue Oct 16 19:01:27 2012
+ *
+ * @brief Grid Analysis Helper
+ *
+ * @ingroup pwglf_forward_trains_helper
+ *
+ */
+#ifndef GRIDHELPER_C
+#define GRIDHELPER_C
+#include "PluginHelper.C"
+#ifndef __CINT__
+# include <TUrl.h>
+# include <TString.h>
+# include <TGrid.h>
+# include <AliAnalysisManager.h>
+# include <AliAnalysisAlien.h>
+#else
+class TUrl;
+class AliAnalysisAlien;
+#endif
+
+// ===================================================================
+/**
+ * Handle analysis on an the Grid
+ *
+ * This helper is triggered by a URL of the form
+ *
+ * @code
+ * alien:///<directory>[?<options>][#<pattern>]
+ * @endcode
+ * where
+ * <dl>
+ * <dt><directory@gt;</dt>
+ * <dd>Grid directory that holds the data</dd>
+ * <dt><treeName@gt;</dt>
+ * <dd>Tree to loop over</dd>
+ * <dt><options@gt;</dt>
+ * <dd>List of options separated by an &
+ * <dl>
+ * <dt><tt>storage=<url></tt></dt>
+ * <dd>Specify a non-default storage location for special output
+ * (e.g., AOD trees). <url> should be a valid XRootd
+ * server URI accessible to the slaves - e.g.,
+ * <tt>root://lxplus.cern.ch:10930//tmp</tt>.</dd>
+ * <dt><tt>mode=[default,rec,sim,train,custom]</tt></dt>
+ * <dd>Set the AliROOT mode. If not specified <tt>default</tt>
+ * is assumed</tt>. See also CreateAliROOTPar</dd>
+ * <dt><tt>par</tt></dt>
+ * <dd> Use PAR files</dd>
+ * <dt><tt>runs=[list or file]</tt></dt>
+ * <dd>Comma separated list of run numbers, or file(s) containing
+ * run numbers</dd>
+ * <dt><tt>oper=[FULL,TERMINATE,SUBMIT,OFFLINE,TEST]</tt></dt>
+ * <dd>How to run the analysis</dd>
+ * <dt><tt>split=<N></tt></dt>
+ * <dd>Maximum number of files per split</dd>
+ * <dt><tt>merge=<N></tt></dt>
+ * <dd>Maximum number of files per merger</dd>
+ * <dt><tt>mc</tt></dt>
+ * <dd>Scan also for MC files (<tt>galice.root</tt>,
+ * <tt>Kinematics.root</tt>, and <tt>TrackRefs.root</tt>) when
+ * scanning <datadir></dd>
+ * <dt><tt>pattern=<GLOB></tt></dt>
+ * <dd>Shell glob pattern that files must check when scanning
+ * <datadir></dd>
+ * </dl>
+ * </dd>
+ * </dl>
+ *
+ * @ingroup pwglf_forward_trains_helper
+ */
+struct GridHelper : public PluginHelper
+{
+ /**
+ * Constructor
+ *
+ * @param url Url
+ * @param opts Options
+ */
+ GridHelper(const TUrl& url, Int_t verbose)
+ : PluginHelper(url, verbose)
+ {
+ fOptions.Add("oper", "FULL|TERMINATE|SUBMIT", "Analysis operation", "FULL");
+ fOptions.Add("split", "N", "Maximum number of files before split", "max");
+ fOptions.Add("merge", "N", "Maximum number of files for merge", "max");
+ fOptions.Add("run", "RUNS", "Range, list, and/or file of runs", "");
+ fOptions.Add("pattern","GLOB", "File/directory name pattern", "");
+ fOptions.Add("mc", "Assume MC input");
+ }
+ virtual ~GridHelper() {}
+ /**
+ * Get the mode identifier
+ *
+ * @return Always kProof
+ */
+ virtual UShort_t Mode() const { return kGrid; }
+ /**
+ * Get the mode string used for AliAnalysisManager::StartAnalysis
+ */
+ virtual const char* ModeString() const { return "grid"; }
+ /**
+ * Set-up done before task set-ups
+ *
+ * @return true on success
+ */
+ virtual UShort_t Operation() const
+ {
+ if (!fOptions.Has("oper")) return kFull;
+ const TString& oper = fOptions.Get("oper");
+ if (oper.EqualTo("FULL", TString::kIgnoreCase)) return kFull;
+ else if (oper.EqualTo("OFFLINE", TString::kIgnoreCase)) return kOffline;
+ else if (oper.EqualTo("SUBMIT", TString::kIgnoreCase)) return kSubmit;
+ else if (oper.EqualTo("TERMINATE", TString::kIgnoreCase)) return kTerminate;
+ else if (oper.EqualTo("TEST", TString::kIgnoreCase)) return kTest;
+ return kFull;
+ }
+ /**
+ * Read run numbers
+ *
+ * @return Number of registered runs
+ */
+ virtual Int_t RegisterRuns()
+ {
+ if (!fOptions.Find("run")) {
+ Error("GridHelper::RegisterRuns", "No runs specified");
+ return -1;
+ }
+ Int_t nRuns = 0;
+ TString runs = fOptions.Get("runs");
+ TObjArray* tokens = runs.Tokenize(",");
+ TObjString* part = 0;
+ TIter next(tokens);
+ Bool_t range = false;
+ Bool_t individual = false;
+ while ((part = static_cast<TObjString*>(next()))) {
+ TString& s = part->String();
+ if (s.Contains("-")) { // Run range
+ if (range) {
+ Warning("GridHelper::RegisterRuns", "Run range already specified, "
+ "ignoring %s", s.Data());
+ continue;
+ }
+ if (individual) {
+ Warning("GridHelper::RegisterRuns",
+ "Run ranges and individual run specs do not mix, "
+ "ignoring %s", s.Data());
+ continue;
+ }
+ TObjArray* ranges = s.Tokenize("-");
+ if (ranges->GetEntriesFast() > 2) {
+ Warning("GridHelper::RegisterRuns", "Invalid run range: %s",
+ s.Data());
+ ranges->Delete();
+ continue;
+ }
+ Int_t first = static_cast<TObjString*>(ranges->At(0))->String().Atoi();
+ Int_t last = static_cast<TObjString*>(ranges->At(1))->String().Atoi();
+ nRuns = last-first+1;
+ fHandler->SetRunRange(first, last);
+ ranges->Delete();
+ range = true;
+ continue;
+ }
+ if (s.IsDigit()) { // single run
+ if (range) {
+ Warning("GridHelper::RegisterRuns",
+ "Run ranges and individual run specs do not mix, "
+ "ignoring %s", s.Data());
+ continue;
+ }
+ fHandler->AddRunNumber(s.Data());
+ nRuns++;
+ individual = true;
+ continue;
+ }
+ if (range) {
+ Warning("GridHelper::RegisterRuns", "Run ranges and list file "
+ "do not mix, ignoring %s", s.Data());
+ continue;
+ }
+
+ // We assume this part is a file
+ std::ifstream in(s.Data());
+ if (!in) {
+ Warning("GridHelper::RegisterRuns", "Failed to open %s", s.Data());
+ continue;
+ }
+ while (!in.eof()) {
+ Int_t r;
+ in >> r;
+ fHandler->AddRunNumber(r);
+ nRuns++;
+ Char_t c;
+ in >> c;
+ if (in.bad()) break;
+ }
+ individual = true;
+ in.close();
+ }
+ return nRuns;
+ }
+ /**
+ * Executed before setting up tasks
+ *
+ * @return true on success
+ */
+ virtual Bool_t PreSetup()
+ {
+ if (!PluginHelper::PreSetup()) return false;
+
+ // --- Open a connection to the grid -----------------------------
+ TGrid::Connect(Form("%s://", fUrl.GetProtocol()));
+ if (!gGrid || !gGrid->IsConnected()) {
+ Error("GridHelper::PreSetup", "Failed to connect to AliEN");
+ return false;
+ }
+
+ return true;
+ }
+ /**
+ * Set-up done after the task set-ups
+ *
+ * @return true on success
+ */
+ virtual Bool_t PostSetup()
+ {
+ if (!PluginHelper::PostSetup()) return false;
+
+ AliAnalysisManager* mgr = AliAnalysisManager::GetAnalysisManager();
+ TString name(mgr->GetName());
+
+ // --- Set the operation to do (TEST, SUBMIT, TERMINATE, FULL) ---
+ TString operation("FULL");
+ if (fOptions.Has("oper")) operation = fOptions.Get("oper");
+ fHandler->SetRunMode(operation);
+
+ // --- Do not test copying ---------------------------------------
+ fHandler->SetCheckCopy(false);
+
+ // --- Set output to be per run ----------------------------------
+ fHandler->SetOutputToRunNo(true);
+
+ // --- Set the job tag -------------------------------------------
+ fHandler->SetJobTag(name);
+
+ // --- Set number of test files - used in test mode only ---------
+ fHandler->SetNtestFiles(1);
+
+ // --- Set the Time-To-Live --------------------------------------
+ fHandler->SetTTL(70000);
+
+ // --- Re-submit failed jobs as long as the ratio of failed jobs -
+ // --- is this percentage.
+ fHandler->SetMasterResubmitThreshold(95);
+
+ // --- Set the input format --------------------------------------
+ fHandler->SetInputFormat("xml-single");
+
+ // --- Set names of generated files ------------------------------
+ fHandler->SetAnalysisMacro(Form("%s.C", name.Data()));
+ fHandler->SetJDLName(Form("%s.jdl", name.Data()));
+ fHandler->SetExecutable(Form("%s.sh", name.Data()));
+
+ // ---- Set the job price !? -------------------------------------
+ fHandler->SetPrice(1);
+
+ // --- Set whether to merge via JDL ------------------------------
+ fHandler->SetMergeViaJDL(true);
+
+ // --- Fast read otion -------------------------------------------
+ fHandler->SetFastReadOption(false);
+
+ // --- Whether to overwrite existing output ----------------------
+ fHandler->SetOverwriteMode(true);
+
+ // --- Set the executable binary name and options ----------------
+ fHandler->SetExecutableCommand("aliroot -b -q -x");
+
+ // --- Split by storage element - must be lower case! ------------
+ fHandler->SetSplitMode("se");
+
+ // --- How much to split -----------------------------------------
+ if (fOptions.Has("split")) {
+ if (!fOptions.Get("split").EqualTo("max")) {
+ fHandler->SetSplitMaxInputFileNumber(fOptions.Get("split").Atoi());
+ }
+ }
+
+ // --- Enable default outputs ------------------------------------
+ fHandler->SetDefaultOutputs(true);
+
+ // --- Merge parameters ------------------------------------------
+ if (fOptions.Has("merge")) {
+ if (!fOptions.Get("merge").EqualTo("max")) {
+ fHandler->SetMaxMergeFiles(fOptions.Get("merge").Atoi());
+ }
+ }
+ fHandler->SetMergeExcludes("AliAOD.root *EventStat*.root "
+ "*event_stat*.root");
+
+ // --- Keep log files ------------------------------------------
+ fHandler->SetKeepLogs();
+
+ // --- Set the working directory to be the trains name (with -----
+ // --- special characters replaced by '_' and the date appended),
+ // --- and also set the output directory (relative to working
+ // --- directory)
+ fHandler->SetGridWorkingDir(name.Data());
+ fHandler->SetGridOutputDir("output");
+ fHandler->SetGridDataDir(fUrl.GetFile());
+
+ // --- Get the tree name and set the file pattern ----------------
+ TString pattern;
+ if (fOptions.Has("pattern")) pattern = fOptions.Get("pattern");
+ else {
+ TString treeName(fUrl.GetAnchor());
+ if (treeName.IsNull()) {
+ Warning("GridHelper::PreSetup", "No tree name specified, assuming T");
+ treeName = "T";
+ }
+ if (treeName.EqualTo("esdTree")) pattern = "AliESD";
+ else if (treeName.EqualTo("aodTree")) pattern = "AliAOD";
+ }
+ fHandler->SetDataPattern(pattern);
+ fHandler->SetRunPrefix(mgr->GetMCtruthEventHandler() ? "" : "000");
+
+ // --- Add the run numbers ---------------------------------------
+ Int_t nRun = RegisterRuns();
+
+ // --- Set number of runs per master - set to one to per run -----
+ fHandler->SetNrunsPerMaster(fOptions.Has("run-merge") ? 1 : nRun+1);
+
+ // --- Loop over defined containers in the analysis manager, and -
+ // --- declare these as outputs
+ TString listOfAODs = "";
+ TString listOfHists = "";
+
+ AliAnalysisDataContainer* cont = 0;
+ TIter nextCont(mgr->GetOutputs());
+ while ((cont = static_cast<AliAnalysisDataContainer*>(nextCont()))) {
+ TString outName(cont->GetFileName());
+ TString& list = (outName == "default" ? listOfAODs : listOfHists);
+ if (outName == "default") {
+ if (!mgr->GetOutputEventHandler()) continue;
+
+ outName = mgr->GetOutputEventHandler()->GetOutputFileName();
+ }
+ if (list.Contains(outName)) continue;
+ if (!list.IsNull()) list.Append(",");
+ list.Append(outName);
+ }
+ if (!mgr->GetExtraFiles().IsNull()) {
+ if (!listOfAODs.IsNull()) listOfAODs.Append("+");
+ TString extra = mgr->GetExtraFiles();
+ extra.ReplaceAll(" ", ",");
+ listOfAODs.Append(extra);
+ }
+
+ Int_t nReplica = 2;
+ TString outArchive = Form("stderr, stdout@disk=%d", nReplica);
+ if (!listOfHists.IsNull())
+ outArchive.Append(Form(" hist_archive.zip:%s@disk=%d",
+ listOfHists.Data(), nReplica));
+ if (!listOfAODs.IsNull())
+ outArchive.Append(Form(" aod_archive.zip:%s@disk=%d",
+ listOfAODs.Data(), nReplica));
+ if (listOfAODs.IsNull() && listOfHists.IsNull())
+ Fatal("PostSetup", "No outputs defined");
+
+ return true;
+ };
+ /**
+ * Start the analysis
+ *
+ * @param nEvents Number of events to analyse
+ *
+ * @return The return value of AliAnalysisManager::StartAnalysis
+ */
+ virtual Long64_t Run(Long64_t nEvents=-1)
+ {
+ AliAnalysisManager* mgr = AliAnalysisManager::GetAnalysisManager();
+
+ return mgr->StartAnalysis("grid", nEvents);
+ }
+ /**
+ * Link an auxilary file to working directory
+ *
+ * @param name Name of the file
+ *
+ * @return true on success
+ */
+ virtual Bool_t AuxFile(const TString& name)
+ {
+ if (!Helper::AuxFile(name)) return false;
+ // We need to add this file as an additional 'library', so that the
+ // file is uploaded to the users Grid working directory.
+ fHandler->AddAdditionalLibrary(gSystem->BaseName(name.Data()));
+ return true;
+ }
+ /**
+ * Get the output (directory)
+ *
+ */
+ virtual TString OutputPath() const
+ {
+ TString ret;
+ if (!fHandler) {
+ Warning("GridHelper::OutputLocation", "No AliEn handler");
+ return ret;
+ }
+ ret = fHandler->GetGridOutputDir();
+ if (ret.BeginsWith("/")) return ret;
+
+ AliAnalysisManager* mgr = AliAnalysisManager::GetAnalysisManager();
+ if (!mgr) {
+ Warning("GridHelper::OutputLocation", "No analysis manager");
+ return ret;
+ }
+ ret.Prepend(Form("%s/", mgr->GetName()));
+ if (gGrid)
+ ret.Prepend(Form("%s/", gGrid->GetHomeDirectory()));
+
+ return ret;
+ }
+ /**
+ * @return URL help string
+ */
+ virtual const Char_t* UrlHelp() const
+ {
+ return "alien:///<datadir>[?<options>][#<treeName>]";
+ }
+ /**
+ * @return Short description
+ */
+ virtual const char* Desc() const { return "AliEn"; }
+};
+#endif
+//
+// EOF
+//
--- /dev/null
+/**
+ * @defgroup pwglf_forward_trains_helper Analysis helpers
+ *
+ * @ingroup pwglf_forward_trains
+ *
+ *
+ */
+/**
+ * @file Helper.C
+ * @author Christian Holm Christensen <cholm@master.hehi.nbi.dk>
+ * @date Tue Oct 16 19:00:17 2012
+ *
+ * @brief Base class for analysis helpers
+ *
+ * @ingroup pwglf_forward_trains_helper
+ *
+ */
+#ifndef TRAIN_HELPER_C
+#define TRAIN_HELPER_C
+#ifndef __CINT__
+# include "Option.C"
+# include <TUrl.h>
+# include <TString.h>
+# include <TMap.h>
+# include <TObjString.h>
+# include <TSystem.h>
+# include <TROOT.h>
+# include <TError.h>
+# include <TObjArray.h>
+# include <AliAnalysisManager.h>
+# include <iostream>
+#else
+class TString;
+class TUrl;
+class TMap;
+class Option;
+class OptionList;
+#endif
+
+/**
+ * Helper class to set-up an analysis using a train
+ *
+ * @ingroup pwglf_forward_trains_helper
+ */
+struct Helper
+{
+ enum EMode {
+ kLocal,
+ kProof,
+ kGrid
+ };
+ enum EOperation {
+ kTest,
+ kOffline,
+ kSubmit,
+ kTerminate,
+ kFull
+ };
+ enum EInput {
+ kESD,
+ kAOD,
+ kUser
+ };
+ Helper(const Helper& o)
+ : fUrl(o.fUrl), fOptions(o.fOptions), fVerbose(o.fVerbose)
+ {}
+ Helper& operator=(const Helper&) { return *this; }
+ /**
+ * Create a helper object.
+ *
+ * @param url Url describing the job.
+ *
+ * - Local mode:
+ *
+ * @code
+ * local://<path>[#<treeName>][?[recursive[&]]]
+ * @endcode
+ *
+ * <path> can be a single ROOT file, a text file with one
+ * entry per file to add to the chain, or a directory containing the
+ * files. If <path> does not start with a '/' then it is
+ * interpreted as a relative path.
+ *
+ * - Grid mode:
+ *
+ * @code
+ * alien:///<path>#<pattern>
+ * @endcode
+ *
+ * - PROOF mode:
+ *
+ * Several options
+ *
+ * @code
+ * lite:///<path>[?[recursive[&]][workers=<n>]][#treeName]
+ * proof:///<path>[?[recursive[&]][workers=<n>]][#treeName]
+ * @endcode
+ *
+ * @code
+ * proof://<host>/<dsname>[?[workers=<n>[&]][dsname[=<outname>]]][#treeName]
+ * @endcode
+ *
+ * Note, if <host> is recognised as an Alice Analysis
+ * Facility, then the Grid handler (AliAnalysisAlien) is used unless
+ * the option <tt>plain</tt> was given.
+ *
+ * @return Newly allocated helper or null
+ */
+ static Helper* Create(const TUrl& url, Int_t verbose=0);
+ /**
+ * Load a library
+ *
+ * @param name Name of library
+ * @param slave If true also load on slaves
+ *
+ * @return true on success, false otherwise
+ */
+ virtual Bool_t LoadLibrary(const TString& name,
+ Bool_t slave=true) = 0;
+ /**
+ * Load a source file, and compile it
+ *
+ * @param name Name of the source file
+ *
+ * @return true on success
+ */
+ virtual Bool_t LoadSource(const TString& name)
+ {
+ if (!AuxFile(name)) return false;
+ TString base(gSystem->BaseName(name));
+ gROOT->LoadMacro(Form("%s++g", base.Data()));
+ return true;
+ }
+ /**
+ * Load auxillary file - not compiled or sourced. Just copied to
+ * working directory
+ *
+ * @param name Extra file name
+ *
+ * @return true on success
+ */
+ virtual Bool_t LoadAux(const TString& name)
+ {
+ if (!AuxFile(name)) return false;
+ return true;
+ }
+
+ /**
+ * Load needed ROOT libaries
+ */
+ virtual Bool_t LoadROOT()
+ {
+ if (gSystem->Load("libTree.so") < 0) return false;
+ if (gSystem->Load("libGeom.so") < 0) return false;
+ if (gSystem->Load("libVMC.so") < 0) return false;
+ if (gSystem->Load("libPhysics.so") < 0) return false;
+ if (gSystem->Load("libMinuit.so") < 0) return false;
+ return true;
+ }
+ /**
+ * Set-up to load the AliROOT libraries
+ *
+ * @param par Whether to use PAR files
+ *
+ * @return true on success
+ */
+ virtual Bool_t LoadAliROOT()
+ {
+ if (!gSystem->Getenv("ALICE_ROOT")) {
+ Error("Helper::LoadAliROOT", "Local AliROOT not available");
+ return false;
+ }
+ if (!LoadLibrary("STEERBase")) return false;
+ if (!LoadLibrary("ESD")) return false;
+ if (!LoadLibrary("AOD")) return false;
+ if (!LoadLibrary("ANALYSIS")) return false;
+ if (!LoadLibrary("OADB")) return false;
+ if (!LoadLibrary("ANALYSISalice")) return false;
+ return true;
+ }
+ /**
+ * Get the execution mode
+ *
+ * @return Execution mode set in set-up URL
+ */
+ virtual UShort_t Mode() const = 0;
+ /**
+ * Get the operation - this only makes sense for Grid jobs
+ *
+ * @return Operation type
+ */
+ virtual UShort_t Operation() const { return kFull; }
+ /**
+ * Get the input data type
+ *
+ * @return Input data type
+ */
+ virtual Short_t InputType() const
+ {
+ UShort_t ret = DeduceType(fUrl.GetAnchor());
+ if (ret != kUser) return ret;
+
+ if (fOptions.Has("pattern")) ret = DeduceType(fOptions.Get("pattern"));
+ if (ret != kUser) return ret;
+
+ ret = DeduceType(fUrl.GetFile());
+ return ret;
+ }
+ /**
+ * The file part of tehe output URL - overwritten by derived classes.
+ *
+ *
+ * @return File part of output URL
+ */
+ virtual TString OutputPath() const { return ""; }
+ /**
+ * Get the location of the output data. Use ful to define second pass
+ * scripts, etc.
+ *
+ *
+ * @return Url string
+ */
+ virtual TString OutputLocation() const
+ {
+ AliAnalysisManager* mgr = AliAnalysisManager::GetAnalysisManager();
+ if (!mgr || !mgr->GetOutputEventHandler()) return "";
+
+ TString path(OutputPath());
+ if (path.IsNull()) {
+ path = gSystem->WorkingDirectory();
+ // mgr->GetName();
+ }
+
+ TUrl u(fUrl);
+ u.SetFile(path);
+ u.SetAnchor("aodTree");
+ TString opt(u.GetOptions());
+ opt.ReplaceAll("AliESDs", "AliAOD");
+ u.SetOptions(opt);
+
+ return u.GetUrl();
+ }
+ /**
+ * Set-up done before task setup
+ *
+ * @return true on success
+ */
+ virtual Bool_t PreSetup() = 0;
+ /**
+ * Set-up done after task setup
+ *
+ * @return true on success
+ */
+ virtual Bool_t PostSetup() = 0;
+ /**
+ * Run the analysis
+ *
+ * @param nEvents Number of events to analyse
+ *
+ * @return The return value of AliAnalysisManager::StartAnalysis
+ */
+ virtual Long64_t Run(Long64_t nEvents=-1) = 0;
+ /**
+ * Print information to standard output
+ *
+ * @param option
+ *
+ * @return
+ */
+ virtual void Print(Option_t* ="") const
+ {
+ std::cout << "Url: " << fUrl.GetUrl() << std::endl;
+ fOptions.Show(std::cout);
+ }
+ /**
+ * @return URL help string
+ */
+ virtual const Char_t* UrlHelp() const = 0;
+ /**
+ * @return Short description string
+ */
+ virtual const char* Desc() const = 0;
+ /**
+ * Get the input URL
+ *
+ * @return Input URL
+ */
+ const TUrl& Url() const { return fUrl; }
+ /**
+ * Get the list of options
+ *
+ * @return Reference to list of options
+ */
+ const OptionList& Options() const { return fOptions; }
+ /**
+ * Create an instance of a helper class
+ */
+ static Helper* CreateObject(const TString& cl,
+ const TUrl& url,
+ Int_t verbose=0)
+ {
+ if (verbose > 3) gSystem->RedirectOutput("/dev/null","w");
+ if (cl.Contains("proof", TString::kIgnoreCase) ||
+ cl.Contains("lite", TString::kIgnoreCase) ||
+ cl.Contains("aaf", TString::kIgnoreCase)) {
+ gSystem->Load("libProof");
+ gSystem->Load("libProofPlayer");
+ }
+ gROOT->LoadMacro(Form("%s.C+",cl.Data()));
+ Long_t ptr = gROOT->ProcessLine(Form("new %s(\"%s\", %d);",
+ cl.Data(), url.GetUrl(), verbose));
+ if (verbose > 3) gSystem->RedirectOutput(0);
+ if (!ptr) {
+ Warning("Helper::CreateObject", "Failed to instantize a %s", cl.Data());
+ return 0;
+ }
+ Helper* h = reinterpret_cast<Helper*>(ptr);
+ return h;
+ }
+ /**
+ * Show help on URL using the interpreter
+ *
+ * @param cl Helper class
+ */
+ static void ShowUrlHelp(const TString& cl)
+ {
+ Helper* h = CreateObject(cl, "", true);
+ if (!h) return;
+
+ std::cout << " " << h->UrlHelp() << std::endl;
+ }
+ /**
+ * Show help on URL and options using the interpreter
+ *
+ * @param cl Helper class
+ */
+ static void ShowFullHelp(const TString& cl)
+ {
+ Helper* h = CreateObject(cl, "", true);
+ if (!h) return;
+
+ std::cout << h->Desc() << ":\n"
+ << "==============\n"
+ << " " << h->UrlHelp() << "\n\n"
+ << "Options: " << std::endl;
+ h->Options().Help(std::cout);
+ std::cout << std::endl;
+ }
+protected:
+ /**
+ * Constructor
+ *
+ * @param url Set-up URL
+ * @param opts Pre-parsed options
+ */
+ Helper(const TUrl& url, Int_t verbose)
+ : fUrl(url), fOptions(), fVerbose(verbose)
+ {
+ }
+
+ virtual Bool_t ParseOptions()
+ {
+ return fOptions.Parse(fUrl.GetOptions(), "&");
+ }
+ /**
+ * Destructor
+ */
+ virtual ~Helper()
+ {
+ }
+ /**
+ * Normalize a library name
+ *
+ * @param name
+ *
+ * @return
+ */
+ const TString& MakeLibraryName(const TString& name)
+ {
+ static TString libName;
+
+ libName = name;
+
+ if (!libName.BeginsWith("lib")) {
+ // Check if the library corresponds to a compiled macro
+ if (!gSystem->AccessPathName(Form("%s_C.so", libName.Data())))
+ libName.Append("_C");
+ else if (!gSystem->AccessPathName(Form("../%s_C.so", libName.Data())))
+ libName = Form("../%s_C", libName.Data());
+ else
+ libName = Form("lib%s", libName.Data());
+ }
+ if (!libName.EndsWith(".so")) libName.Append(".so");
+
+ return libName;
+ }
+ /**
+ * Link an auxilary file to working directory
+ *
+ * @param name Name of the file
+ *
+ * @return true on success
+ */
+ virtual Bool_t AuxFile(const TString& name)
+ {
+ TString path(gSystem->ExpandPathName(name.Data()));
+ // If not absolute, prepend up-one
+ if (!path.BeginsWith("/")) path.Prepend("../");
+ if (gSystem->AccessPathName(path.Data())) {
+ // File not accessible
+ Warning("Helper::LoadSource", "File %s not accessible", path.Data());
+ return false;
+ }
+ gSystem->Exec(Form("ln -s %s .", path.Data()));
+ return true;
+ }
+ /**
+ * Deduce the top of job from a string
+ *
+ * @param str String
+ *
+ * @return Job type
+ */
+ static UShort_t DeduceType(const TString& str)
+ {
+ if (str.IsNull()) return kUser;
+ if (str.Contains("aod", TString::kIgnoreCase)) return kAOD;
+ if (str.Contains("esd", TString::kIgnoreCase)) return kESD;
+ return kUser;
+ }
+ // --- Data members ------------------------------------------------
+ TUrl fUrl; // The URI
+ OptionList fOptions;
+ Int_t fVerbose;
+};
+
+
+
+
+// ===================================================================
+Helper*
+Helper::Create(const TUrl& url, Int_t verbose)
+{
+ if (!url.IsValid()) {
+ Warning("Helper::Create", "URL is invalid");
+ return 0;
+ }
+
+ TString prot(url.GetProtocol());
+ prot.ToLower();
+
+ TUrl tmp(url);
+ TString opts(tmp.GetOptions());
+ TString host(url.GetHost());
+ TString cl = "";
+ if (prot.EqualTo("alien")) {
+ // Create an AliEn helper
+ cl = "GridHelper";
+ }
+ else if (prot.EqualTo("local")) {
+ // Create Lite helper
+ cl = "LocalHelper";
+ }
+ else if (prot.EqualTo("proof")) {
+ // Create a Proof helper
+ if (host.IsNull())
+ cl = "LiteHelper";
+ else if (host.BeginsWith("alice-caf")) {
+ // AAF
+ cl = opts.Contains("plugin") ? "AAFPluginHelper" : "AAFHelper";
+ }
+ else
+ cl = "ProofHelper";
+ }
+ else if (prot.EqualTo("lite")) {
+ // Create a Proof helper
+ cl = "LiteHelper";
+ }
+ else if (prot.EqualTo("help")) {
+ // Special HELP protocol
+ if (host.Contains("options")) {
+ std::cout << "Possible URL types and options are:" << std::endl;
+ ShowFullHelp("LocalHelper");
+ ShowFullHelp("ProofHelper");
+ ShowFullHelp("LiteHelper");
+ ShowFullHelp("AAFHelper");
+ ShowFullHelp("AAFPluginHelper");
+ ShowFullHelp("GridHelper");
+ return 0;
+ }
+ std::cout << "Possible URL types are:" << std::endl;
+ ShowUrlHelp("LocalHelper");
+ ShowUrlHelp("ProofHelper");
+ ShowUrlHelp("LiteHelper");
+ ShowUrlHelp("AAFHelper");
+ ShowUrlHelp("AAFPluginHelper");
+ ShowUrlHelp("GridHelper");
+ return 0;
+ }
+ // --- Check if we got a scheme ------------------------------------
+ if (cl.IsNull()) {
+ Error("Helper::Create", "Unknown scheme: %s", prot.Data());
+ return 0;
+ }
+
+ // --- Use interpreter to make our object --------------------------
+ Helper* helper = CreateObject(cl, url, verbose);
+ if (!helper) {
+ Error("Helper::Create", "Failed to make object of class %s", cl.Data());
+ return 0;
+ }
+
+ // --- Parse options -----------------------------------------------
+ if (!helper->ParseOptions()) {
+ delete helper;
+ helper = 0;
+ }
+
+ return helper;
+}
+
+#endif
--- /dev/null
+/**
+ * @file LiteHelper.C
+ * @author Christian Holm Christensen <cholm@master.hehi.nbi.dk>
+ * @date Tue Oct 16 18:59:59 2012
+ *
+ * @brief Proof-Lite analysis helper
+ *
+ * @ingroup pwglf_forward_trains_helper
+ *
+ */
+#ifndef LITEHELPER_C
+#define LITEHELPER_C
+#include "ProofHelper.C"
+#ifndef __CINT__
+# include "ChainBuilder.C"
+# include <TUrl.h>
+# include <TString.h>
+# include <TChain.h>
+# include <AliAnalysisManager.h>
+#else
+class TChain;
+class TUrl;
+#endif
+
+// ===================================================================
+/**
+ * Handler of analysis in Proof-Lite. This is triggered by URIs of the
+ * form
+ *
+ * @code
+ * local:///<datadir>[?<options>][#treeName]
+ * local:///<collection>[?<options>][#treeName]
+ * local:///<file>[?<options>][#treeName]
+ * @endcode
+ *
+ * where
+ *
+ * <dl>
+ * <dt><tt><datadir></tt></dt>
+ * <dd>is the base directory holding data files </dd>
+ * <dt><tt><collection></tt></dt>
+ * <dd>is an ASCII or XML list of input sources</dd>
+ * <dt><tt><file></tt></dt>
+ * <dd>is a single ROOT file</dd>
+ * <dt><tt><options></tt></dt>
+ * <dd>A & separated list of options
+ * <dl>
+ * <dt><tt>recursive</tt></dt>
+ * <dd>Scan <datadir> recursively</dd>
+ * <dt><tt>mc</tt></dt>
+ * <dd>Scan also for MC files (<tt>galice.root</tt>,
+ * <tt>Kinematics.root</tt>, and <tt>TrackRefs.root</tt>) when
+ * scanning <datadir></dd>
+ * <dt><tt>pattern=<GLOB></tt></dt>
+ * <dd>Shell glob pattern that files must check when scanning
+ * <datadir></dd>
+ * <dt><tt>workers=N[x]</tt></dt>
+ * <dd>Set the number of workers to use. If <tt>x</tt> is appended,
+ * then it's maximum number of workers per slave</dd>
+ * <dt><tt>par[=all]</tt></dt>
+ * <dd>Use PAR files. If the value <tt>all</tt> is given, then also
+ * PAR files of STEERBase, ESD, AOD, ANALYSIS, OADB, ANALYSISalice
+ * are used. </dd>
+ * <dt><tt>mode=[default,rec,sim,train,custom]</tt></dt>
+ * <dd>Set the AliROOT mode. If not specified <tt>default</tt>
+ * is assumed</tt>. See also CreateAliROOTPar</dd>
+ * </dl>
+ * </dd>
+ * </dl>
+ *
+ * @ingroup pwglf_forward_trains_helper
+ */
+struct LiteHelper : public ProofHelper
+{
+ /**
+ * Constructor
+ *
+ * @param url Url
+ * @param opts Options
+ */
+ LiteHelper(const TUrl& url, Int_t verbose)
+ : ProofHelper(url, verbose), fChain(0)
+ {
+ fOptions.Add("mc", "Scan for MC files (galice,kinematics,trackrefs)");
+ fOptions.Add("recursive","Recursive scan");
+ fOptions.Add("pattern", "GLOB", "File name pattern", "*.root");
+ fOptions.Remove("dsname");
+ fOptions.Remove("storage");
+ }
+ /**
+ * Set-up done before task set-ups
+ *
+ * @return true on success
+ */
+ virtual Bool_t PreSetup()
+ {
+ fUrl.SetProtocol("lite");
+ Bool_t ret = ProofHelper::PreSetup();
+ return ret;
+ }
+ /**
+ * Set-up done after task set-ups
+ *
+ * @return true on success
+ */
+ virtual Bool_t PostSetup()
+ {
+ // -- Check for local chain --------------------------------------
+ TString pattern = (fOptions.Has("pattern") ?fOptions.Get("pattern") :"");
+ TString treeName = fUrl.GetAnchor();
+ Bool_t recursive = fOptions.Has("recursive");
+ Bool_t mc = fOptions.Has("mc");
+ TString src = fUrl.GetFile();
+ UShort_t type = ChainBuilder::CheckSource(src);
+ if (type == ChainBuilder::kInvalid) {
+ Error("LiteHelper", "Cannot generate TChain from %s", src.Data());
+ return false;
+ }
+
+ // --- Create the chain ------------------------------------------
+ fChain = ChainBuilder::Create(type, src, treeName, pattern, mc, recursive);
+ if (!fChain) {
+ Error("PreSetup", "No chain defined");
+ return false;
+ }
+
+ return ProofHelper::PostSetup();
+ }
+ /**
+ * Start the analysis
+ *
+ * @param nEvents Number of events to analyse
+ *
+ * @return The return value of AliAnalysisManager::StartAnalysis
+ */
+ virtual Long64_t Run(Long64_t nEvents=-1)
+ {
+ AliAnalysisManager* mgr = AliAnalysisManager::GetAnalysisManager();
+ gProof->SetLogLevel(TMath::Max(fVerbose-2,0),
+ /* TProofDebug::kPacketizer| */
+ TProofDebug::kLoop|
+ /* TProofDebug::kSelector|
+ TProofDebug::kOutput|
+ TProofDebug::kInput|
+ TProofDebug::kGlobal|*/
+ TProofDebug::kPackage);
+ if (nEvents < 0) nEvents = fChain->GetEntries();
+ Long64_t ret = mgr->StartAnalysis("proof", fChain, nEvents);
+
+ if (fVerbose > 2)
+ TProof::Mgr(fUrl.GetUrl())->GetSessionLogs()->Save("*","lite.log");
+ return ret;
+ }
+
+ /**
+ * @return URL help string
+ */
+ virtual const Char_t* UrlHelp() const
+ {
+ return "lite://<datadir_or_list>[?<options>][#<treeName]";
+ }
+ /**
+ * @return The short description
+ */
+ virtual const char* Desc() const { return "PROOF-lite"; }
+ /** Our chain */
+ TChain* fChain;
+};
+#endif
+//
+// EOF
+//
+
--- /dev/null
+/**
+ * @file LocalHelper.C
+ * @author Christian Holm Christensen <cholm@master.hehi.nbi.dk>
+ * @date Tue Oct 16 18:59:42 2012
+ *
+ * @brief Local analysis helper
+ *
+ * @ingroup pwglf_forward_trains_helper
+ *
+ */
+#ifndef LOCALHELPER_C
+#define LOCALHELPER_C
+#ifndef __CINT__
+# include "Helper.C"
+# include "ChainBuilder.C"
+# include <TUrl.h>
+# include <TString.h>
+# include <TSystem.h>
+# include <AliAnalysisManager.h>
+#else
+class TChain;
+class Helper;
+class TUrl;
+#endif
+
+// ===================================================================
+/**
+ * Handle local analysis jobs
+ *
+ * This is triggered by URIs of the form
+ *
+ * @code
+ * local:///<datadir>[?<options>][#treeName]
+ * local:///<collection>[?<options>][#treeName]
+ * local:///<file>[?<options>][#treeName]
+ * @endcode
+ *
+ * where
+ *
+ * <dl>
+ * <dt><tt><datadir></tt></dt>
+ * <dd>is the base directory holding data files </dd>
+ * <dt><tt><collection></tt></dt>
+ * <dd>is an ASCII or XML list of input sources</dd>
+ * <dt><tt><file></tt></dt>
+ * <dd>is a single ROOT file</dd>
+ * <dt><tt><options></tt></dt>
+ * <dd>A & separated list of options
+ * <dl>
+ * <dt><tt>recursive</tt></dt>
+ * <dd>Scan <datadir> recursively</dd>
+ * <dt><tt>mc</tt></dt>
+ * <dd>Scan also for MC files (<tt>galice.root</tt>,
+ * <tt>Kinematics.root</tt>, and <tt>TrackRefs.root</tt>) when
+ * scanning <datadir></dd>
+ * <dt><tt>pattern=<GLOB></tt></dt>
+ * <dd>Shell glob pattern that files must check when scanning
+ * <datadir></dd>
+ * </dl>
+ * </dd>
+ * </dl>
+ *
+ * @ingroup pwglf_forward_trains_helper
+ */
+struct LocalHelper : public Helper
+{
+ /**
+ * Constructor
+ *
+ * @param url Url
+ * @param opts Options
+ */
+ LocalHelper(const TUrl& url, Int_t verbose)
+ : Helper(url, verbose), fChain(0)
+ {
+ fOptions.Add("mc", "Scan for MC files (galice,kinematics,trackrefs)");
+ fOptions.Add("recursive","Scan recursive");
+ fOptions.Add("pattern", "GLOB", "File name pattern", "*.root");
+ }
+ /**
+ * Destructor
+ */
+ virtual ~LocalHelper() {}
+ /**
+ * Load a library
+ *
+ * @param name Name of library
+ *
+ * @return true on success
+ */
+ virtual Bool_t LoadLibrary(const TString& name, Bool_t)
+ {
+ Int_t ret = gSystem->Load(MakeLibraryName(name));
+ return ret >= 0;
+ }
+ /**
+ * Get the execution mode
+ *
+ * @return Always kLocal
+ */
+ virtual UShort_t Mode() const { return kLocal; }
+ /**
+ * Get the mode string used for AliAnalysisManager::StartAnalysis
+ */
+ virtual const char* ModeString() const { return "local"; }
+ /**
+ * Set-up done before task set-ups
+ *
+ * @return true on success
+ */
+ virtual Bool_t PreSetup()
+ {
+ return true;
+ }
+ /**
+ * Set-up done after the task set-ups
+ *
+ * @return true on success
+ */
+ virtual Bool_t PostSetup()
+ {
+ TString treeName(fUrl.GetAnchor());
+ TString pattern(fOptions.Has("pattern") ? fOptions.Get("pattern") : "");
+ Bool_t recursive = fOptions.Has("recursive");
+ Bool_t mc = fOptions.Has("mc");
+
+ fChain = ChainBuilder::Create(fUrl.GetFile(), treeName,
+ pattern, mc, recursive);
+
+ AliAnalysisManager* mgr = AliAnalysisManager::GetAnalysisManager();
+ if (!mgr) {
+ Error("PostSetup", "No analysis manager defined");
+ return false;
+ }
+ return true;
+ };
+ /**
+ * Start the analysis
+ *
+ * @param nEvents Number of events to analyse
+ *
+ * @return The return value of AliAnalysisManager::StartAnalysis
+ */
+ virtual Long64_t Run(Long64_t nEvents=-1)
+ {
+ AliAnalysisManager* mgr = AliAnalysisManager::GetAnalysisManager();
+
+ if (nEvents < 0) nEvents = fChain->GetEntries();
+ return mgr->StartAnalysis(fUrl.GetProtocol(), fChain, nEvents);
+ }
+ /**
+ * @return URL help string
+ */
+ virtual const Char_t* UrlHelp() const
+ {
+ return "local://<datadir or list>[?<options>][#<treeName>]";
+ }
+ /**
+ * @return Short description
+ */
+ virtual const char* Desc() const { return "Local"; }
+ TChain* fChain; // Our chain
+};
+#endif
+//
+// EOF
+//
--- /dev/null
+/**
+ * @file MakeAODTrain.C
+ * @author Christian Holm Christensen <cholm@dalsgaard.hehi.nbi.dk>
+ * @date Tue Jul 12 10:05:30 2011
+ *
+ * @brief Run first pass analysis - make AOD tree
+ *
+ * @ingroup pwglf_forward_trains_specific
+ */
+#include "TrainSetup.C"
+
+//====================================================================
+/**
+ * Analysis train to make Forward and Central multiplicity
+ *
+ *
+ * @ingroup pwglf_forward_aod
+ * @ingroup pwglf_forward_trains_specific
+ */
+class MakeAODTrain : public TrainSetup
+{
+public:
+ /**
+ * Constructor.
+ *
+ * @param name Name of train (free form)
+ */
+ MakeAODTrain(const TString& name)
+ : TrainSetup(name)
+ {
+ fOptions.Add("sys", "SYSTEM", "1:pp, 2:PbPb, 3:pPb", "");
+ fOptions.Add("snn", "ENERGY", "Center of mass energy in GeV", "");
+ fOptions.Add("field", "STRENGTH","L3 field strength in kG", "");
+ fOptions.Add("cent", "Use centrality");
+ fOptions.Add("tpc-ep", "Use TPC event plane");
+ fOptions.Add("forward-config", "FILE", "Forward configuration",
+ "ForwardAODConfig.C");
+ fOptions.Add("central-config", "FILE", "Forward configuration",
+ "CentralAODConfig.C");
+ fOptions.Add("satelitte", "Use satelitte interactions");
+ fOptions.Set("type", "ESD");
+ }
+protected:
+ /**
+ * Create the tasks
+ *
+ * @param par Whether to use par files
+ * @param mgr Analysis manager
+ */
+ void CreateTasks(AliAnalysisManager* mgr)
+ {
+ // --- Output file name ------------------------------------------
+ AliAnalysisManager::SetCommonFileName("forward.root");
+
+ // --- Load libraries/pars ---------------------------------------
+ fHelper->LoadLibrary("PWGLFforward2");
+
+ // --- Set load path ---------------------------------------------
+ gROOT->SetMacroPath(Form("%s:$(ALICE_ROOT)/PWGLF/FORWARD/analysis2",
+ gROOT->GetMacroPath()));
+ gROOT->SetMacroPath(Form("%s:$(ALICE_ROOT)/ANALYSIS/macros",
+ gROOT->GetMacroPath()));
+
+ // --- Check if this is MC ---------------------------------------
+ Bool_t mc = mgr->GetMCtruthEventHandler() != 0;
+
+ // --- Add TPC eventplane task
+ if (fOptions.Has("tpc-ep")) gROOT->Macro("AddTaskEventplane.C");
+
+ // --- Task to copy header information ---------------------------
+ gROOT->Macro("AddTaskCopyHeader.C");
+
+ // --- Get options -----------------------------------------------
+ UShort_t sys = fOptions.AsInt("sys", 0);
+ UShort_t sNN = fOptions.AsInt("snn", 0);
+ UShort_t fld = fOptions.AsInt("field", 0);
+
+ // --- Add the task ----------------------------------------------
+ TString fwdConfig = fOptions.Get("forward-config");
+ gROOT->Macro(Form("AddTaskForwardMult.C(%d,%d,%d,%d,\"%s\")",
+ mc, sys, sNN, fld, fwdConfig.Data()));
+ fHelper->LoadAux(gSystem->Which(gROOT->GetMacroPath(), fwdConfig));
+
+ // --- Add the task ----------------------------------------------
+ TString cenConfig = fOptions.Get("central-config");
+ gROOT->Macro(Form("AddTaskCentralMult.C(%d,%d,%d,%d,\"%s\")",
+ mc, sys, sNN, fld, cenConfig.Data()));
+ fHelper->LoadAux(gSystem->Which(gROOT->GetMacroPath(), cenConfig));
+
+ // --- Add MC particle task --------------------------------------
+ if (mc) gROOT->Macro("AddTaskMCParticleFilter.C");
+
+ }
+ //__________________________________________________________________
+ /**
+ * Create physics selection , and add to manager
+ *
+ * @param mc Whether this is for MC
+ * @param mgr Manager
+ */
+ void CreatePhysicsSelection(Bool_t mc, AliAnalysisManager* mgr)
+ {
+ TrainSetup::CreatePhysicsSelection(mc, mgr);
+
+ // --- Get input event handler -----------------------------------
+ AliInputEventHandler* ih =
+ dynamic_cast<AliInputEventHandler*>(mgr->GetInputEventHandler());
+ if (!ih)
+ Fatal("CreatePhysicsSelection", "Couldn't get input handler (%p)", ih);
+
+ // --- Get Physics selection -------------------------------------
+ AliPhysicsSelection* ps =
+ dynamic_cast<AliPhysicsSelection*>(ih->GetEventSelection());
+ if (!ps)
+ Fatal("CreatePhysicsSelection", "Couldn't get PhysicsSelection (%p)",ps);
+
+ // --- Special for pPb pilot run Sep. 2012 -----------------------
+ UShort_t sys = fOptions.AsInt("sys", 0);
+ if (sys == 3) {
+ Warning("CreatePhysicsSelection",
+ "Special setup for pPb pilot run September, 2012");
+ gROOT->SetMacroPath(Form("%s:$(ALICE_ROOT)/ANALYSIS/macros",
+ gROOT->GetMacroPath()));
+ gROOT->LoadMacro("PhysicsSelectionOADB_CINT5_pA.C");
+ gROOT->ProcessLine(Form("((AliPhysicsSelection*)%p)"
+ "->SetCustomOADBObjects("
+ "OADBSelection_CINT5_V0A(),0);", ps));
+ ps->SetSkipTriggerClassSelection(true);
+ }
+ // --- Ignore trigger class when selecting events. This means ---
+ // --- that we get offline+(A,C,E) events too --------------------
+ // ps->SetSkipTriggerClassSelection(true);
+ }
+ //__________________________________________________________________
+ /**
+ * Create the centrality selection only if requested
+ *
+ * @param mc Monte-Carlo truth flag
+ * @param mgr Manager
+ */
+ void CreateCentralitySelection(Bool_t mc, AliAnalysisManager* mgr)
+ {
+ if (!fOptions.Has("cent")) return;
+ TrainSetup::CreateCentralitySelection(mc, mgr);
+ }
+ //__________________________________________________________________
+ const char* ClassName() const { return "MakeAODTrain"; }
+ //__________________________________________________________________
+ /**
+ * Overloaded to create new dNdeta.C and dndeta.sh in the output
+ * directory
+ *
+ * @param asShellScript
+ */
+ void SaveSetup(Bool_t asShellScript)
+ {
+ TrainSetup::SaveSetup(asShellScript);
+
+ TString cls("MakedNdetaTrain");
+ TString name(fName); name.Append("_dndeta");
+ OptionList opts(fOptions);
+ opts.Remove("forward-config");
+ opts.Remove("central-config");
+ opts.Remove("sys");
+ opts.Remove("snn");
+ opts.Remove("field");
+ opts.Remove("bare-ps");
+ opts.Remove("tpc-ep");
+ opts.Add("trig", "TRIGGER", "Trigger type", "");
+ opts.Add("vzMin", "CENTIMETER", "Lower bound on Ip Z", "-10");
+ opts.Add("vzMax", "CENTIMETER", "Upper bound on Ip Z", "+10");
+ opts.Add("scheme", "FLAGS", "Normalization scheme", "EVENT BACKGROUND");
+ opts.Add("cut-edges", "Cut edges of acceptance");
+ opts.Add("trigEff", "EFFICIENCY", "Trigger efficiency", "1");
+ opts.Add("trigEff0", "EFFICIENCY", "0-bin trigger efficiency", "1");
+ TString out = fHelper->OutputLocation();
+ if (out.IsNull()) out = fEscapedName;
+ opts.Set("url", out);
+ opts.Set("type", "AOD");
+ // opts.Show(std::cout);
+
+ SaveSetupROOT("dNdeta", cls, name, opts);
+ if (asShellScript)
+ SaveSetupShell("dndeta", cls, name, opts);
+ }
+};
+//
+// EOF
+//
--- /dev/null
+/**
+ * @file MakeFMDELossTrain.C
+ * @author Christian Holm Christensen <cholm@master.hehi.nbi.dk>
+ * @date Fri Jun 1 13:53:02 2012
+ *
+ * @brief
+ *
+ *
+ * @ingroup pwglf_forward_trains_specific
+ */
+#include "TrainSetup.C"
+
+//====================================================================
+/**
+ * Analysis train to do energy loss fits
+ *
+ * @ingroup pwglf_forward_trains_specific
+ * @ingroup pwglf_forward_eloss
+ */
+class MakeFMDELossTrain : public TrainSetup
+{
+public:
+ /**
+ * Constructor.
+ *
+ * @param name Name of train
+ */
+ MakeFMDELossTrain(const char* name = "FMD Energy Loss")
+ : TrainSetup(name)
+ {
+ fOptions.Add("cent", "Use centrality");
+ }
+protected:
+ //------------------------------------------------------------------
+ /**
+ * Create the analysis manager
+ *
+ * @param name Name of the analysis
+ *
+ * @return Created analysis manager
+ */
+ virtual AliAnalysisManager* CreateAnalysisManager(const char* name)
+ {
+ AliAnalysisManager* mgr = TrainSetup::CreateAnalysisManager(name);
+ // mgr->SetAutoBranchLoading(false);
+ return mgr;
+ }
+ //__________________________________________________________________
+ /**
+ * Create the tasks
+ *
+ * @param par Whether to use par files
+ * @param mgr Analysis manager
+ */
+ void CreateTasks(AliAnalysisManager* mgr)
+ {
+ // --- Output file name ------------------------------------------
+ AliAnalysisManager::SetCommonFileName("forward_eloss.root");
+
+ // --- Load libraries/pars ---------------------------------------
+ LoadLibrary("PWGLFforward2");
+
+ // --- Set load path ---------------------------------------------
+ gROOT->SetMacroPath(Form("%s:$(ALICE_ROOT)/PWGLF/FORWARD/analysis2",
+ gROOT->GetMacroPath()));
+
+ // --- Check if this is MC ---------------------------------------
+ Bool_t mc = mgr->GetMCtruthEventHandler() != 0;
+ Bool_t cent = fOptions.Has("cent");
+
+ // --- Add the task ----------------------------------------------
+ gROOT->Macro(Form("AddTaskFMDELoss.C(%d,%d)", mc, cent));
+ }
+ /**
+ * 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 (!fOptions.Has("cent")) return;
+
+ const char* name = "CentralitySelection";
+ gROOT->Macro("AddTaskCentrality.C");
+ AliCentralitySelectionTask* ctask =
+ dynamic_cast<AliCentralitySelectionTask*>(mgr->GetTask(name));
+ if (!ctask) return;
+ // ctask->SetPass(fESDPass);
+ if (mc) ctask->SetMCInput();
+ }
+ /**
+ * Crete output handler - we don't want one here.
+ *
+ * @return 0
+ */
+ AliVEventHandler* CreateOutputHandler(UShort_t) { return 0; }
+ //__________________________________________________________________
+ const char* ClassName() const { return "MakeFMDElossTrain"; }
+};
+
+//
+// EOF
+//
--- /dev/null
+/**
+ * @file MakeFMDEventPlaneTrain.C
+ * @author Christian Holm Christensen <cholm@master.hehi.nbi.dk>
+ * @date Fri Jun 1 13:52:39 2012
+ *
+ * @brief
+ *
+ *
+ * @ingroup pwglf_forward_trains_specific
+ */
+#include "TrainSetup.C"
+
+//====================================================================
+/**
+ * Analysis train to make @f$ \Psi_R@f$
+ *
+ *
+ * @ingroup pwglf_forward_flow
+ * @ingroup pwglf_forward_trains_specific
+ */
+class MakeFMDEventPlaneTrain : public TrainSetup
+{
+public:
+ /**
+ * Constructor.
+ *
+ * @param name Name of train (free form)
+ */
+ MakeFMDEventPlaneTrain(const char* name)
+ : TrainSetup(name)
+ {
+ fOptions.Set("type", "AOD");
+ }
+protected:
+ /**
+ * Create the tasks
+ *
+ * @param par Whether to use par files
+ */
+ void CreateTasks(AliAnalysisManager*)
+ {
+ // --- Output file name ------------------------------------------
+ AliAnalysisManager::SetCommonFileName("AnalysisResults.root");
+
+ // --- Load libraries/pars ---------------------------------------
+ LoadLibrary("PWGLFforward2)");
+
+ Bool_t mc = mgr->GetMCtruthEventHandler() != 0;
+
+ // --- Set load path ---------------------------------------------
+ gROOT->SetMacroPath(Form("%s:$(ALICE_ROOT)/PWGLF/FORWARD/analysis2:"
+ "$ALICE_ROOT/ANALYSIS/macros",
+ gROOT->GetMacroPath()));
+
+ // --- Add the task ----------------------------------------------
+ gROOT->Macro(Form("AddTaskFMDEventPlane.C(%d)", mc));
+ }
+ /**
+ * Do not the centrality selection
+ */
+ void CreateCentralitySelection(Bool_t, AliAnalysisManager*) {}
+ /**
+ * Crete output handler - we don't want one here.
+ *
+ * @return 0
+ */
+ AliVEventHandler* CreateOutputHandler(UShort_t) { return 0; }
+ //__________________________________________________________________
+ const char* ClassName() const { return "MakeFMDEventPlaneTrain"; }
+};
+//
+// EOF
+//
--- /dev/null
+/**
+ * @file MakeFlowTrain.C
+ * @author Christian Holm Christensen <cholm@master.hehi.nbi.dk>
+ * @date Fri Jun 1 13:51:48 2012
+ *
+ * @brief
+ *
+ * @ingroup pwglf_forward_trains_specific
+ *
+ */
+#include "TrainSetup.C"
+
+//====================================================================
+/**
+ * Analysis train to make @f$ flow@f$
+ *
+ *
+ * @ingroup pwglf_forward_flow
+ * @ingroup pwglf_forward_trains_specific
+ */
+class MakeFlowTrain : public TrainSetup
+{
+public:
+ /**
+ * Constructor. Date and time must be specified when running this
+ * in Termiante mode on Grid
+ *
+ * @param name Name of train (free form)
+ */
+ MakeFlowTrain(const char* name)
+ : TrainSetup(name),
+ fType("123456"),
+ fOutlierCutFMD(4.1),
+ fOutlierCutSPD(4.1),
+ fAddFlow(""),
+ fAddFType(0),
+ fAddFOrder(0)
+ {
+ fOptions.Add("mom", "MOMENTS", "Flow moments to determine", "123456");
+ fOptions.Add("outlier-fmd", "NSIGMA", "Cut on outliers in FMD", "4.1");
+ fOptions.Add("outlier-spd", "NSIGMA", "Cut on outliers in SPD", "4.1");
+ fOptions.Add("afterburner", "WHAT", "What to afterburn", "eta phi b pid");
+ fOptions.Add("ab-type", "1|2|3|4", "Type of afterburner", "");
+ fOptions.Add("ab-order", "1|2|3|4|5|6", "Order used by afterburner", "");
+ fOptions.Add("satelitte", "Whether to use satelitte interactions");
+ }
+protected:
+ //__________________________________________________________________
+ /**
+ * Create the tasks
+ *
+ * @param par Whether to use par files
+ */
+ void CreateTasks(AliAnalysisManager* mgr)
+ {
+ // --- Output file name ------------------------------------------
+ AliAnalysisManager::SetCommonFileName("AnalysisResults.root");
+
+ // --- Load libraries/pars ---------------------------------------
+ LoadLibrary("PWGLFforward2");
+
+ // --- Set load path ---------------------------------------------
+ gROOT->SetMacroPath(Form("%s:$(ALICE_ROOT)/PWGLF/FORWARD/analysis2",
+ gROOT->GetMacroPath()));
+
+ // --- Get the parameters ----------------------------------------
+ TString type = fOptions.Get("mom");
+ Bool_t mc = mgr->GetMCtruthEventHandler() != 0;
+ Bool_t satelitte = fOptions.Has("satelitte");
+ Double_t outlierFMD = fOptions.AsDouble("outlier-fmd");
+ Double_t outlierSPD = fOptions.AsDouble("outlier-spd");
+ TString afterburner = fOptions.Get("afterburner");
+ Int_t abType = fOptions.Get("ab-type");
+ Int_t abOrder = fOptions.Get("ab-order");
+
+ // --- Add the task ----------------------------------------------
+ gROOT->Macro(Form("AddTaskForwardFlow.C(\"%s\",%d,%d,%f,%f,\"%s\",%d,%d)",
+ type.Data(), mc, satelitte, outlierFMD, outlierSPD,
+ afterburner.Data(), abType, abOrder));
+ }
+ //__________________________________________________________________
+ /**
+ * Do not the centrality selection
+ */
+ void CreateCentralitySelection(Bool_t, AliAnalysisManager*) {}
+ //__________________________________________________________________
+ /**
+ * Crete output handler - we don't want one here.
+ *
+ * @return 0
+ */
+ AliVEventHandler* CreateOutputHandler(UShort_t) { return 0; }
+ //__________________________________________________________________
+ /**
+ * Create MC input handler. Since this train does not use the MC
+ * information from @c galice.root, @c Kinematics.root, and @c
+ * TrackRefs.root directly, we define this member function to return
+ * null even when doing MC analysis. This train _only_ looks at the
+ * AOD object of the _processed_ MC data.
+ *
+ * @return Always 0
+ */
+ AliVEventHandler* CreateMCHandler(UShort_t, bool) { return 0; }
+ //__________________________________________________________________
+ /**
+ * Get the class name of the train setup
+ *
+ * @return Class name
+ */
+ const char* ClassName() const { return "MakeFlowTrain"; }
+};
+//
+// EOF
+//
--- /dev/null
+#include "TrainSetup.C"
+/**
+ * @file MakeFullTrain.C
+ * @author Christian Holm Christensen <cholm@master.hehi.nbi.dk>
+ * @date Fri Jun 1 13:53:43 2012
+ *
+ * @brief
+ *
+ *
+ * @ingroup pwglf_forward_trains_specific
+ */
+
+//====================================================================
+/**
+ * Analysis train to make Forward and Central multiplicity, @f$
+ * dN/d\eta@f$, flow and @f$\Psi_R@f$ in one loop over the ESDs
+ *
+ * @ingroup pwglf_forward_aod
+ * @ingroup pwglf_forward_dndete
+ * @ingroup pwglf_forward_flow
+ * @ingroup pwglf_forward_trains_specific
+ */
+class MakeFullTrain : public TrainSetup
+{
+public:
+ /**
+ * Constructor. Date and time must be specified when running this
+ * in Termiante mode on Grid
+ *
+ * @param name Name of train (free form)
+ */
+ MakeFullTrain(const char* name)
+ : TrainSetup(name)
+ {
+ fOptions.Add("sys", "SYSTEM", "1:pp, 2:PbPb, 3:pPb", "");
+ fOptions.Add("snn", "ENERGY", "Center of mass energy in GeV", "");
+ fOptions.Add("field", "STRENGTH","L3 field strength in kG", "");
+ fOptions.Add("cent", "Use centrality");
+ fOptions.Add("tpc-ep", "Use TPC event plane");
+ fOptions.Add("forward-config", "FILE", "Forward configuration",
+ "ForwardAODConfig.C");
+ fOptions.Add("central-config", "FILE", "Forward configuration",
+ "CentralAODConfig.C");
+ fOptions.Add("satelitte", "Use satelitte interactions");
+ fOptions.Add("trig", "TYPE", "Trigger type", "INEL");
+ fOptions.Add("vzMin", "CENTIMETER", "Min Ip Z", "-10");
+ fOptions.Add("vzMax", "CENTIMETER", "Max Ip Z", "+10");
+ fOptions.Add("scheme", "SCHEME", "Normalization scheme", "");
+ fOptions.Add("trigEff", "EFFICENCY", "Trigger effeciency", "1");
+ fOptions.Add("trigEff0", "EFFICENCY", "0-bin trigger effeciency", "1");
+ fOptions.Add("cut-edges", "Cut acceptance edges");
+ fOptions.Add("mom", "MOMENTS", "Flow moments to determine", "123456");
+ fOptions.Add("outlier-fmd", "NSIGMA", "Cut on outliers in FMD", "4.1");
+ fOptions.Add("outlier-spd", "NSIGMA", "Cut on outliers in SPD", "4.1");
+ fOptions.Add("afterburner", "WHAT", "What to afterburn", "eta phi b pid");
+ fOptions.Add("ab-type", "1|2|3|4", "Type of afterburner", "");
+ fOptions.Add("ab-order", "1|2|3|4|5|6", "Order used by afterburner", "");
+
+ fOptions.Set("type", "ESD");
+ }
+protected:
+ /**
+ * Create the tasks
+ *
+ * @param par Whether to use par files
+ * @param mgr Analysis manager
+ */
+ void CreateTasks(AliAnalysisManager* mgr)
+ {
+ // --- Output file name ------------------------------------------
+ AliAnalysisManager::SetCommonFileName("forward.root");
+
+ // --- Load libraries/pars ---------------------------------------
+ LoadLibrary("PWGLFforward2");
+
+ // --- Set load path ---------------------------------------------
+ gROOT->SetMacroPath(Form("%s:$(ALICE_ROOT)/PWGLF/FORWARD/analysis2",
+ gROOT->GetMacroPath()));
+ gROOT->SetMacroPath(Form("%s:$(ALICE_ROOT)/ANALYSIS/macros",
+ gROOT->GetMacroPath()));
+
+ // --- Check if this is MC ---------------------------------------
+ Bool_t mc = mgr->GetMCtruthEventHandler() != 0;
+
+ // --- Add TPC eventplane task -----------------------------------
+ if (fOptions.Has("tpc-ep")) gROOT->Macro("AddTaskEventplane.C");
+
+ // --- Task to copy header information ---------------------------
+ gROOT->Macro("AddTaskCopyHeader.C");
+
+ // --- Get options -----------------------------------------------
+ UShort_t sys = fOptions.AsInt("sys", 0);
+ UShort_t sNN = fOptions.AsInt("snn", 0);
+ UShort_t fld = fOptions.AsInt("field", 0);
+
+ // --- Add the task ----------------------------------------------
+ TString fwdConfig = fOptions.Get("forward-config");
+ gROOT->Macro(Form("AddTaskForwardMult.C(%d,%d,%d,%d,\"%s\")",
+ mc, sys, sNN, fld, fwdConfig.Data()));
+ fHelper->LoadAux(gSystem->Which(gROOT->GetMacroPath(), fwdConfig));
+
+ // --- Add the task ----------------------------------------------
+ TString cenConfig = fOptions.Get("central-config");
+ gROOT->Macro(Form("AddTaskCentralMult.C(%d,%d,%d,%d,\"%s\")",
+ mc, sys, sNN, fld, cenConfig.Data()));
+ fHelper->LoadAux(gSystem->Which(gROOT->GetMacroPath(), cenConfig));
+
+ // --- Get parameters --------------------------------------------
+ TString trig = fOptions.Get("trig");
+ TString scheme = fOptions.Get("scheme");
+ Double_t vzMin = fOptions.AsDouble("vzmin", -10);
+ Double_t vzMax = fOptions.AsDouble("vzmax", +10);
+ Double_t effT = fOptions.AsDouble("trigEff", 1);
+ Double_t effT0 = fOptions.AsDouble("trigEff0", 1);
+ Bool_t cent = fOptions.Has("cent");
+ Bool_t edges = fOptions.Has("cut-edges");
+
+ // --- Add the task ----------------------------------------------
+ gROOT->Macro(Form("AddTaskForwarddNdeta.C(\"%s\",%f,%f,%d,\"%s\")",
+ trig.Data(), vzMin, vzMax, cent, scheme.Data(),
+ edges, trigEff, trigEff0));
+
+ gROOT->Macro(Form("AddTaskCentraldNdeta.C(\"%s\",%f,%f,%d,\"%s\")",
+ trig.Data(), vzMin, vzMax, cent, scheme.Data()),
+ edges, trigEff, trigEff0);
+
+ gROOT->Macro(Form("AddTaskMCTruthdNdeta.C(\"%s\",%f,%f,%d,\"%s\")",
+ trig.Data(), vzMin, vzMax, cent, scheme.Data()),
+ edges, trigEff, trigEff0);
+
+ // --- Add the task ----------------------------------------------
+ gROOT->Macro(Form("AddTaskFMDEventPlane.C(%d)", mc));
+
+ // --- Add MC particle task --------------------------------------
+ if (mc) gROOT->Macro("AddTaskMCParticleFilter.C");
+
+ // --- Get the parameters ----------------------------------------
+ TString type = fOptions.Get("mom");
+ Bool_t satelitte = fOptions.Has("satelitte");
+ Double_t outlierFMD = fOptions.AsDouble("outlier-fmd");
+ Double_t outlierSPD = fOptions.AsDouble("outlier-spd");
+ TString afterburner = fOptions.Get("afterburner");
+ Int_t abType = fOptions.Get("ab-type");
+ Int_t abOrder = fOptions.Get("ab-order");
+
+ // --- Add the task ----------------------------------------------
+ gROOT->Macro(Form("AddTaskForwardFlow.C(\"%s\",%d,%d,%f,%f,\"%s\",%d,%d)",
+ type.Data(), mc, satelitte, outlierFMD, outlierSPD,
+ afterburner.Data(), abType, abOrder));
+ }
+ //__________________________________________________________________
+ /**
+ * Create physics selection , and add to manager
+ *
+ * @param mc Whether this is for MC
+ * @param mgr Manager
+ */
+ void CreatePhysicsSelection(Bool_t mc,
+ AliAnalysisManager* mgr)
+ {
+ TrainSetup::CreatePhysicsSelection(mc, mgr);
+
+ // --- Get input event handler -----------------------------------
+ AliInputEventHandler* ih =
+ dynamic_cast<AliInputEventHandler*>(mgr->GetInputEventHandler());
+ if (!ih)
+ Fatal("CreatePhysicsSelection", "Couldn't get input handler (%p)", ih);
+
+ // --- Get Physics selection -------------------------------------
+ AliPhysicsSelection* ps =
+ dynamic_cast<AliPhysicsSelection*>(ih->GetEventSelection());
+ if (!ps)
+ Fatal("CreatePhysicsSelection", "Couldn't get PhysicsSelection (%p)",ps);
+
+ // --- Special for pPb pilot run Sep. 2012 -----------------------
+ UShort_t sys = fOptions.AsInt("sys", 0);
+ if (sys == 3) {
+ Warning("CreatePhysicsSelection",
+ "Special setup for pPb pilot run September, 2012");
+ gROOT->SetMacroPath(Form("%s:$(ALICE_ROOT)/ANALYSIS/macros",
+ gROOT->GetMacroPath()));
+ gROOT->LoadMacro("PhysicsSelectionOADB_CINT5_pA.C");
+ gROOT->ProcessLine(Form("((AliPhysicsSelection*)%p)"
+ "->SetCustomOADBObjects("
+ "OADBSelection_CINT5_V0A(),0);", ps));
+ ps->SetSkipTriggerClassSelection(true);
+ }
+ // --- Ignore trigger class when selecting events. This means ---
+ // --- that we get offline+(A,C,E) events too --------------------
+ // ps->SetSkipTriggerClassSelection(true);
+ }
+ //__________________________________________________________________
+ /**
+ * Create the centrality selection only if requested
+ *
+ * @param mc Monte-Carlo truth flag
+ * @param mgr Manager
+ */
+ void CreateCentralitySelection(Bool_t mc, AliAnalysisManager* mgr)
+ {
+ if (!fOptions.Has("cent")) return;
+ TrainSetup::CreateCentralitySelection(mc, mgr);
+ }
+ //__________________________________________________________________
+ const char* ClassName() const { return "MakeFullTrain"; }
+};
+//
+// EOF
+//
--- /dev/null
+/**
+ * @file MakeMCCorrTrain.C
+ * @author Christian Holm Christensen <cholm@master.hehi.nbi.dk>
+ * @date Fri Jun 1 13:54:47 2012
+ *
+ * @brief
+ *
+ * @ingroup pwglf_forward_trains_specific
+ */
+#include "TrainSetup.C"
+
+//====================================================================
+/**
+ * Analysis train to make Forward and Central MC corrections
+ *
+ *
+ * @ingroup pwglf_forward_mc
+ * @ingroup pwglf_forward_trains_specific
+ */
+class MakeMCCorrTrain : public TrainSetup
+{
+public:
+ /**
+ * Constructor. Date and time must be specified when running this
+ * in Termiante mode on Grid
+ *
+ * @param name Name of train (free form)
+ */
+ MakeMCCorrTrain(const char* name)
+ : TrainSetup(name)
+ {
+ fOptions.Set("type", "ESD");
+ }
+protected:
+ /**
+ * Create the tasks
+ *
+ * @param par Whether to use par files
+ * @param mgr Analysis manager
+ */
+ void CreateTasks(AliAnalysisManager* mgr)
+ {
+ // --- Output file name ------------------------------------------
+ AliAnalysisManager::SetCommonFileName("forward_mccorr.root");
+
+ // --- Load libraries/pars ---------------------------------------
+ LoadLibrary("PWGLFforward2");
+
+ // --- Set load path ---------------------------------------------
+ gROOT->SetMacroPath(Form("%s:$(ALICE_ROOT)/PWGLF/FORWARD/analysis2",
+ gROOT->GetMacroPath()));
+
+ // --- Check if this is MC ---------------------------------------
+ if (!mgr->GetMCtruthEventHandler()) return;
+
+ // --- Task to copy header information ---------------------------
+ gROOT->Macro("AddTaskCopyHeader.C");
+
+ // --- Add the task ----------------------------------------------
+ gROOT->Macro("AddTaskForwardMCCorr.C");
+
+ // --- Add the task ----------------------------------------------
+ gROOT->Macro("AddTaskCentralMCCorr.C");
+ }
+ //__________________________________________________________________
+ /**
+ * Create physics selection , and add to manager
+ *
+ * @param mc Whether this is for MC
+ * @param mgr Manager
+ */
+ void CreatePhysicsSelection(Bool_t mc,
+ AliAnalysisManager* mgr)
+ {
+ TrainSetup::CreatePhysicsSelection(mc, mgr);
+
+ // --- Get input event handler -----------------------------------
+ AliInputEventHandler* ih =
+ dynamic_cast<AliInputEventHandler*>(mgr->GetInputEventHandler());
+ if (!ih)
+ Fatal("CreatePhysicsSelection", "Couldn't get input handler (%p)", ih);
+
+ // --- Get Physics selection -------------------------------------
+ AliPhysicsSelection* ps =
+ dynamic_cast<AliPhysicsSelection*>(ih->GetEventSelection());
+ if (!ps)
+ Fatal("CreatePhysicsSelection", "Couldn't get PhysicsSelection (%p)", ps);
+
+ // --- Ignore trigger class when selecting events. This means ---
+ // --- that we get offline+(A,C,E) events too --------------------
+ // ps->SetSkipTriggerClassSelection(true);
+ }
+ /**
+ * Do not the centrality selection
+ */
+ // void CreateCentralitySelection(Bool_t, AliAnalysisManager*) {}
+ //__________________________________________________________________
+ const char* ClassName() const { return "MakeMCCorrTrain"; }
+};
+
+//
+// EOF
+//
--- /dev/null
+/**
+ * @file MakeQATrain.C
+ * @author Christian Holm Christensen <cholm@master.hehi.nbi.dk>
+ * @date Fri Jun 1 13:55:02 2012
+ *
+ * @brief
+ *
+ *
+ * @ingroup pwglf_forward_trains_specific
+ */
+#include "TrainSetup.C"
+
+//====================================================================
+/**
+ * Analysis train to do Quality assurance
+ *
+ * @ingroup pwglf_forward_trains_specific
+ * @ingroup pwglf_forward_qa
+ */
+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
+ */
+ MakeQATrain(const char* name = "Forward QA")
+ : TrainSetup(name)
+ {
+ fOptions.Add("cent", "Use centrality");
+ fOptions.Set("type", "ESD");
+ }
+protected:
+ //__________________________________________________________________
+ /**
+ * Create the tasks
+ *
+ * @param par Whether to use par files
+ * @param mgr Analysis manager
+ */
+ void CreateTasks(AliAnalysisManager* mgr)
+ {
+ // --- Output file name ------------------------------------------
+ AliAnalysisManager::SetCommonFileName("forward_qa.root");
+
+ // --- Load libraries/pars ---------------------------------------
+ LoadLibrary("PWGLFforward2");
+
+ // --- Set load path ---------------------------------------------
+ gROOT->SetMacroPath(Form("%s:$(ALICE_ROOT)/PWGLF/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, fOptions.Has("cent")));
+ }
+ /**
+ * 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 (!fOptions.Has("cent")) return;
+
+ gROOT->Macro("AddTaskCentrality.C");
+ const char* cname = "CentralitySelection";
+ AliCentralitySelectionTask* ctask =
+ dynamic_cast<AliCentralitySelectionTask*>(mgr->GetTask(cname));
+ if (!ctask) return;
+ // ctask->SetPass(fESDPass);
+ if (mc) ctask->SetMCInput();
+ }
+ /**
+ * Crete output handler - we don't want one here.
+ *
+ * @return 0
+ */
+ AliVEventHandler* CreateOutputHandler(UShort_t) { return 0; }
+ //__________________________________________________________________
+ const char* ClassName() const { return "MakeQATrain"; }
+};
+
+//
+// EOF
+//
--- /dev/null
+/**
+ * @file MakedNdetaTrain.C
+ * @author Christian Holm Christensen <cholm@master.hehi.nbi.dk>
+ * @date Fri Jun 1 13:51:26 2012
+ *
+ * @brief
+ *
+ * @ingroup pwglf_forward_trains_specific
+ *
+ */
+
+#include "TrainSetup.C"
+
+//====================================================================
+/**
+ * Analysis train to make @f$ dN/d\eta@f$
+ *
+ *
+ * @ingroup pwglf_forward_dndeta
+ * @ingroup pwglf_forward_trains_specific
+ */
+class MakedNdetaTrain : public TrainSetup
+{
+public:
+ /**
+ * Constructor.
+ *
+ * @param name Name of train (free form)
+ */
+ MakedNdetaTrain(const char* name)
+ : TrainSetup(name)
+ {
+ fOptions.Add("trig", "TYPE", "Trigger type", "INEL");
+ fOptions.Add("vzMin", "CENTIMETER", "Min Ip Z", "-10");
+ fOptions.Add("vzMax", "CENTIMETER", "Max Ip Z", "+10");
+ fOptions.Add("scheme", "SCHEME", "Normalization scheme", "");
+ fOptions.Add("trigEff", "EFFICENCY", "Trigger effeciency", "1");
+ fOptions.Add("trigEff0", "EFFICENCY", "0-bin trigger effeciency", "1");
+ fOptions.Add("cent", "Use centrality");
+ fOptions.Add("cut-edges", "Cut acceptance edges");
+ }
+protected:
+ /**
+ * Create the tasks
+ *
+ * @param par Whether to use par files
+ */
+ void CreateTasks(AliAnalysisManager*)
+ {
+ // --- Output file name ------------------------------------------
+ AliAnalysisManager::SetCommonFileName("forward_dndeta.root");
+
+ // --- Load libraries/pars ---------------------------------------
+ fHelper->LoadLibrary("PWGLFforward2");
+
+ // --- Set load path ---------------------------------------------
+ gROOT->SetMacroPath(Form("%s:$(ALICE_ROOT)/PWGLF/FORWARD/analysis2",
+ gROOT->GetMacroPath()));
+
+ // --- Get parameters --------------------------------------------
+ TString trig = fOptions.Get("trig");
+ TString scheme = fOptions.Get("scheme");
+ Double_t vzMin = fOptions.AsDouble("vzmin", -10);
+ Double_t vzMax = fOptions.AsDouble("vzmax", +10);
+ Double_t effT = fOptions.AsDouble("trigEff", 1);
+ Double_t effT0 = fOptions.AsDouble("trigEff0", 1);
+ Bool_t cent = fOptions.Has("cent");
+ Bool_t edges = fOptions.Has("cut-edges");
+
+ // --- Add the task ----------------------------------------------
+ gROOT->Macro(Form("AddTaskForwarddNdeta.C(\"%s\",%f,%f,%d,\"%s\",%d,%g,%g)",
+ trig.Data(), vzMin, vzMax, cent, scheme.Data(),
+ edges, effT, effT0));
+
+ gROOT->Macro(Form("AddTaskCentraldNdeta.C(\"%s\",%f,%f,%d,\"%s\",%d,%g,%g)",
+ trig.Data(), vzMin, vzMax, cent, scheme.Data(),
+ edges, effT, effT0));
+
+ gROOT->Macro(Form("AddTaskMCTruthdNdeta.C(\"%s\",%f,%f,%d,\"%s\",%d,%g,%g)",
+ trig.Data(), vzMin, vzMax, cent, scheme.Data(),
+ edges, effT, effT0));
+ }
+ //__________________________________________________________________
+ /**
+ * Do not the centrality selection
+ */
+ void CreateCentralitySelection(Bool_t, AliAnalysisManager*) {}
+ //__________________________________________________________________
+ /**
+ * Crete output handler - we don't want one here.
+ *
+ * @return 0
+ */
+ AliVEventHandler* CreateOutputHandler(UShort_t) { return 0; }
+ //__________________________________________________________________
+ const char* ClassName() const { return "MakedNdetaTrain"; }
+};
+//
+// EOF
+//
--- /dev/null
+// MyAnalysis.C
+#ifndef __CINT__
+# include <AliAnalysisManager.h>
+# include <AliESDEvent.h>
+# include <AliMultiplicity.h>
+# include <AliESDVertex.h>
+# include <TH1D.h>
+# include <TH2D.h>
+#else
+class TH1D;
+class TH2D;
+#endif
+#include <AliAnalysisTaskSE.h>
+class MyAnalysis : public AliAnalysisTaskSE
+{
+public:
+ MyAnalysis()
+ : AliAnalysisTaskSE(), fList(0), fMult(0), fVz(0)
+ {}
+ MyAnalysis(const char* name)
+ : AliAnalysisTaskSE(name), fList(0), fMult(0), fVz(0)
+ {
+ DefineOutput(1, TList::Class());
+ DefineOutput(2, TList::Class()); // For output from Terminate
+ fBranchNames = "AliMultiplicity.,SPDVertex.,PrimaryVertex.";
+ }
+ MyAnalysis(const MyAnalysis& o)
+ : AliAnalysisTaskSE(o), fList(o.fList), fMult(o.fMult), fVz(o.fVz)
+ {}
+ virtual ~MyAnalysis() {}
+ MyAnalysis& operator=(const MyAnalysis&) { return *this; }
+ virtual void UserCreateOutputObjects()
+ {
+ fList = new TList();
+ fList->SetName("Sums");
+ fList->SetOwner();
+
+ fMult = new TH2D("mult", "SPD tracklets", 80, -2, 2, 10, -10, 10);
+ fMult->SetXTitle("#eta");
+ fMult->SetYTitle("v_{z} [cm]");
+ fMult->Sumw2();
+ fMult->SetDirectory(0); // Disassociate from file
+
+ fVz = new TH1D("vz", "Interaction point", 10, -10, 10);
+ fVz->SetXTitle("v_{z} [cm]");
+ fVz->Sumw2();
+ fVz->SetDirectory(0); // Disassociate from file
+
+ fList->Add(fMult);
+ fList->Add(fVz);
+
+ PostData(1, fList);
+ }
+ virtual void UserExec(Option_t* )
+ {
+ AliESDEvent* event = dynamic_cast<AliESDEvent*>(InputEvent());
+ if (!event) return;
+ if (event->IsPileupFromSPD(3,0.8)) return;
+
+ const AliESDVertex* vtx = event->GetPrimaryVertexSPD();
+ if (!vtx || !vtx->GetStatus()) return;
+ if (vtx->IsFromVertexerZ() &&
+ (vtx->GetDispersion() > 0.2 || vtx->GetZRes() > 1.25 * 0.2))
+ return;
+
+ const AliMultiplicity* mult = event->GetMultiplicity();
+ if (!mult) return;
+
+ Double_t vz = vtx->GetZ();
+ fVz->Fill(vz);
+
+ Int_t nTracklets = mult->GetNumberOfTracklets();
+ for (Int_t i = 0; i < nTracklets; i++)
+ fMult->Fill(mult->GetEta(i), vz);
+
+ PostData(1, fList);
+ }
+ void Terminate(Option_t *)
+ {
+ TList* l = dynamic_cast<TList*>(GetOutputData(1));
+ if (!l) {
+ Warning("Terminate", "No out data # 1 found");
+ return;
+ }
+
+ TH2D* mult = static_cast<TH2D*>(l->FindObject("mult"));
+ TH1D* vz = static_cast<TH1D*>(l->FindObject("vz"));
+ if (!mult || !vz) {
+ Warning("Terminate", "Either 'mult' (%p) or 'vz' (%p) or both not found",
+ mult, vz);
+ return;
+ }
+
+ TList* output = new TList; // Needed for new output from Terminate
+ output->SetName("Results"); // 1st output re-opened read-only
+ output->SetOwner();
+
+ TH2D* out = static_cast<TH2D*>(mult->Clone("dndeta"));
+ out->SetTitle("dN_{ch}/d#eta from SPD tracklets per vertex bin");
+ out->SetZTitle("#frac{1}{N}#frac{dN_{ch}}{d#eta}");
+ out->SetDirectory(0); // Disassociate from file
+ Int_t nVz = mult->GetNbinsY();
+ Int_t nEta = mult->GetNbinsX();
+ for (Int_t iVz = 1; iVz <= nVz; iVz++) {
+ Double_t nEv = vz->GetBinContent(iVz);
+ Double_t e1 = vz->GetBinError(iVz);
+ Double_t sca = (nEv == 0 ? 0 : 1. / nEv);
+ for (Int_t iEta = 1; iEta <= nEta; iEta++) {
+ Double_t c = mult->GetBinContent(iEta,iVz);
+ Double_t e = mult->GetBinError(iEta,iVz);
+ Double_t ee = TMath::Sqrt(c*c * e1*e1 + nEv*nEv * e*e) * sca*sca;
+ out->SetBinContent(iEta, iVz, sca * c);
+ out->SetBinError(iEta, iVz, ee);
+ }
+ }
+ Double_t etaMin = mult->GetXaxis()->GetXmin();
+ Double_t etaMax = mult->GetXaxis()->GetXmax();
+ out->Scale(Double_t(nEta) / (etaMax-etaMin));
+
+ output->Add(out);
+ PostData(2, output);
+ }
+protected:
+ TList* fList;
+ TH2D* fMult;
+ TH1D* fVz;
+ ClassDef(MyAnalysis, 1);
+};
+//
+// EOF
+//
+
--- /dev/null
+#ifndef __CINT__
+# include <AliAnalysisManager.h>
+#else
+class AliAnalysisManager;
+#endif
+#include "TrainSetup.C"
+class MyTrain : public TrainSetup
+{
+public:
+ MyTrain(const char* name="myTest") : TrainSetup(name)
+ {
+ fOptions.Set("type", "ESD");
+ }
+ void CreateTasks(AliAnalysisManager* mgr)
+ {
+ if (!ParUtilities::MakeScriptPAR(fHelper::Mode() != Helper::kLocal,
+ "MyAnalysis.C",
+ "STEERBase,ESD,AOD,ANALYSIS,"
+ "OADB,ANALYSISalice"))
+ Fatal("CreateTasks", "Failed to create PAR file");
+ LoadLibrary("MyAnalysis");
+
+ Long_t r = gROOT->ProcessLine("new MyAnalysis(\"test\")");
+ AliAnalysisTaskSE* t = reinterpret_cast<AliAnalysisTaskSE*>(r);
+ if (!t) Fatal("CreateTasks", "Failed to make task");
+ mgr->AddTask(t);
+
+ AliAnalysisDataContainer* sums =
+ mgr->CreateContainer("Sums", TList::Class(),
+ AliAnalysisManager::kOutputContainer,
+ AliAnalysisManager::GetCommonFileName());
+ AliAnalysisDataContainer* results = // Needed for output from Terminate
+ mgr->CreateContainer("Results", TList::Class(),
+ AliAnalysisManager::kParamContainer, // Important!
+ AliAnalysisManager::GetCommonFileName());
+
+ mgr->ConnectOutput(t, 1, sums);
+ mgr->ConnectOutput(t, 2, results);
+ mgr->ConnectInput(t, 0, mgr->GetCommonInputContainer());
+ }
+ void CreateCentralitySelection(Bool_t, AliAnalysisManager*) {}
+ AliVEventHandler* CreateOutputHandler(UShort_t type) { return 0; }
+ const char* ClassName() const { return "MyTrain"; }
+};
+//
+// EOF
+//
--- /dev/null
+/**
+ * @file Option.C
+ * @author Christian Holm Christensen <cholm@master.hehi.nbi.dk>
+ * @date Tue Oct 16 18:59:04 2012
+ *
+ * @brief
+ *
+ *
+ * @ingroup pwglf_forward_trains_util
+ */
+#ifndef OPTION_C
+#define OPTION_C
+#include <TNamed.h>
+#include <iomanip>
+#ifndef __CINT__
+# include <TString.h>
+# include <TList.h>
+# include <TObjArray.h>
+# include <TObjString.h>
+# include <TMath.h>
+# include <iostream>
+# include <iomanip>
+# include <cstdarg>
+# include <cstdio>
+#else
+class TString;
+class TList;
+class TObjArray;
+#endif
+
+/**
+ * An option. The value is stored as a string
+ *
+ * @ingroup pwglf_forward_trains_util
+ */
+struct Option /* : public TNamed */
+{
+ /**
+ * Constructor
+ *
+ * @param name Name of option
+ * @param arg Dummy argument (possibly null)
+ * @param description Description
+ * @param value Default value
+ */
+ Option(const TString& name,
+ const TString& arg,
+ const TString& description,
+ const TString& value)
+ : fName(name), fDescription(description),
+ fValue(value), fArg(arg), fIsSet(false)
+ {}
+ /**
+ * Copy constructor
+ *
+ * @param other Object to copy from
+ */
+ Option(const Option& other)
+ : fName(other.fName),
+ fDescription(other.fDescription),
+ fValue(other.fValue),
+ fArg(other.fArg),
+ fIsSet(other.fIsSet)
+ {}
+ /**
+ * Assignment operator
+ *
+ * @param other Object to assign from
+ *
+ * @return Reference to this object
+ */
+ Option& operator=(const Option& other)
+ {
+ if (&other == this) return *this;
+
+ fName = other.fName;
+ fDescription = other.fDescription;
+ fValue = other.fValue;
+ fArg = other.fArg;
+ fIsSet = other.fIsSet;
+
+ return *this;
+ }
+ /**
+ * Set the value
+ *
+ * @param val New value
+ */
+ void Set(const TString& val) { fIsSet = true; fValue = val; }
+ /**
+ * Set the value
+ */
+ void Set()
+ {
+ if (HasArg()) {
+ Error("Option::Set", "Option %s needs an argument", fName.Data());
+ return;
+ }
+ Set("");
+ }
+ /**
+ * Reset the set flag
+ *
+ */
+ void Reset() { fIsSet = false; }
+ /**
+ * @return constant reference to value
+ */
+ const TString& Get() const { return fValue; }
+ /**
+ * @return true if this option was set externally
+ */
+ Bool_t IsSet() const { return fIsSet; }
+ /**
+ * @return true if this option needs an argument
+ */
+ Bool_t HasArg() const { return !fArg.IsNull(); }
+ /**
+ * @return value as a boolean value
+ */
+ Bool_t AsBool() const { return fIsSet; }
+ /**
+ * @return value as an integer value
+ */
+ Int_t AsInt() const { return fValue.Atoi(); }
+ /**
+ * @return value as a long integer value
+ */
+ Long64_t AsLong() const { return fValue.Atoll(); }
+ /**
+ * @return value as a double precision value
+ */
+ Double_t AsDouble() const { return fValue.Atof(); }
+ /**
+ * @return value as a C string
+ */
+ const char* AsString() const { return fValue.Data(); }
+ /**
+ * @return Width of the name
+ */
+ Int_t NameWidth() const { return fName.IsNull() ? 0 : fName.Length(); }
+ /**
+ * @return the width of the dummy argument
+ */
+ Int_t ArgWidth() const { return fArg.IsNull() ? 0 : fArg.Length(); }
+ /**
+ * Show help
+ *
+ * @param o Output stream
+ * @param w With of option plus argument
+ */
+ void Help(std::ostream& o, Int_t w=-1) const
+ {
+ TString tmp(fName);
+ if (HasArg()) {
+ tmp.Append("=");
+ tmp.Append(fArg);
+ }
+ if (w <= 0) w = NameWidth() + ArgWidth() + 1;
+ std::ios::fmtflags oldf = o.setf(std::ios::left);
+ o << std::setw(w) << tmp << " " << fDescription << " [";
+ if (!HasArg()) o << (IsSet() ? "true" : "false");
+ else o << fValue;
+ o << "]" << std::endl;
+ o.setf(oldf);
+ }
+ /**
+ * Show the option
+ *
+ * @param o Output stream
+ * @param w With of name
+ */
+ void Show(std::ostream& o, Int_t w=-1) const
+ {
+ if (w <= 0) w = NameWidth();
+ std::ios::fmtflags oldf = o.setf(std::ios::left);
+ o << std::setw(w) << fName << ": ";
+ if (!HasArg()) o << (IsSet() ? "true" : "false");
+ else o << fValue;
+ o << std::endl;
+ o.setf(oldf);
+ }
+ /**
+ * Store option and possible value
+ *
+ * @param o Output stream
+ */
+ void Store(std::ostream& o, bool quote=true) const
+ {
+ o << fName;
+ if (!HasArg()) return;
+ o << "=" << (quote ? "\"" : "") << fValue << (quote ? "\"" : "");
+ }
+ TString fName; // Name
+ TString fDescription; // Description
+ TString fValue; // Value
+ TString fArg; // Argument dummy
+ Bool_t fIsSet; // True if this option was set
+
+ // ClassDef(Option,1) // Option
+};
+
+/**
+ * A List of options
+ */
+struct OptionList
+{
+ // Linked list element
+ struct Link
+ {
+ Link* fPrev;
+ Link* fNext;
+ Option* fThis;
+ Link() : fPrev(0), fNext(0), fThis(0) {}
+ Link(Link* next, Option* opt)
+ : fPrev(next ? next->fPrev : 0), // Set previous
+ fNext(next), // Set next link
+ fThis(opt) // Set data
+ {
+ if (fPrev) fPrev->fNext = this; // Set forward link
+ if (fNext) fNext->fPrev = this; // Set previous link
+ }
+ ~Link() {
+ if (fPrev) fPrev->fNext = fNext;
+ if (fNext) fNext->fPrev = fPrev;
+ delete fThis;
+ }
+ };
+ /**
+ * Constructor
+ */
+ OptionList() : fList(0) { }
+ /**
+ * Copy constructor
+ *
+ * @param other Object to copy from
+ */
+ OptionList(const OptionList& other)
+ : fList(0)
+ {
+ // fList.SetOwner();
+ // TIter next(&other.fList);
+ // Option* o = 0;
+ // while ((o = static_cast<Option*>(next())))
+ // fList.Add(new Option(*o));
+ Copy(other);
+ }
+ /**
+ * Destructor
+ */
+ ~OptionList() { Delete(); }
+
+ /**
+ * Remove all options
+ */
+ void Delete()
+ {
+ Link* cur = fList;
+ while (cur) {
+ Link* tmp = cur->fNext;
+ delete cur;
+ cur = tmp;
+ // Remove(cur->fThis->fName);
+ // cur = tmp;
+ }
+ fList = 0;
+ }
+ /**
+ * Assignment operator
+ *
+ * @param other Object to assign from
+ *
+ * @return reference to this
+ */
+ OptionList& operator=(const OptionList& other)
+ {
+ if (&other == this) return *this;
+ Delete();
+ Copy(other);
+
+ return *this;
+ }
+ /**
+ * Copy list from other object
+ *
+ * @param other Object to copy from
+ */
+ void Copy(const OptionList& other)
+ {
+ Delete();
+ const Link* ocur = other.fList;
+ Link* cur = fList;
+ Link* prev = fList;
+ while (ocur) {
+ cur = new Link;
+ cur->fThis = new Option(*(ocur->fThis));
+ cur->fNext = 0;
+ cur->fPrev = prev;
+ if (fList == 0) fList = cur;
+ if (prev) prev->fNext = cur;
+ prev = cur;
+ ocur = ocur->fNext;
+ }
+ }
+ void DebugLink(const Link* link) const
+ {
+ std::cout << "Link=" << link;
+ if (link) {
+ std::cout << " prev=" << link->fPrev
+ << " next=" << link->fNext
+ << " obj=" << link->fThis;
+ if (link->fThis)
+ std::cout << " name=" << link->fThis->fName;
+ }
+ std::cout <<std::endl;
+ }
+ /**
+ * Find an optio by name
+ *
+ * @param name Name of option to find
+ *
+ * @return Pointer to option or null
+ */
+ Option* Find(const TString& name) const
+ {
+ const Link* cur = fList;
+ // DebugLink(cur);
+ while (cur && cur->fThis) {
+ if (name.EqualTo(cur->fThis->fName)) return cur->fThis;
+ cur = cur->fNext;
+ }
+ return 0;
+ }
+ /**
+ * Add an option with argument
+ *
+ * @param name Name of option
+ * @param arg Dummy argument
+ * @param desc Description
+ * @param val Default value
+ *
+ * @return Newly added option
+ */
+ Option* Add(const TString& name,
+ const TString& arg,
+ const TString& desc,
+ const TString& val)
+ {
+ Option* o = Find(name);
+ if (o) {
+ Warning("OptionList::Add", "Option %s already registered", name.Data());
+ return o;
+ }
+ o = new Option(name, arg, desc, val);
+ Link* cur = fList;
+ if (!cur) {
+ cur = new Link;
+ cur->fThis = o;
+ cur->fNext = 0;
+ cur->fPrev = 0;
+ fList = cur;
+ }
+ else {
+ Link* n = 0;
+ Link* l = 0;
+ while (cur) {
+ if (cur->fThis->fName.CompareTo(name) < 0) {
+ l = cur;
+ cur = cur->fNext;
+ continue;
+ }
+ n = new Link(cur, o);
+ if (cur == fList) fList = n;
+ break;
+ }
+ if (!n) {
+ n = new Link;
+ l->fNext = n;
+ n->fPrev = l;
+ n->fNext = 0;
+ n->fThis = o;
+ }
+ }
+ return o;
+ }
+ /**
+ * Add an option with no argument
+ *
+ * @param name Name of option
+ * @param desc Description
+ *
+ * @return Newly created option
+ */
+ Option* Add(const TString& name,
+ const TString& desc)
+ {
+ return Add(name, "", desc, "");
+ }
+ /**
+ * Remove an option
+ *
+ * @param name Name of option to remove
+ */
+ void Remove(const TString& name)
+ {
+ Link* cur = fList;
+ while (cur) {
+ if (!cur->fThis->fName.EqualTo(name)) {
+ cur = cur->fNext;
+ continue;
+ }
+ if (fList == cur) fList = cur->fNext;
+ delete cur;
+ break;
+ }
+ }
+ /**
+ * Check if a given option was set externally
+ *
+ * @param name Name of option
+ *
+ * @return true if option exists and was set externally
+ */
+ Bool_t Has(const TString& name) const
+ {
+ Option* o = Find(name);
+ return (o && o->IsSet());
+ }
+ /**
+ * Get the value of an option
+ *
+ * @param name Name of option
+ *
+ * @return Value of option, or empty string
+ */
+ const TString& Get(const TString& name) const
+ {
+ static TString null("");
+ Option* o = Find(name);
+ if (!o) return null;
+ return o->Get();
+ }
+ /**
+ * Get a value using a format statement. Remember argument(s) must
+ * be passed by address (as pointers)
+ *
+ * @param name Name of option @param format Format statement.
+ * Remeber, double and long needs the "l" modifier
+ *
+ * @return true on success
+ */
+ Bool_t GetF(const TString& name, const Char_t* format, ...) const
+ {
+ Option* o = Find(name);
+ if (!o) return false;
+
+ va_list ap;
+ va_start(ap, format);
+ int ret = vsscanf(o->fValue.Data(), format, ap);
+ va_end(ap);
+
+ return ret > 0;
+ }
+ /**
+ * Get value of an option as a boolean
+ *
+ * @param name Name of
+ *
+ * @return Value or false if not found
+ */
+ Bool_t AsBool(const TString& name) const
+ {
+ Option* o = Find(name);
+ if (!o) return false;
+ return o->AsBool();
+ }
+ /**
+ * Return value of an option as an integer
+ *
+ * @param name Name of option
+ * @param def Default value if options isn't found
+ *
+ * @return Value or default value
+ */
+ Int_t AsInt(const TString& name, Int_t def=0) const
+ {
+ Option* o = Find(name);
+ if (!o) return def;
+ return o->AsInt();
+ }
+ /**
+ * Return value of an option as an integer
+ *
+ * @param name Name of option
+ * @param def Default value if options isn't found
+ *
+ * @return Value or default value
+ */
+ Long64_t AsLong(const TString& name, Long64_t def=0) const
+ {
+ Option* o = Find(name);
+ if (!o) return def;
+ return o->AsLong();
+ }
+ /**
+ * Return value of an option as a double precision real number
+ *
+ * @param name Name of option
+ * @param def Default value if options isn't found
+ *
+ * @return Value or default value
+ */
+ Double_t AsDouble(const TString& name, Double_t def=0) const
+ {
+ Option* o = Find(name);
+ if (!o) return def;
+ return o->AsDouble();
+ }
+ /**
+ * Set value using a format statement
+ *
+ * @param name Name of option.
+ * @param format Format statement
+ */
+ void SetF(const TString& name, const Char_t* format, ...)
+ {
+ Option* o = Find(name);
+ if (!o) return;
+
+ static char buf[1024];
+ va_list ap;
+
+ va_start(ap, format);
+ vsnprintf(buf, 1023, format, ap);
+ buf[1023] = '\0';
+ va_end(ap);
+
+ o->Set(buf);
+ }
+ /**
+ * Set an option
+ *
+ * @param name Name of option
+ * @param value Value of option
+ */
+ void Set(const TString& name, const TString& value)
+ {
+ Option* o = Find(name);
+ if (!o) return;
+ o->Set(value);
+ }
+ /**
+ * Set a flag
+ *
+ * @param name Name of flag
+ */
+ void Set(const TString& name)
+ {
+ Option* o = Find(name);
+ if (!o) return;
+ o->Set();
+ }
+ /**
+ * Set long integer value
+ *
+ * @param name Name of option
+ * @param val Value
+ */
+ void Set(const TString& name, Int_t val, Bool_t asHex=false)
+ {
+ if (asHex) Set(name, Form("0x%x", val));
+ else Set(name, Form("%d", val));
+ }
+ /**
+ * Set long integer value
+ *
+ * @param name Name of option
+ * @param val Value
+ */
+ void Set(const TString& name, Long64_t val, Bool_t asHex=false)
+ {
+ ULong64_t uval = val;
+ if (asHex) Set(name, Form("0x%llx", uval));
+ else Set(name, Form("%lld", val));
+ }
+ /**
+ * Set double precision floating point value
+ *
+ * @param name Name of option
+ * @param val Value
+ */
+ void Set(const TString& name, Double_t val)
+ {
+ Set(name, Form("%lg", val));
+ }
+ /**
+ * Parse the options given in tmp
+ *
+ * @param tmp String to pass
+ * @param delims Delimiters
+ *
+ * @return true on success
+ */
+ Bool_t Parse(const TString& tmp, const TString& delims)
+ {
+ TObjArray* opts = tmp.Tokenize(delims);
+ // Info("OptionList::Parse", "Parsing options %s", tmp.Data());
+ Bool_t ret = Parse(opts);
+ opts->Delete();
+ return ret;
+ }
+ /**
+ * Parse options given in a collection
+ *
+ * @param opts List of arguments
+ *
+ * @return true on success
+ */
+ Bool_t Parse(const TCollection* opts, Bool_t ignoreUnknown=false)
+ {
+ // Info("OptionList::Parse", "List of options");
+ // opts->ls();
+ TIter next(opts);
+ TObjString* o = 0;
+ while ((o = static_cast<TObjString*>(next()))) {
+ TString& s = o->String();
+ TString key = s;
+ TString val = "";
+ Int_t eq = s.Index("=");
+ if (eq != kNPOS) {
+ key = s(0, eq);
+ val = s(eq+1, s.Length()-eq-1);
+ }
+
+ // Info("OptionList::Parse", "Looking for key=%s", key.Data());
+ Option* opt = Find(key);
+ if (!opt) {
+ if (!ignoreUnknown)
+ Warning("OptionList::Parse", "Unknown option: \"%s\"", s.Data());
+ continue;
+ }
+ if (opt->HasArg() && val.IsNull()) {
+ Warning("OptionList::Parse",
+ "Option %s needs an argument, using default %s",
+ key.Data(), opt->fValue.Data());
+ val = opt->fValue;
+ // return false;
+ }
+ opt->Set(val);
+ }
+ return true;
+ }
+ /**
+ * Find the widest name and dummy argument
+ *
+ * @param nWidth On return, the largest width of option names
+ * @param aWidth On return, the largest width of option dummy args
+ */
+ void Widest(Int_t& nWidth, Int_t& aWidth) const
+ {
+ nWidth = 0;
+ aWidth = 0;
+ const Link* cur = fList;
+ while (cur) {
+ Option* opt = cur->fThis;
+ nWidth = TMath::Max(nWidth, opt->NameWidth());
+ aWidth = TMath::Max(aWidth, opt->ArgWidth());
+ cur = cur->fNext;
+ }
+
+ // while ((opt = static_cast<Option*>(next()))) {
+ // }
+ }
+ /**
+ * Display option help
+ *
+ * @param o Output stream
+ * @param prefix Prefix for each option.
+ */
+ void Help(std::ostream& o, const char* prefix=" ") const
+ {
+ Int_t nWidth, aWidth;
+ Widest(nWidth, aWidth);
+ if (aWidth > 0) nWidth += aWidth+1;
+
+ const Link* cur = fList;
+ while (cur) {
+ Option* opt = cur->fThis;
+ o << prefix;
+ opt->Help(o, nWidth);
+ cur = cur->fNext;
+ }
+ }
+ /**
+ * Show the values of options
+ *
+ * @param o Output stream
+ * @param prefix Prefix for each option
+ */
+ void Show(std::ostream& o, const char* prefix=" ") const
+ {
+ Int_t nWidth, aWidth;
+ Widest(nWidth, aWidth);
+
+
+ const Link* cur = fList;
+ while (cur) {
+ Option* opt = cur->fThis;
+ o << prefix;
+ opt->Show(o, nWidth);
+ cur = cur->fNext;
+ }
+ }
+ /**
+ * Show the values of options
+ *
+ * @param o Output stream
+ * @param prefix Prefix for each option
+ */
+ void Store(std::ostream& o, const char* prefix="",
+ const char* delim=",", bool quote=true) const
+ {
+ Int_t nWidth, aWidth;
+ Widest(nWidth, aWidth);
+
+ const Link* cur = fList;
+ while (cur) {
+ Option* opt = cur->fThis;
+ if (!opt->HasArg() && !opt->IsSet()) {
+ cur = cur->fNext;
+ continue;
+ }
+ o << prefix;
+ opt->Store(o, quote);
+ o << delim;
+ cur = cur->fNext;
+ }
+ }
+ // Our linked list
+ Link* fList;
+
+ static void Test()
+ {
+ OptionList l;
+ l.Add("int", "NUMBER", "Integer", "42");
+ l.Add("float", "NUMBER", "Floating point", "3.14");
+ l.Add("bool", "Flag");
+ l.Add("hex", "NUMBER", "Hexadecimal", "0xdead");
+ l.Add("string", "STRING", "A string", "Hello, world");
+ l.Show(std::cout, "\t");
+
+ std::cout << "Find" << std::endl;
+ Option* b = l.Find("bool");
+ b->Show(std::cout);
+
+ std::cout << "SetF" << std::endl;
+ l.SetF("float", "%f", 2.17);
+ l.Show(std::cout, "\t");
+
+ std::cout << "GetF" << std::endl;
+ Float_t f;
+ l.GetF("float", "%f", &f);
+ std::cout << "\tf=" << f << std::endl;
+ std::cout << "Remove" << std::endl;
+ l.Remove("float");
+ l.Show(std::cout, "\t");
+
+ std::cout << "Set" << std::endl;
+ l.Set("int", "10");
+ l.Set("hex", 0xbeef, true);
+ l.Show(std::cout, "\t");
+
+ std::cout << "Copy" << std::endl;
+ OptionList c(l);
+ c.Show(std::cout, "\t");
+
+ std::cout << "End of test" << std::endl;
+ }
+ // TList fList;
+};
+
+#endif
+
--- /dev/null
+/**
+ * @defgroup pwglf_forward_trains_util Utilities for Train setups
+ *
+ * @ingroup pwglf_forward_trains
+ */
+/**
+ * @file OutputUtilities.C
+ * @author Christian Holm Christensen <cholm@master.hehi.nbi.dk>
+ * @date Tue Oct 16 17:55:32 2012
+ *
+ * @brief Special output handling
+ *
+ * @ingroup pwglf_forward_trains_util
+ */
+#ifndef TREEOUTPUTHELPER_C
+#define TREEOUTPUTHELPER_C
+#ifndef __CINT__
+# include <TString.h>
+# include <TError.h>
+# include <AliAnalysisManager.h>
+# include <AliAnalysisDataContainer.h>
+# include <AliVEventHandler.h>
+#else
+class TString;
+#endif
+
+// ===================================================================
+/**
+ * Special output handling - data sets and remote storage
+ *
+ * @ingroup pwglf_forward_trains_util
+ */
+struct OutputUtilities
+{
+ /**
+ * Register output data set
+ *
+ * @param dsname Data set name
+ *
+ * @return true on success
+ */
+ static Bool_t RegisterDataset(const TString& dsname)
+ {
+ // Get the manager
+ AliAnalysisManager* mgr = AliAnalysisManager::GetAnalysisManager();
+
+ // If we are asked to make a data-set, get the output handler and
+ // common output container.
+ AliVEventHandler* handler = mgr->GetOutputEventHandler();
+ if (!handler) return true;
+
+ // Get the container
+ AliAnalysisDataContainer* cont = mgr->GetCommonOutputContainer();
+ if (!cont) {
+ Warning("OutputUtilities::RegisterDataset",
+ "No common output container defined");
+ return false;
+ }
+
+ // Make the name
+ TString nme(dsname);
+ if (nme.IsNull()) nme = mgr->GetName();
+ if (nme.IsNull()) {
+ Error("OutputUtilities::RegisterDataset", "No data set name specified");
+ return false;
+ }
+
+ // Flag for data-set creation
+ cont->SetRegisterDataset(true);
+
+ handler->SetOutputFileName(nme);
+ // cont->SetFileName(nme);
+
+ TString base(handler->GetOutputFileName());
+ base.ReplaceAll(".root","");
+ Info("OutputUtilities::RegisterDataset",
+ "Will register tree output AODs (%s%s) as dataset",
+ base.Data(), cont->GetTitle());
+
+ return true;
+ }
+ /**
+ * Get the name of the registered data set
+ *
+ *
+ * @return Name of the registered data set
+ */
+ static TString RegisteredDataset()
+ {
+ TString ret;
+
+ AliAnalysisManager* mgr = AliAnalysisManager::GetAnalysisManager();
+ AliVEventHandler* oh = mgr->GetOutputEventHandler();
+ if (!oh) {
+ Warning("OutputUtilities::GetOutputDataSet",
+ "No outout event handler defined");
+ return ret;
+ }
+ AliAnalysisDataContainer* co = mgr->GetCommonOutputContainer();
+ if (!co) {
+ Warning("OutputUtilities::GetOutputDataSet",
+ "No common output container defined");
+ return ret;
+ }
+ if (!co->IsRegisterDataset()) {
+ Info("OutputUtilities::GetOutputDataSet",
+ "Common output is not registered as dataset");
+ return ret;
+ }
+ ret = oh->GetOutputFileName();
+ // ret.ReplaceAll("TTree", "");
+ ret.ReplaceAll(".root", "");
+ // ret.Append(co->GetTitle());
+
+ return ret;
+ }
+ /**
+ * Register special putput storage
+ *
+ * @param url Url (root://host/full_path)
+ *
+ * @return true on success
+ */
+ static Bool_t RegisterStorage(const TString& url)
+ {
+ if (url.IsNull()) {
+ Error("OutputUtilities::RegisterStorage", "No storage URI specified");
+ return false;
+ }
+
+ // Get the manager
+ AliAnalysisManager* mgr = AliAnalysisManager::GetAnalysisManager();
+
+ // Get the container
+ AliAnalysisDataContainer* cont = mgr->GetCommonOutputContainer();
+ if (!cont) {
+ Warning("OutputUtilities::RegisterStorage",
+ "No common output container defined");
+ return false;
+ }
+
+ cont->SetSpecialOutput();
+ mgr->SetSpecialOutputLocation(url);
+
+ return true;
+ }
+};
+#endif
+//
+// EOF
+//
--- /dev/null
+/**
+ * @file ParUtilities.C
+ * @author Christian Holm Christensen <cholm@master.hehi.nbi.dk>
+ * @date Tue Oct 16 17:51:10 2012
+ *
+ * @brief PAR file utilities
+ *
+ * @ingroup pwglf_forward_trains_util
+ *
+ */
+#ifndef PARHELPER_C
+#define PARHELPER_C
+#ifndef __CINT__
+# include <TString.h>
+# include <TProof.h>
+# include <TSystem.h>
+# include <TError.h>
+# include <TFile.h>
+# include <TSystem.h>
+# include <TROOT.h>
+# include <fstream>
+# include <cstdlib>
+#else
+class TString;
+#endif
+
+// ===================================================================
+/**
+ * Helper to set-up and load PARs
+ *
+ * @ingroup pwglf_forward_trains_util
+ */
+struct ParUtilities
+{
+ /**
+ * Find PAR file (either in current or parent directory or directly
+ * in $ALICE_ROOT), and copy/link here
+ *
+ * @param what PAR file name (sans .par)
+ *
+ * @return true on success
+ */
+ static Bool_t Find(const TString& what)
+ {
+ if (what.IsNull()) return false;
+
+ TString parFile(what);
+ if (!parFile.EndsWith(".par")) parFile.Append(".par");
+ if (gSystem->AccessPathName(parFile.Data())) {
+ // If not found
+ if (gSystem->AccessPathName(Form("../%s.par", parFile.Data()))) {
+ // If not found
+ TString aliParFile =
+ gSystem->ExpandPathName(Form("$(ALICE_ROOT)/%s", parFile.Data()));
+ if (gSystem->AccessPathName(aliParFile.Data())) {
+ Error("ParUtilities::Find",
+ "PAR file %s not found in current or parent "
+ "directory nor in $(ALICE_ROOT)", parFile.Data());
+ return false;
+ }
+ // Copy to current directory
+ TFile::Cp(aliParFile, parFile);
+ }
+ else
+ gSystem->Exec(Form("ln -s %s .", parFile.Data()));
+ }
+ return true;
+ }
+ static Bool_t Load(const TString& name)
+ {
+ if (name.IsNull()) return true;
+ if (!gProof) {
+ Error("ParUtilities::Load", "No connection to a Proof cluster");
+ return false;
+ }
+
+ // Load par library
+ TString fn(name);
+ Info("ParUtilities::LoadLibrary", "Uploading %s", name.Data());
+
+ // First check in current directory
+ Int_t ret = gProof->UploadPackage(fn, TProof::kRemoveOld);
+
+ if (ret < 0) {
+ // IF not found there, then check parent directory
+ fn.Prepend("../");
+ gSystem->ExpandPathName(fn);
+ ret = gProof->UploadPackage(fn);
+ }
+
+ if (ret < 0) {
+ // If not found in current or parent directory, try the
+ // the ALICE_ROOT directory
+ fn = Form("$ALICE_ROOT/%s.par", name.Data());
+ gSystem->ExpandPathName(fn);
+ ret = gProof->UploadPackage(fn);
+ }
+
+ if (ret < 0) {
+ // IF not found, bark
+ Error("ParUtilities::Load",
+ "Could not find module %s.par in current or parent directory "
+ "nor in $ALICE_ROOT", name.Data());
+ return false;
+ }
+
+ ret = gProof->EnablePackage(name);
+ Info("ParUtilities::Load", "Enabled package %s (from %s)",
+ name.Data(), fn.Data());
+
+ return true;
+ }
+ /**
+ * Unpack, build, and load a PAR file.
+ *
+ * @param what Which PAR file
+ *
+ * @return
+ */
+ static Bool_t Build(const TString& what)
+ {
+ if (what.IsNull()) return false;
+
+ TString parFile(what);
+ if (!parFile.EndsWith(".par")) parFile.Append(".par");
+
+ // Extract archive
+ gSystem->Exec(Form("tar xzf %s", parFile.Data()));
+
+ // Change directory into par archive
+ TString cwd = gSystem->WorkingDirectory();
+
+ TString dir(what);
+ if (dir.EndsWith(".par")) dir.ReplaceAll(".par", "");
+ if (!gSystem->ChangeDirectory(dir)) {
+ Error("ParUtilities::Setup", "Failed to change directory to %s",
+ dir.Data());
+ return false;
+ }
+
+ // Test the build
+ if (!gSystem->AccessPathName("PROOF-INF/BUILD.sh")) {
+ Info("ParUtilities::Setup", "Building in PAR archive %s", parFile.Data());
+ if (gSystem->Exec("PROOF-INF/BUILD.sh")) {
+ Error("ParUtilities::Setup", "Failed to build in PAR directory %s",
+ dir.Data());
+ gSystem->ChangeDirectory(cwd.Data());
+ return false;
+ }
+ }
+
+ // Check for setup script
+ if (!gSystem->AccessPathName("PROOF-INF/SETUP.C")) {
+ // Info("ParUtilities::SetupPAR", "Setting up for PAR %s", what);
+ gROOT->Macro("PROOF-INF/SETUP.C");
+ }
+ if (!gSystem->ChangeDirectory(cwd.Data())) return false;
+
+ return true;
+ }
+ //__________________________________________________________________
+ /**
+ * @{
+ * @name PAR generation from script
+ */
+ /**
+ * Service function to make a PAR out of a script.
+ *
+ * The script should contain can contain a sub-class of AliAnalysisTask.
+ * The script will be compiled on the slaves before loading the
+ * AliAnalysisManager. Parts to (not) be compiled can be protected like
+ *
+ * @code
+ * #ifdef BUILD_PAR
+ * // This will _only_ be compiled in the servers
+ * #endif
+ * #ifndef BUILD_PAR
+ * // This will not be compiled in the servers
+ * #endif
+ * @endcode
+ *
+ * @param mode Execution mode (Grid, PROOF, Local)
+ * @param script Script to upload and compile in the PAR
+ * @param deps Dependency pars
+ *
+ * @return true on success.
+ */
+ static Bool_t MakeScriptPAR(Bool_t isLocal,
+ const TString& script,
+ const TString& deps)
+ {
+ // --- In local mode, just AcLic and load ------------------------
+ if (isLocal) {
+ if (gROOT->LoadMacro(Form("%s++g", script.Data())) < 0)
+ return false;
+ return true;
+ }
+
+ // --- Get the base name -----------------------------------------
+ Info("ParUtilities::MakeScriptPAR", "Making par file for %s",
+ script.Data());
+ TString base(gSystem->BaseName(script));
+ Int_t idx = base.Last('.');
+ if (idx != kNPOS) base.Remove(idx);
+
+ // --- Check name of script file ---------------------------------
+ TString scr(script);
+ TString ext;
+ if (script.EndsWith(".C")) ext = "C";
+ else if (script.EndsWith(".cxx")) ext = "cxx";
+ else { ext = "C"; scr.Append(".C"); }
+
+ // --- Check if we can access the file ---------------------------
+ TString path = TString::Format(".:%s", TROOT::GetMacroPath());
+ char* loc = gSystem->Which(path, scr);
+ if (!loc) {
+ Error("ParUtilities::MakeScriptPAR",
+ "Script %s not found in %s", scr.Data(), path.Data());
+ return false;
+ }
+ TString full(loc);
+
+ // --- Create our temporary directory ----------------------------
+ TString tmpdir(gSystem->TempDirectory());
+ int ltempl = tmpdir.Length() + 1 + 5 + 6 + 1;
+ char* templ = new char[ltempl];
+ snprintf(templ, ltempl, "%s/trainXXXXXX", tmpdir.Data());
+ if (!mkdtemp(templ)) {
+ Error("ParUtilities::MakeScriptPAR",
+ "Failed to generate temporary directory from template %s",
+ templ);
+ return false;
+ }
+
+ Bool_t retVal = false;
+ try {
+ // --- Make directories for package ------------------------------
+ TString dir = TString::Format("%s/%s", templ, base.Data());
+ // Set-up directories
+ if (gSystem->MakeDirectory(dir) < 0)
+ throw TString::Format("Could not make directory '%s'", base.Data());
+ if (gSystem->MakeDirectory(Form("%s/PROOF-INF", dir.Data())))
+ throw TString::Format("Could not make directory %s/PROOF-INF",
+ base.Data());
+
+ // --- Copy the script to the setup directory --------------------
+ TString dest = TString::Format("%s/%s.%s", dir.Data(),
+ base.Data(), ext.Data());
+ Int_t ret = gSystem->CopyFile(full, dest, true);
+ switch (ret) {
+ case -1: throw TString::Format("Couldn't open %s for copy", scr.Data());
+ case -2: throw TString::Format("File %s exists", dest.Data());
+ case -3: throw TString::Format("Error while copying %s", scr.Data());
+ }
+
+ // --- Make scripts, etc. ----------------------------------------
+ TObjArray* depList = deps.Tokenize(", ");
+ if (!MakeBuildScript(dir, base))
+ throw TString::Format("Failed to make build script");
+ if (!MakeUtilityScript(dir))
+ throw TString::Format("Failed to make utility script");
+ if (!MakeBuildMacro(dir, base, ext, depList))
+ throw TString::Format("Failed to make build macro");
+ if (!MakeSetupMacro(dir, base, ext, depList))
+ throw TString::Format("Failed to setup macro");
+
+ // --- Pack up the archive ---------------------------------------
+ ret = gSystem->Exec(Form("(cd %s && tar -czf %s.par %s)",
+ templ, base.Data(),base.Data()));
+ if (ret != 0)
+ throw TString::Format("Failed to create PAR file %s.PAR from %s",
+ base.Data(), dir.Data());
+
+ // --- Move PAR file to here -------------------------------------
+ ret = gSystem->Exec(Form("mv -f %s/%s.par %s.par", templ, base.Data(),
+ base.Data()));
+ if (ret != 0)
+ throw TString::Format("Failed to rename %s/%s.par to %s.par: %s",
+ templ, base.Data(), base.Data(),
+ gSystem->GetError());
+ retVal = true;
+ }
+ catch (TString& e) {
+ Error("ParUtilities::MakeScriptPAR", e.Data());
+ retVal = false;
+ }
+
+ // --- Remove temporary directory --------------------------------
+ gSystem->Exec(Form("rm -rf %s", templ));
+
+ return retVal;
+ }
+ /**
+ * Write a build script
+ *
+ * @param dir Directory to put it in
+ *
+ * @return true on success
+ */
+ static Bool_t MakeBuildScript(const TString& dir,
+ const TString& base)
+ {
+ // Make our build file
+ std::ofstream out(Form("%s/PROOF-INF/BUILD.sh", dir.Data()));
+ if (!out) {
+ Error("ParUtilities::MakeBuildScript", "Failed to open out shell script");
+ return false;
+ }
+ out << "#!/bin/sh\n"
+ << "if test x$ALICE_ROOT != x ; then\n"
+ << " if test x$ALICE_TARGET = x ; then\n"
+ << " export ALICE_TARGET=`$ROOTSYS/bin/root-config --arch`\n"
+ << " fi\n"
+ << " export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:"
+ << "${ALICE_ROOT}/lib/tgt_${ALICE_TARGET}\n"
+ << "fi\n"
+ << "echo BUILD.sh@`hostname`: Building " << base << "\n"
+ << "root.exe -l -out -q PROOF-INF/BUILD.C 2>&1 | tee "
+ << base << ".log\n"
+ << "echo BUILD.sh@`hostname`: done: $?\n"
+ << std::endl;
+ out.close();
+ if (gSystem->Chmod(Form("%s/PROOF-INF/BUILD.sh", dir.Data()), 0755) != 0) {
+ Error("ParUtilities::MakeBuildScript",
+ "Failed to set exectuable flags on %s/PROOF-INF/BUILD.sh",
+ dir.Data());
+ return false;
+ }
+ return true;
+ }
+ /**
+ * Write a build macro
+ *
+ * @param dir Directory to put macro in
+ * @param deps Dependencies
+ * @param base Base name of script to compile
+ *
+ * @return true on success
+ */
+ static Bool_t MakeBuildMacro(const TString& dir,
+ const TString& base,
+ const TString& ext,
+ const TCollection* deps) {
+ std::ofstream out(Form("%s/PROOF-INF/BUILD.C", dir.Data()));
+ if (!out) {
+ Error("ParUtilities::MakeBuildMacro", "Failed to open build script");
+ return false;
+ }
+ out << "void BUILD() {\n"
+ << " gSystem->AddIncludePath(\"-DBUILD_PAR=1\");\n"
+ << " gROOT->LoadMacro(\"PROOF-INF/UTIL.C\");\n"
+ << " LoadROOTLibs();\n"
+ << " AddAliROOT();\n";
+ if (deps) {
+ TIter next(deps);
+ TObject* dep = 0;
+ while ((dep = next())) {
+ out << " AddDep(\"" << dep->GetName() << "\");\t"
+ << " LoadDep(\"" << dep->GetName() << "\");\n";
+ }
+ }
+ out << " // gDebug = 5;\n"
+ << " int ret = gROOT->LoadMacro(\""
+ << base << "." << ext << "++g\");\n"
+ << " if (ret != 0) Fatal(\"BUILD\",\"Failed to build\");\n"
+ << " // else Info(\"BUILD\", \"Made " << base << "\");\n"
+ << "}\n"
+ << std::endl;
+ out.close();
+
+ return true;
+ }
+ /**
+ * Make a utility macro
+ *
+ * @param dir Directory to put the macro in
+ *
+ * @return true on success
+ */
+ static Bool_t MakeUtilityScript(const TString& dir)
+ {
+ std::ofstream out(Form("%s/PROOF-INF/UTIL.C", dir.Data()));
+ if (!out) {
+ Error("ParUtilities::MakeUtilityScript", "Failed to open utility script");
+ return false;
+ }
+ out << "void LoadROOTLibs() {\n"
+ << " gSystem->Load(\"libVMC\");\n"
+ << " gSystem->Load(\"libNet\");\n"
+ << " gSystem->Load(\"libTree\");\n"
+ << " gSystem->Load(\"libPhysics\");\n"
+ << " gSystem->Load(\"libMinuit\");\n"
+ << "}\n\n"
+ << "void AddAliROOT() {\n"
+ << " TString val(gSystem->Getenv(\"ALICE_ROOT\"));\n"
+ << " if (val.IsNull())\n"
+ << " Warning(\"Add\",\"ALICE_ROOT not defined\");\n"
+ << " else\n"
+ << " gSystem->AddIncludePath(Form(\"-I%s/include\",val.Data()));\n"
+ << "}\n\n"
+ << "void AddDep(const char* env) {\n"
+ << " TString val(gSystem->Getenv(Form(\"%s_INCLUDE\",env)));\n"
+ << " if (val.IsNull())\n"
+ << " Warning(\"Add\",\"%s_INCLUDE not defined\", env);\n"
+ << " else {\n"
+ << " gSystem->AddIncludePath(Form(\"-I../%s\",val.Data()));\n"
+ << " }\n"
+ << "}\n\n"
+ << "void LoadDep(const char* name) {\n"
+ << " gSystem->AddDynamicPath(Form(\"../%s\",name));\n"
+ << " char* full = gSystem->DynamicPathName(name,true);\n"
+ << " if (!full) \n"
+ << " full = gSystem->DynamicPathName(Form(\"lib%s\",name),true);\n"
+ << " if (!full) \n"
+ << " full = gSystem->DynamicPathName(Form(\"lib%s.so\",name),true);\n"
+ << " if (!full) {\n"
+ << " Warning(\"LoadDep\",\"Module %s not found\", name);\n"
+ << " return;\n"
+ << " }\n"
+ << " gSystem->Load(full);\n"
+ << "}\n"
+ << std::endl;
+ out.close();
+ return true;
+ }
+ /**
+ * Make a setup script
+ *
+ * @param dir Directory to put it in
+ * @param base Base name of target script
+ * @param ext Extension of target script
+ * @param deps Dependencies
+ *
+ * @return true on success
+ */
+ static Bool_t MakeSetupMacro(const TString& dir,
+ const TString& base,
+ const TString& ext,
+ const TCollection* deps)
+ {
+ // Make our set-up script
+ std::ofstream out(Form("%s/PROOF-INF/SETUP.C", dir.Data()));
+ if (!out) {
+ Error("ParUtilities::MakeSetupMacro", "Failed to open setup script");
+ return false;
+ }
+ out << "void SETUP() {\n"
+ << " gROOT->LoadMacro(\"PROOF-INF/UTIL.C\");\n"
+ << " LoadROOTLibs();\n"
+ << " // Info(\"SETUP\",\"Loading libraries\");\n";
+ if (deps) {
+ TIter next(deps);
+ TObject* dep = 0;
+ while ((dep = next()))
+ out << " LoadDep(\"" << dep->GetName() << "\");\n";
+ }
+ out << " // gDebug = 5;\n"
+ << " // Info(\"SETUP\",\"Loading " << base <<"_"<< ext << ".so\");\n"
+ << " gSystem->Load(\"" << base << "_" << ext << ".so\");\n"
+ << " // gDebug = 0;\n"
+ << " gROOT->ProcessLine(\".include " << base << "\");\n"
+ << " gSystem->Setenv(\"" << base << "_INCLUDE\",\""
+ << base << "\");\n"
+ << " // Info(\"SETUP\", \"Done\");\n"
+ << "}\n"
+ << std::endl;
+ out.close();
+ return true;
+ }
+ /* @} */
+};
+#endif
+//
+// EOF
+//
--- /dev/null
+/**
+ * @file PluginHelper.C
+ * @author Christian Holm Christensen <cholm@master.hehi.nbi.dk>
+ * @date Tue Oct 16 18:57:18 2012
+ *
+ * @brief Base class for helpers using the AliAnalysisAlien plugin
+ *
+ * @ingroup pwglf_forward_trains_helper
+ *
+ */
+#ifndef PLUGINHELPER_C
+#define PLUGINHELPER_C
+#include "Helper.C"
+#ifndef __CINT__
+# include "AvailableSoftware.C"
+# include "ParUtilities.C"
+# include "OutputUtilities.C"
+# include <TUrl.h>
+# include <TString.h>
+# include <TEnv.h>
+# include <TProof.h>
+# include <AliAnalysisManager.h>
+# include <AliAnalysisAlien.h>
+#else
+class TUrl;
+class AliAnalysisAlien;
+#endif
+
+// ===================================================================
+/**
+ * Handle analysis on using the AliAnalysisAlien plugin - i.e., AAF or Grid
+ *
+ * This helper is triggered by a URL of the form
+ *
+ * @code
+ * <protocol>://[<user>@][<host>][:<port>]/[<file>][?<options>][#<anchor>]
+ * @endcode
+ * where <options> contains <tt>plugin</tt>
+ * <dl>
+ * <dt><options@gt;</dt>
+ * <dd>List of options separated by an &
+ * <dl>
+ * <dt><tt>storage=<url></tt></dt>
+ * <dd>Specify a non-default storage location for special output
+ * (e.g., AOD trees). <url> should be a valid XRootd
+ * server URI accessible to the slaves - e.g.,
+ * <tt>root://lxplus.cern.ch:10930//tmp</tt>.</dd>
+ * <dt><tt>mode=[default,rec,sim,train,custom]</tt></dt>
+ * <dd>Set the AliROOT mode. If not specified <tt>default</tt>
+ * is assumed</tt>. See also CreateAliROOTPar</dd>
+ * <dt><tt>par</tt></dt>
+ * <dd>Use par files</dd>
+ * <dt><tt>aliroot=<version></tt></dt>
+ * <dd>Set AliROOT version to use </dd>
+ * <dt><tt>root=<version></tt></dt>
+ * <dd>Set ROOT version to use </dd>
+ * </dl>
+ * </dd>
+ * </dl>
+ *
+ * @ingroup pwglf_forward_trains_helper
+ */
+struct PluginHelper : public Helper
+{
+ /**
+ * Constructor
+ *
+ * @param url Url
+ * @param opts Options
+ */
+ PluginHelper(const TUrl& url, Int_t verbose)
+ : Helper(url, verbose), fHandler(0), fUsePars(false)
+ {
+ fHandler = new AliAnalysisAlien();
+
+ fOptions.Add("aliroot", "VERSION", "AliROOT version", "last");
+ fOptions.Add("root", "VERSION", "ROOT version", "last");
+ fOptions.Add("par", "Use par files");
+ fOptions.Add("mode", "default|rec|sim", "AliROOT mode", "default");
+ fOptions.Add("storage", "URL", "Location for external storage", "");
+ fOptions.Add("plugin", "Use AliEn handler");
+ }
+ virtual ~PluginHelper() {}
+ /**
+ * Load a library/PAR/script
+ *
+ * @param name Name
+ * @param par If true, upload & enable PAR
+ * @param slaves If true, also load on slaves
+ *
+ * @return true on success
+ */
+ virtual Bool_t LoadLibrary(const TString& name,
+ Bool_t slaves=true)
+ {
+ if (!fUsePars) {
+ TString fullName(MakeLibraryName(name));
+ Int_t ret = gSystem->Load(fullName);
+ if (ret < 0) return false;
+ if (slaves) fHandler->AddAdditionalLibrary(fullName);
+ }
+ else {
+ if (!ParUtilities::Find(name)) {
+ Error("PluginHelper::LoadLibrary", "Failed to find PAR file %s",
+ name.Data());
+ return false;
+ }
+ if (!ParUtilities::Build(name)) {
+ Error("PluginHelper::LoadLibrary", "Failed to build PAR file %s",
+ name.Data());
+ return false;
+ }
+ fHandler->EnablePackage(name);
+ }
+ return true;
+ }
+ /**
+ * Load a source file, and compile it
+ *
+ * @param name Name of the source file
+ *
+ * @return true on success
+ */
+ virtual Bool_t LoadSource(const TString& name)
+ {
+ static TString s;
+ if (!Helper::LoadSource(name)) return false;
+ s.Append(Form(" %s", gSystem->BaseName(name.Data())));
+ fHandler->SetAnalysisSource(s);
+ return true;
+ }
+
+ /**
+ * Set-up to load the AliROOT libraries
+ *
+ * @param par Whether to use PAR files
+ *
+ * @return true on success
+ */
+ virtual Bool_t LoadAliROOT()
+ {
+ if (!gSystem->Getenv("ALICE_ROOT")) {
+ Error("PluginHelper::LoadAliROOT", "Local AliROOT not available");
+ return false;
+ }
+ Bool_t tmp = fUsePars;
+ fUsePars = false;
+
+ if (!LoadLibrary("STEERBase")) return false;
+ if (!LoadLibrary("ESD")) return false;
+ if (!LoadLibrary("AOD")) return false;
+ if (!LoadLibrary("ANALYSIS")) return false;
+ if (!LoadLibrary("OADB")) return false;
+ if (!LoadLibrary("ANALYSISalice")) return false;
+ fUsePars = tmp;
+
+ return true;
+ }
+ /**
+ * Set-up done before task set-ups
+ *
+ * @return true on success
+ */
+ virtual Bool_t PreSetup()
+ {
+ // --- Set prefered GSI method ---------------------------------
+ gEnv->SetValue("XSec.GSI.DelegProxy", "2");
+
+ TString aliroot("last");
+ TString root("last");
+ if (fOptions.Has("aliroot")) aliroot = fOptions.Get("aliroot");
+ if (fOptions.Has("root")) root = fOptions.Get("root");
+
+ AvailableSoftware::Check(aliroot, root);
+ fOptions.Set("aliroot", aliroot);
+ fOptions.Set("root", root);
+
+ fUsePars = fOptions.Has("par");
+
+ fHandler->SetROOTVersion(root);
+ fHandler->SetAliROOTVersion(aliroot);
+ if (fOptions.Has("mode"))
+ fHandler->SetAliRootMode(fOptions.Get("mode"));
+ else
+ fHandler->SetAliRootMode("default");
+
+ return true;
+ }
+ /**
+ * Set-up done after the task set-ups
+ *
+ * @return true on success
+ */
+ virtual Bool_t PostSetup()
+ {
+ AliAnalysisManager* mgr = AliAnalysisManager::GetAnalysisManager();
+ if (!mgr) {
+ Error("PluginHelper::PostSetup", "No analysis manager defined");
+ return false;
+ }
+ mgr->SetGridHandler(fHandler);
+
+ fHandler->SetJobTag(mgr->GetName());
+ fHandler->SetAnalysisMacro(Form("%s.C", mgr->GetName()));
+
+ if (fOptions.Has("storage"))
+ OutputUtilities::RegisterStorage(fOptions.Get("storage"));
+
+ return true;
+ };
+ /**
+ * Pure virtual overload
+ *
+ * @param Long64_t
+ *
+ * @return
+ */
+ virtual Long64_t Run(Long64_t) = 0;
+ /**
+ * Pure virtual overload
+ *
+ * @return Short description
+ */
+ virtual const char* Desc() const = 0;
+ /**
+ * Pure virtual overload
+ *
+ * @return URI help string
+ */
+ virtual const Char_t* UrlHelp() const = 0;
+ /**
+ * Overload
+ *
+ * @param option Options
+ */
+ virtual void Print(Option_t* option="") const
+ {
+ Helper::Print(option);
+ fHandler->Print(option);
+ }
+ AliAnalysisAlien* fHandler;
+ Bool_t fUsePars;
+};
+#endif
+//
+// EOF
+//
--- /dev/null
+/**
+ * @file ProofHelper.C
+ * @author Christian Holm Christensen <cholm@master.hehi.nbi.dk>
+ * @date Tue Oct 16 18:58:37 2012
+ *
+ * @brief
+ *
+ *
+ * @ingroup pwglf_forward_trains_helper
+ *
+ */
+#ifndef PROOFHELPER_C
+#define PROOFHELPER_C
+#include "Helper.C"
+#ifndef __CINT__
+# include "OutputUtilities.C"
+# include "ParUtilities.C"
+# include "ChainBuilder.C"
+# include <TUrl.h>
+# include <TString.h>
+# include <TProof.h>
+# include <TProofLog.h>
+# include <TProofDebug.h>
+# include <AliAnalysisManager.h>
+# include <TEnv.h>
+# include <TChain.h>
+#else
+class TUrl;
+class TChain;
+#endif
+
+// ===================================================================
+/**
+ * Handle analysis on a Proof farm.
+ *
+ * This helper is triggered by URIs of the form
+ *
+ * @code
+ * proof://[<user>@]<host>[:<port>]/<dsname>[?<options>][#<treename>]
+ * @endcode
+ * where
+ * <dl>
+ * <dt><user@gt;</dt>
+ * <dd>Optional user name</dd>
+ * <dt><host@gt;</dt>
+ * <dd>PROOF cluster master host</dd>
+ * <dt><port@gt;</dt>
+ * <dd>Optional PROOF cluster port on master host</dd>
+ * <dt><dsname@gt;</dt>
+ * <dd>Data set name</dd>
+ * <dt><tt><datadir></tt></dt>
+ * <dd>is the base directory holding data files </dd>
+ * <dt><tt><collection></tt></dt>
+ * <dd>is an ASCII or XML list of input sources</dd>
+ * <dt><tt><file></tt></dt>
+ * <dd>is a single ROOT file</dd>
+ * <dt><treename@gt;</dt>
+ * <dd>Optional tree name in data set, often <tt>esdTree</tt> or
+ * <tt>aodTree</tt></dd>
+ * <dt><options@gt;</dt>
+ * <dd>List of options separated by an &
+ * <dl>
+ * <dt><tt>workers=N[x]</tt></dt>
+ * <dd>Set the number of workers to use. If <tt>x</tt> is appended,
+ * then it's maximum number of workers per slave</dd>
+ * <dt><tt>dsname</tt>[=<output dataset>]</dt>
+ * <dd>Register tree output (e.g., AOD) as a new data set on the
+ * PROOF cluster. If <output dataset> is not specified, take
+ * the name of the train.</dd>
+ * <dt><tt>par[=all]</tt></dt>
+ * <dd>Use PAR files. If the value <tt>all</tt> is given, then also
+ * PAR files of STEERBase, ESD, AOD, ANALYSIS, OADB, ANALYSISalice
+ * are used. </dd>
+ * <dt><tt>mode=[default,rec,sim,train,custom]</tt></dt>
+ * <dd>Set the AliROOT mode. If not specified <tt>default</tt>
+ * is assumed</tt>. See also CreateAliROOTPar</dd>
+ * <dt><tt>storage=<url></tt></dt>
+ * <dd>Specify a non-default storage location for special output
+ * (e.g., AOD trees). <url> should be a valid XRootd
+ * server URI accessible to the slaves - e.g.,
+ * <tt>root://lxplus.cern.ch:10930//tmp</tt>.</dd>
+ * </dl>
+ * </dd>
+ * </dl>
+ *
+ * @ingroup pwglf_forward_trains_helper
+ */
+struct ProofHelper : public Helper
+{
+ /**
+ * Constructor
+ *
+ * @param url Url
+ * @param opts Options
+ */
+ ProofHelper(const TUrl& url, Int_t verbose)
+ : Helper(url, verbose),
+ fUsePars(false),
+ fBasePars(false)
+ {
+ fOptions.Add("workers", "N[x]", "Number of workers to use", "0");
+ fOptions.Add("dsname", "NAME", "Make output dataset", "");
+ fOptions.Add("par", "tasks|all", "Use par files", "tasks");
+ fOptions.Add("mode", "default|rec|sim", "AliROOT mode", "default");
+ fOptions.Add("storage", "URL", "Location for external storage", "");
+
+ if (!fUrl.GetUser() || fUrl.GetUser()[0] == '\0')
+ fUrl.SetUser(gSystem->GetUserInfo()->fUser);
+ }
+ virtual ~ProofHelper() {}
+ /**
+ * Load a library/PAR/script
+ *
+ * @param name Name
+ * @param par If true, upload & enable PAR
+ * @param slaves If true, also load on slaves
+ *
+ * @return true on success
+ */
+ virtual Bool_t LoadLibrary(const TString& name,
+ Bool_t slaves=true)
+ {
+ if (!fUsePars) {
+ Int_t ret = gSystem->Load(MakeLibraryName(name));
+ if (ret < 0) return false;
+ if (slaves) fExtraLibs.Append(Form(":%s", name.Data()));
+ }
+ else {
+ if (!ParUtilities::Find(name)) {
+ Error("ProofHelper::LoadLibrary", "Failed to find PAR file %s",
+ name.Data());
+ return false;
+ }
+ if (!ParUtilities::Build(name)) {
+ Error("ProofHelper::LoadLibrary", "Failed to build PAR file %s",
+ name.Data());
+ return false;
+ }
+ if (gProof->UploadPackage(name.Data(), TProof::kRemoveOld) < 0) {
+ Error("ProofHelper::LoadLibrary", "Failed to upload PAR file %s",
+ name.Data());
+ return false;
+ }
+ fExtraPars.Append(Form(":%s", name.Data()));
+ }
+ return true;
+ }
+ /**
+ * Load a source file, and compile it
+ *
+ * @param name Name of the source file
+ *
+ * @return true on success
+ */
+ virtual Bool_t LoadSource(const TString& name)
+ {
+ if (!Helper::LoadSource(name)) return false;
+ fExtraSrcs.Append(Form(":%s", gSystem->BaseName(name.Data())));
+ return true;
+ }
+ /**
+ * Set-up to load the AliROOT libraries
+ *
+ * @param par Whether to use PAR files
+ *
+ * @return true on success
+ */
+ virtual Bool_t LoadAliROOT()
+ {
+ if (!gSystem->Getenv("ALICE_ROOT")) {
+ Error("ProofHelper::LoadAliROOT", "Local AliROOT not available");
+ return false;
+ }
+
+ Bool_t tmp = fUsePars;
+ fUsePars = fBasePars;
+ if (!LoadLibrary("STEERBase")) return false;
+ if (!LoadLibrary("ESD")) return false;
+ if (!LoadLibrary("AOD")) return false;
+ if (!LoadLibrary("ANALYSIS")) return false;
+ if (!LoadLibrary("OADB")) return false;
+ if (!LoadLibrary("ANALYSISalice")) return false;
+ fUsePars = tmp;
+
+ return CreateAliROOTPar();
+ }
+ /**
+ * Get the name of the AliROOT par file to use
+ *
+ * @return String
+ */
+ virtual const char* AliROOTParName() const
+ {
+ return "ALIROOT";
+ }
+ /**
+ * Create an AliROOT par file from the executing AliROOT. This PAR
+ * file basically uses the environment of the client - that is, we
+ * assume that the used AliROOT is accessible on the slaves - e.g.,
+ * via an NFS export.
+ *
+ * Note, the SETUP.C script take one argument - a TList of TNamed
+ * parameters. Parameters processed are
+ *
+ * - ALIROOT_MODE=[default,aliroot,rec,sim,train]
+ * - default: Load base analysis libraries
+ * - aliroot: Load $ALICE_ROOT/macros/loadlibs.C
+ * - rec: Load $ALICE_ROOT/macros/loadlibsrec.C
+ * - sim: Load $ALICE_ROOT/macros/loadlibssim.C
+ * - ALIROOT_EXTRA_LIBS Colon separated list of additional (Ali)ROOT
+ * libraries to load on the slaves.
+ *
+ * The generated PAR file is uploaded but not enabled until we have
+ * populated fExtraLibs. The enabling takes place at the end of the
+ * set-up.
+ *
+ * @return true on success, false otherwise. */
+ virtual Bool_t CreateAliROOTPar()
+ {
+ if (fBasePars) return true;
+
+ TString parName(AliROOTParName());
+ // Set-up directories
+ if (gSystem->MakeDirectory(parName) < 0) {
+ Error("ProofHelper::CreateAliROOTPar", "Could not make directory '%s'",
+ parName.Data());
+ return false;
+ }
+
+ if (gSystem->MakeDirectory(Form("%s/PROOF-INF", parName.Data()))) {
+ Error("ProofHelper::CreateAliROOTPar",
+ "Could not make directory %s/PROOF-INF",
+ parName.Data());
+ return false;
+ }
+
+ std::ofstream b(Form("%s/PROOF-INF/BUILD.sh",parName.Data()));
+ if (!b) {
+ Error("ProofHelper::CreateAliROOTPar",
+ "Failed to make BUILD.sh shell script");
+ return false;
+ }
+ b << "#!/bin/sh\n\n"
+ << "# echo Nothing to do\n"
+ << "exit 0\n"
+ << std::endl;
+ b.close();
+ gSystem->Exec(Form("chmod a+x %s/PROOF-INF/BUILD.sh",parName.Data()));
+
+ std::ofstream s(Form("%s/PROOF-INF/SETUP.C", parName.Data()));
+ if (!s) {
+ Error("ProofHelper::CreateAliROOTPar",
+ "Failed to make SETUP.C ROOT script");
+ return false;
+ }
+ s << "void SETUP(TList* opts) {\n"
+ << " gSystem->Setenv(\"ALICE\",\""
+ << gSystem->Getenv("ALICE") << "\");\n"
+ << " gSystem->Setenv(\"ALICE_ROOT\",\""
+ << gSystem->Getenv("ALICE_ROOT") << "\");\n"
+ << " gSystem->Setenv(\"ALICE_TARGET\",\""
+ << gSystem->Getenv("ALICE_TARGET") << "\");\n"
+ << " gSystem->AddDynamicPath("
+ << "\"$(ALICE_ROOT)/lib/tgt_$(ALICE_TARGET)\");\n";
+ if (gSystem->Getenv("OADB_PATH"))
+ s << " gSystem->Setenv(\"OADB_PATH\",\""
+ << gSystem->Getenv("OADB_PATH") << "\");\n";
+ s << " \n"
+ << " // Info(\"SETUP\",\"Loading ROOT libraries\");\n"
+ << " gSystem->Load(\"libTree\");\n"
+ << " gSystem->Load(\"libGeom\");\n"
+ << " gSystem->Load(\"libVMC\");\n"
+ << " gSystem->Load(\"libPhysics\");\n"
+ << " gSystem->Load(\"libMinuit\");\n"
+ << " \n";
+ s << " // Info(\"SETUP\",\"Parameter list:\");\n"
+ << " if (!opts) return;\n"
+ << " //opts->ls();\n"
+ << " \n";
+ s << " TObject* par = opts->FindObject(\"ALIROOT_MODE\");\n"
+ << " if (par) {\n"
+ << " // Info(\"SETUP\",\"ALIROOT mode: %s\", par->GetTitle());\n"
+ << " TString mode(par->GetTitle());\n"
+ << " if (mode.EqualTo(\"default\",TString::kIgnoreCase)) {\n"
+ << " gSystem->Load(\"libSTEERBase\");\n"
+ << " gSystem->Load(\"libESD\");\n"
+ << " gSystem->Load(\"libAOD\");\n"
+ << " gSystem->Load(\"libANALYSIS\");\n"
+ << " gSystem->Load(\"libOADB\");\n"
+ << " gSystem->Load(\"libANALYSISalice\");\n"
+ << " }\n"
+ << " else if (mode.EqualTo(\"aliroot\",TString::kIgnoreCase)) \n"
+ << " gROOT->Macro(\"$ALICE_ROOT/macros/loadlibs.C\");\n"
+ << " else if (mode.EqualTo(\"rec\",TString::kIgnoreCase)) \n"
+ << " gROOT->Macro(\"$ALICE_ROOT/macros/loadlibsrec.C\");\n"
+ << " else if (mode.EqualTo(\"sim\",TString::kIgnoreCase)) \n"
+ << " gROOT->Macro(\"$ALICE_ROOT/macros/loadlibssim.C\");\n"
+ << " else if (mode.EqualTo(\"train\",TString::kIgnoreCase)) \n"
+ << " gROOT->Macro(\"$ALICE_ROOT/macros/loadlibstrain.C\");\n"
+ << " else if (mode.EqualTo(\"custom\",TString::kIgnoreCase)) \n"
+ << " gROOT->Macro(\"$ALICE_ROOT/macros/loadlibstrain.C\");\n"
+ << " }\n"
+ << " \n";
+ s << " par = opts->FindObject(\"ALIROOT_EXTRA_LIBS\");\n"
+ << " if (par) {\n"
+ << " Info(\"SETUP\",\"Libaries to load: %s\n\",par->GetTitle());\n"
+ << " TString tit(par->GetTitle());\n"
+ << " TObjArray* tokens = tit.Tokenize(\":\");\n"
+ << " TObject* lib = 0;\n"
+ << " TIter next(tokens);\n"
+ << " while ((lib = next())) {\n"
+ << " TString libName(lib->GetName());\n"
+ << " if (!libName.BeginsWith(\"lib\")) libName.Prepend(\"lib\");\n"
+ << " // Info(\"SETUP\",\"Loading %s ...\",libName.Data());\n"
+ << " gSystem->Load(Form(\"lib%s\",lib->GetName()));\n"
+ << " }\n"
+ << " }\n"
+ << "}\n"
+ << std::endl;
+ s.close();
+
+ Int_t ret = gSystem->Exec(Form("tar -czf %s.par %s",
+ parName.Data(), parName.Data()));
+ if (ret != 0) {
+ Error("ProofHelper::CreateAliROOTPar", "Failed to pack up PAR files");
+ return false;
+ }
+
+ ret = gProof->UploadPackage(Form("./%s.par", parName.Data()),
+ TProof::kRemoveOld);
+ if (ret != 0) {
+ Error("ProofHelper::CreateAliROOTPar",
+ "Failed to upload the AliROOT PAR file");
+ return false;
+ }
+ // Note, the PAR isn't enabled until much later when we've
+ // collected all the needed libraries in fExtraLibs
+ return true;
+ }
+ /**
+ * Get the mode identifier
+ *
+ * @return Always kProof
+ */
+ virtual UShort_t Mode() const { return kProof; }
+ /**
+ * Get the mode string used for AliAnalysisManager::StartAnalysis
+ */
+ virtual const char* ModeString() const { return "proof"; }
+ /**
+ * Set-up done before task set-ups
+ *
+ * @return true on success
+ */
+ virtual Bool_t PreSetup()
+ {
+ // --- Set prefered GSI method ---------------------------------
+ gEnv->SetValue("XSec.GSI.DelegProxy", "2");
+
+ // --- Add ALICE_ROOT directory to search path for packages ----
+ Info("ProofHelper::PreSetup", "Set location of packages");
+ gEnv->SetValue("Proof.GlobalPackageDirs",
+ Form("%s:%s",
+ gEnv->GetValue("Proof.GlobalPackageDirs", "."),
+ gSystem->Getenv("ALICE_ROOT")));
+
+ // --- PAR parameters --------------------------------------------
+ fUsePars = fOptions.Has("par");
+ fBasePars = (fUsePars &&
+ fOptions.Get("par").EqualTo("all",TString::kIgnoreCase));
+
+ // --- Connect to the cluster ------------------------------------
+ TUrl connect(fUrl);
+ connect.SetAnchor("");
+ connect.SetFile("");
+ connect.SetOptions("");
+ TString opts;
+ if (fOptions.Has("workers"))
+ opts.Append(Form("workers=%s", fOptions.Get("workers").Data()));
+
+ Info("ProofHelper::PreSetup", "Connecting to %s with %soptions %s",
+ connect.GetUrl(),
+ opts.IsNull() ? "no " : "",
+ opts.Data());
+ TString proto(connect.GetProtocol());
+ if (proto.BeginsWith("lite") && fOptions.Has("workers"))
+ TProof::Open(opts);
+ else
+ TProof::Open(connect.GetUrl(), opts);
+ // TProof::Open(connect.GetHost(), opts);
+ if (!gProof) {
+ Error("ProofHelper::PreSetup", "Failed to open Proof connection %s",
+ connect.GetUrl());
+ return false;
+ }
+ Info("ProofHelper::PreSetup", "Using progress dialog=%d",
+ gProof->TestBit(TProof::kUseProgressDialog));
+ return true;
+ }
+ /**
+ * Set-up done after the task set-ups
+ *
+ * @return true on success
+ */
+ virtual Bool_t PostSetup()
+ {
+ AliAnalysisManager* mgr = AliAnalysisManager::GetAnalysisManager();
+ if (!mgr) {
+ Error("ProofHelper::PostSetup", "No analysis manager defined");
+ return false;
+ }
+
+ // --- Check for output ------------------------------------------
+ if (fOptions.Has("dsname"))
+ OutputUtilities::RegisterDataset(fOptions.Get("dsname"));
+ if (fOptions.Has("storage"))
+ OutputUtilities::RegisterStorage(fOptions.Get("storage"));
+
+ // --- If we are not using PARs for Base, enable special PAR -----
+ if (!fBasePars) {
+ TString tmp(fExtraLibs.Strip(TString::kBoth,':'));
+ TList* params = new TList;
+ params->SetOwner(true);
+ params->Add(new TNamed("ALIROOT_EXTRA_LIBS", tmp.Data()));
+ if (fOptions.Has("mode"))
+ params->Add(new TNamed("ALIROOT_MODE", fOptions.Get("mode").Data()));
+ else
+ params->Add(new TNamed("ALIROOT_MODE", "default"));
+ Int_t ret = gProof->EnablePackage(AliROOTParName(), params, true);
+ if (ret < 0) {
+ Error("ProofHelper::EnableAliROOT", "Failed to enable AliROOT PAR %s",
+ AliROOTParName());
+ return false;
+ }
+ }
+
+ // --- Load par files --------------------------------------------
+ TString tmp = fExtraPars.Strip(TString::kBoth,':');
+ TObjArray* pars = tmp.Tokenize(":");
+ TObject* obj = 0;
+ TIter next(pars);
+ while ((obj = next())) {
+ Int_t ret = gProof->EnablePackage(obj->GetName());
+ if (ret < 0) {
+ Error("ProofHelper::PostSetup", "Failed to enable PAR %s",
+ obj->GetName());
+ return false;
+ }
+ }
+
+ // --- Load extra sources ----------------------------------------
+ TString tmp2 = fExtraSrcs.Strip(TString::kBoth, ':');
+ TObjArray* srcs = tmp2.Tokenize(":");
+ TIter next2(srcs);
+ while ((obj = next())) {
+ Int_t ret = gProof->Load(Form("%s++g", obj->GetName()), true);
+ if (ret < 0) {
+ Error("ProofHelper::PostSetup", "Failed to compile %s", obj->GetName());
+ return false;
+ }
+ }
+ return true;
+ }
+ /**
+ * Start the analysis
+ *
+ * @param nEvents Number of events to analyse
+ *
+ * @return The return value of AliAnalysisManager::StartAnalysis
+ */
+ virtual Long64_t Run(Long64_t nEvents=-1)
+ {
+ AliAnalysisManager* mgr = AliAnalysisManager::GetAnalysisManager();
+ gProof->SetLogLevel(TMath::Max(fVerbose-2,0),
+ /* TProofDebug::kPacketizer| */
+ TProofDebug::kLoop|
+ /* TProofDebug::kSelector|
+ TProofDebug::kOutput|
+ TProofDebug::kInput|
+ TProofDebug::kGlobal|*/
+ TProofDebug::kPackage);
+ TString dsName(fUrl.GetFile());
+ // if (fUrl.GetAnchor() && fUrl.GetAnchor()[0] != '\0')
+ // dsName.Append(Form("#%s", fUrl.GetAnchor()));
+ Long64_t ret = mgr->StartAnalysis(fUrl.GetProtocol(), dsName, nEvents);
+
+ if (fVerbose > 2)
+ TProof::Mgr(fUrl.GetUrl())->GetSessionLogs()->Save("*","proof.log");
+ return ret;
+ }
+ /**
+ * Print information to standard output
+ *
+ * @param option
+ */
+ virtual void Print(Option_t* option="") const
+ {
+ Helper::Print(option);
+ std::cout << std::boolalpha
+ << " --- Other settings -------\n"
+ << " Extra libraries : " << fExtraLibs << "\n"
+ << " Extra PARs : " << fExtraPars << "\n"
+ << " Extra sources : " << fExtraSrcs << "\n"
+ << " Use PARs of tasks: " << fUsePars << "\n"
+ << " Use PARs of base : " << fBasePars
+ << std::noboolalpha << std::endl;
+ }
+ /**
+ * Path of output
+ *
+ * @return Path to output - possibly a data set
+ */
+ virtual TString OutputPath() const
+ {
+ TString ret;
+ if (fOptions.Has("dsname")) {
+ ret = Form("/%s/%s/", gProof->GetGroup(), gProof->GetUser());
+ ret.Append(OutputUtilities::RegisteredDataset());
+ }
+ return ret;
+ }
+ /**
+ * @return URL help string
+ */
+ virtual const Char_t* UrlHelp() const
+ {
+ return "proof://<host>[:<port>]/[<dataset>|<path>][?<options>][#<treeName>]";
+ }
+ /**
+ * @return Short description
+ */
+ virtual const char* Desc() const { return "PROOF"; }
+ TString fExtraLibs;
+ TString fExtraPars;
+ TString fExtraSrcs;
+ Bool_t fUsePars;
+ Bool_t fBasePars;
+};
+#endif
+//
+// EOF
+//
--- /dev/null
+/**
+ * @file QATrain.C
+ * @author Christian Holm Christensen <cholm@master.hehi.nbi.dk>
+ * @date Fri Jun 1 13:55:50 2012
+ *
+ * @brief
+ *
+ *
+ * @ingroup pwglf_forward_trains_specific
+ */
+
+#include "TrainSetup.C"
+#include <AliESDInputHandlerRP.h>
+#include <AliCDBManager.h>
+
+//====================================================================
+/**
+ * Analysis train to do full Quality Assurance train
+ *
+ * @ingroup pwglf_forward_trains_specific
+ */
+class QATrain : public TrainSetup
+{
+public:
+ enum {
+ kCDBConnect = 0x1,
+ kEventStats = 0x2, // Event Statistics (Jan Fiete)
+ kCentrality = 0x4, // Centrality (A. Toia)
+ kDefaultFlags = (kCDBConnect|kEventStats|kCentrality)
+ };
+ enum {
+ kVertex = 0x000001, // Vertexing (A. Dainese)
+ kSymmetric = 0x000002, // TPC QA (E. Sicking)
+ kVZERO = 0x000004, // VZERO QA (C. Cheshkov)
+ kTPC = 0x000008, // TPC (Jacek Otwinowski & Michael Knichel)
+ kSPD = 0x000010, // SPD (A. Mastroserio) - Needs RP
+ kSDD = 0x000020, // SDD (F. Prino) Needs RP
+ kSSD = 0x000040, // SSD dEdx (Marek Chojnacki)
+ kITS = 0x000080, //
+ kITSSA = 0x000100, // ITS saTracks (F.Prino)
+ kITSAlign = 0x000200, // ITS align (F.Prino)
+ kTRD = 0x000400, // TRD (Alex Bercuci, M. Fasel)
+ kZDC = 0x000800, // ZDC (Chiara Oppedisano)
+ kCALO = 0x001000, // Calorimetry (Gustavo Conesa)
+ kMUONTRG = 0x002000, // Muon Trigger
+ kMUONEff = 0x004000, // Muon Efficiency (not used) Need geo
+ kV0 = 0x008000, // V0-Decay Reconstruction (Ana Marin)
+ // (not used) Need MC truth
+ kBRes = 0x010000, // Impact parameter resolution
+ // (xianbao.yuan@pd.infn.it,
+ // andrea.dainese@pd.infn.it)
+ kMUON = 0x020000, // MUON QA (Philippe Pillot)
+ kTOF = 0x040000, // TOF (Francesca Bellini)
+ kPIDRes = 0x080000, // PIDResponse (Jens)
+ kPID = 0x100000, // PIDqa (Jens)
+ kHMPID = 0x200000, // HMPID QA (Giacomo Volpe)
+ kT0 = 0x400000, // T0 QA (Alla Mayevskaya)
+ kFMD = 0x800000, // FMD QA (Christian Holm Christiansen)
+ kDefaultModules = (kVertex|kSymmetric|kVZERO|kTPC|kSPD|kSDD|kSSD|kITS|
+ kITSSA|kITSAlign|kTRD|kZDC|kCALO|kMUONTRG|kBRes|
+ kMUON|kTOF|kPIDRes|kPID|kHMPID|kT0|kFMD)
+ };
+
+
+
+ /**
+ * Constructor. Date and time must be specified when running this
+ * in Termiante mode on Grid
+ *
+ * @param name Name of train
+ */
+ QATrain(const char* name="PilotAnalysis")
+ : TrainSetup(name, false, 0, 0, 0, 0, 0),
+ fRun(0),
+ fFlags(kDefaultFlags),
+ fModules(kDefaultModules),
+ fTriggerMask(AliVEvent::kAnyINT),
+ fTriggerHM(AliVEvent::kHighMult),
+ fTriggerEMC(AliVEvent::kEMC7),
+ fTriggerMUONBarrel(AliVEvent::kMUU7),
+ fCollisionType(0) // 0: pp, 1: PbPb
+ {}
+ void SetFlags(UShort_t flags) { fFlags = flags; }
+ void SetRun(UInt_t run) { fRun = run; }
+ void SetModules(UInt_t m) { fModules = m; }
+protected:
+ AliVEventHandler* CreateInputHandler(EType type)
+ {
+ if (type != kESD) return 0;
+ AliAnalysisManager::GetAnalysisManager()->SetRunFromPath(fRun);
+
+ AliESDInputHandlerRP* ih = new AliESDInputHandlerRP();
+ ih->SetReadFriends(kTRUE);
+ ih->SetActiveBranches("ESDfriend");
+ return ih;
+ }
+ AliAnalysisTaskSE* CreateTaskAndSetCollisionCandidates(const char* macro)
+ {
+ Long_t ret = gROOT->Macro(macro);
+ if (!ret) return 0;
+ AliAnalysisTaskSE* task = reinterpret_cast<AliAnalysisTaskSE*>(ret);
+ task->SelectCollisionCandidates(fTriggerMask);
+ return task;
+ }
+ void CreateCDBConnect()
+ {
+ ::Info("CreateCDBConnect", "Loading CDB connect w/run=%d", fRun);
+ Long_t ret = gROOT->Macro(Form("AddTaskCDBconnect.C(%d)", fRun));
+ ::Info("CreateCDBConnect", "Loaded %p", fRun);
+ if (!ret) return;
+ AliCDBManager::Instance()->SetDefaultStorage("raw://");
+ }
+ void CreatePhysicsSelection(Bool_t mc,
+ AliAnalysisManager* mgr)
+ {
+ // Event Statistics (Jan Fiete)
+ if (!(fFlags & kEventStats)) return;
+ TrainSetup::CreatePhysicsSelection(mc, mgr);
+ }
+ void CreateCentralitySelection(Bool_t mc, AliAnalysisManager* mgr)
+ {
+ // Centrality (A. Toia)
+ if (!(fFlags & kCentrality)) return;
+ TrainSetup::CreateCentralitySelection(mc, mgr);
+ }
+ void CreateVertex()
+ {
+ // Vertexing (A. Dainese)
+ gROOT->Macro(Form("AddTaskVertexESD.C(kFALSE,0x%x)", fTriggerMask));
+ }
+ void CreateSymmetric()
+ {
+ // TPC QA (E. Sicking)
+ gROOT->Macro(Form("AddTaskQAsym.C(0,0x%x,0x%x,0x%x,0x%x)",
+ fTriggerMask, fTriggerHM, fTriggerEMC,
+ fTriggerMUONBarrel));
+ }
+ void CreateVZERO()
+ {
+ // VZERO QA (C. Cheshkov)
+ gROOT->Macro("AddTaskVZEROQA.C(0)");
+ }
+ void CreateTPC()
+ {
+ // TPC (Jacek Otwinowski & Michael Knichel)
+ //
+ // Optionally MC information can be used by setting the 1st
+ // argument to true
+ //
+ // Optionally friends information can be switched off by setting
+ // the 2st argument to false
+ //
+ // Optionally highMult axis can be used by setting the 3st
+ // argument to true (for PbPb)
+ gROOT->SetMacroPath(Form("%s:$(ALICE_ROOT)/PWGPP/TPC/macros",
+ gROOT->GetMacroPath()));
+ CreateTaskAndSetCollisionCandidates("AddTaskPerformanceTPCdEdxQA.C(kFALSE,kTRUE,kFALSE)");
+ }
+ void CreateSPD()
+ {
+ // SPD (A. Mastroserio)
+ CreateTaskAndSetCollisionCandidates("AddTaskSPDQA.C");
+ // AliAnalysisTask* task =
+ // CreateTaskAndSetCollisionCandidates("AddTaskSPDQA.C");
+ // if (!task) return;
+ // task->SetOCDBInfo(fRun, "raw://");
+ }
+ void CreateSDD()
+ {
+ // SDD (F. Prino)
+ CreateTaskAndSetCollisionCandidates("AddSDDPoints.C");
+ }
+ void CreateSSD()
+ {
+ // SSD dEdx (Marek Chojnacki)
+ CreateTaskAndSetCollisionCandidates("AddTaskdEdxSSDQA.C");
+ }
+ void CreateITS()
+ {
+ gROOT->Macro("AddTaskPerformanceITS.C(kFALSE)");
+ if (fCollisionType == 0) return;
+
+ gROOT->ProcessLine("AddTaskPerformanceITS(kFALSE,kFALSE,kFALSE,3500,10000)");
+ gROOT->ProcessLine("AddTaskPerformanceITS(kFALSE,kFALSE,kFALSE,590,1570)");
+ gROOT->ProcessLine("AddTaskPerformanceITS(kFALSE,kFALSE,kFALSE,70,310)");
+ }
+ void CreateITSSA()
+ {
+ // ITS saTracks, align (F.Prino)
+ CreateTaskAndSetCollisionCandidates("AddTaskITSsaTracks.C(kFALSE,kFALSE)");
+ }
+ void CreateITSAlign()
+ {
+ // ITS saTracks, align (F.Prino)
+ gROOT->Macro("AddTaskITSAlign.C(0,2011");
+ }
+ void CreateTRD()
+ {
+ // TRD (Alex Bercuci, M. Fasel)
+ gSystem->AddIncludePath("-I${ALICE_ROOT}/PWGPP/TRD");
+ gROOT->Macro("AddTrainPerformanceTRD.C(\"ESD DET EFF RES PID\")");
+ }
+ void CreateZDC()
+ {
+ // ZDC (Chiara Oppedisano)
+ gROOT->SetMacroPath(Form("%s:$(ALICE_ROOT)/PWGPP/ZDC",
+ gROOT->GetMacroPath()));
+ CreateTaskAndSetCollisionCandidates("AddTaskZDCQA.C");
+ }
+ void CreateCALO(EMode mode, Bool_t par)
+ {
+ // Calorimetry (Gustavo Conesa)
+ LoadLibrary("EMCALUtils", mode, par, true);
+ LoadLibrary("PHOSUtils", mode, par, true);
+ LoadLibrary("PWG4PartCorrBase", mode, par, true);
+ LoadLibrary("PWG4PartCorrDep", mode, par, true);
+
+ gROOT->SetMacroPath(Form("%s:$(ALICE_ROOT)/PWG4/macros/QA",
+ gROOT->GetMacroPath()));
+ CreateTaskAndSetCollisionCandidates("AddTaskCalorimeterQA.C(\"ESD\",20011,kFALSE,kFALSE)");
+ Long_t ret = gROOT->ProcessLine("AddTaskCalorimeterQA(\"ESD\",2011,kFALSE,kFALSE,\"\",\"EMC7\")");
+ if (!ret) return;
+ AliAnalysisTaskSE* task = reinterpret_cast<AliAnalysisTaskSE*>(ret);
+ task->SelectCollisionCandidates(fTriggerEMC);
+ }
+ void CreateMUONTRG(EMode mode, Bool_t par)
+ {
+ // Muon Trigger
+ LoadLibrary("PWG3base", mode, par, true);
+ LoadLibrary("PWG3muon", mode, par, true);
+ LoadLibrary("PWG3muondep", mode, par, true);
+
+ gROOT->Macro("AddTaskMTRchamberEfficiency.C");
+ }
+ void CreateMUONEff()
+ {
+ gROOT->SetMacroPath(Form("%s:$(ALICE_ROOT)/PWG3/muondep",
+ gROOT->GetMacroPath()));
+ gROOT->Macro("AddTaskMUONTrackingEfficiency.C");
+ }
+ void CreateV0()
+ {
+ // V0-Decay Reconstruction (Ana Marin) (not used)
+ gROOT->Macro("AddTaskV0QA.C(kFALSE)");
+ }
+ void CreateBRes()
+ {
+ // Impact parameter resolution (xianbao.yuan@pd.infn.it,
+ // andrea.dainese@pd.infn.it)
+ CreateTaskAndSetCollisionCandidates(Form("AddTaskImpParRes.C(%s)",
+ fCollisionType == 0 ?
+ "" :
+ "kFALSE,-1,kFALSE,kFALSE"));
+ }
+ void CreateMUON(EMode mode, Bool_t par)
+ {
+ // MUON QA (Philippe Pillot)
+ LoadLibrary("PWG3base", mode, par, true);
+ LoadLibrary("PWG3muon", mode, par, true);
+ LoadLibrary("PWG3muondep", mode, par, true);
+ gROOT->SetMacroPath(Form("%s:$(ALICE_ROOT)/PWG3/muon",
+ gROOT->GetMacroPath()));
+ gROOT->Macro("AddTaskMuonQA.C");
+ }
+ void CreateTOF()
+ {
+ // TOF (Francesca Bellini)
+ gROOT->SetMacroPath(Form("%s:$(ALICE_ROOT)/PWGPP/TOF",
+ gROOT->GetMacroPath()));
+ CreateTaskAndSetCollisionCandidates("AddTaskTOFQA.C");
+ }
+ void CreatePIDRes()
+ {
+ // PIDResponse (Jens)
+ CreateTaskAndSetCollisionCandidates("AddTaskPIDResponse.C");
+ }
+
+ void CreatePID()
+ {
+ // PIDqa (Jens)
+ CreateTaskAndSetCollisionCandidates("AddTaskPIDqa.C");
+ }
+ void CreateHMPID()
+ {
+ // HMPID QA (Giacomo Volpe)
+ gROOT->SetMacroPath(Form("%s:$(ALICE_ROOT)/PWGPP/HMPID",
+ gROOT->GetMacroPath()));
+ CreateTaskAndSetCollisionCandidates("AddTaskHmpidQA.C");
+ }
+ void CreateT0()
+ {
+ // T0 QA (Alla Mayevskaya)
+ gROOT->SetMacroPath(Form("%s:$(ALICE_ROOT)/PWGPP/T0",
+ gROOT->GetMacroPath()));
+ CreateTaskAndSetCollisionCandidates("AddTaskT0QA.C");
+ }
+ void CreateFMD(EMode mode, Bool_t par)
+ {
+ // FMD QA (Christian Holm Christiansen)
+ LoadLibrary("PWGLFforward2", mode, par, true);
+ Bool_t mc = AliAnalysisManager::GetAnalysisManager()
+ ->GetMCtruthEventHandler() != 0;
+ gROOT->Macro(Form("AddTaskForwardQA.C(%d,%d)", mc, (fFlags & kCentrality)));
+ }
+ //__________________________________________________________________
+ /**
+ * 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("QAResults.root");
+
+ LoadLibrary("CORRFW", mode, par);
+ LoadLibrary("TENDER", mode, par);
+ LoadLibrary("PWG0base", mode, par);
+ LoadLibrary("PWG0dep", mode, par);
+ LoadLibrary("PWG0selectors", mode, par);
+ LoadLibrary("PWGPP", mode, par);
+
+ gROOT->SetMacroPath(Form("%s:$(ALICE_ROOT)/PWGPP/PilotTrain"
+ ":$(ALICE_ROOT)/PWGPP/macros",
+ gROOT->GetMacroPath()));
+
+ mgr->AddStatisticsTask(fTriggerMask);
+ if (fFlags & kCDBConnect) CreateCDBConnect();
+ if (fModules & kVertex) CreateVertex();
+ if (fModules & kSymmetric) CreateSymmetric();
+ if (fModules & kVZERO) CreateVZERO();
+ if (fModules & kTPC) CreateTPC();
+ if (fModules & kSPD) CreateSPD();
+ if (fModules & kSDD) CreateSDD();
+ if (fModules & kSSD) CreateSSD();
+ if (fModules & kITS) CreateITS();
+ if (fModules & kITSSA) CreateITSSA();
+ if (fModules & kITSAlign) CreateITSAlign();
+ if (fModules & kTRD) CreateTRD();
+ if (fModules & kZDC) CreateZDC();
+ if (fModules & kCALO) CreateCALO(mode, par);
+ if (fModules & kMUONTRG) CreateMUONTRG(mode, par);
+ if (fModules & kMUONEff) CreateMUONEff();
+ if (fModules & kV0) CreateV0();
+ if (fModules & kBRes) CreateBRes();
+ if (fModules & kMUON) CreateMUON(mode, par);
+ if (fModules & kTOF) CreateTOF();
+ if (fModules & kPIDRes) CreatePIDRes();
+ if (fModules & kPID) CreatePID();
+ if (fModules & kHMPID) CreateHMPID();
+ if (fModules & kT0) CreateT0();
+ if (fModules & kFMD) CreateFMD(mode, par);
+ }
+ /**
+ * Crete output handler - we don't want one here.
+ *
+ * @return 0
+ */
+ AliVEventHandler* CreateOutputHandler(EType) { return 0; }
+ UInt_t fRun; // Run number
+ UShort_t fFlags; // Flags
+ UInt_t fModules; // Modules to load
+ UInt_t fTriggerMask;
+ UInt_t fTriggerHM;
+ UInt_t fTriggerEMC;
+ UInt_t fTriggerMUONBarrel;
+ UShort_t fCollisionType; // 0: pp, 1: PbPb
+
+
+ Bool_t fUseCent; // Whether to use centrality or not
+};
+
+//
+// EOF
+//
--- /dev/null
+/**
+ * @file RunTrain.C
+ * @author Christian Holm Christensen <cholm@nbi.dk>
+ * @date Tue Oct 16 17:49:49 2012
+ *
+ * @brief Script to run a train
+ *
+ * @ingroup pwglf_forward_trains
+ */
+/**
+ * Build a script
+ *
+ * @param name Name of script
+ * @param verbose Whether to be verbose
+ * @param force Whether to force re-compilation
+ * @param debug Whether to enable debug symbols
+ *
+ * @return true on success
+ *
+ * @ingroup pwglf_forward_trains
+ */
+Bool_t
+BuildScript(const char* name, Bool_t verbose, Bool_t force, Bool_t debug)
+{
+ const char opt[] = { (force ? '+' : debug ? 'g' : '\0'),
+ (force && debug ? 'g' : '\0'), '\0' };
+ if (verbose) Printf("Building %s ...",name);
+ Int_t error;
+ Int_t ret = gROOT->LoadMacro(Form("%s.C+%s", name, opt), &error);
+ if (ret < 0 || error) {
+ Error("BuildScript", "Failed to build %s: %d", error);
+ return false;
+ }
+ return true;
+
+}
+
+/**
+ * Build all helper classes
+ *
+ * @param verbose Whether to be verbose
+ * @param force Whether to force re-builds
+ * @param debug Whether to enable debug symbols
+ *
+ * @return true on success
+ *
+ * @ingroup pwglf_forward_trains
+ */
+Bool_t
+BuildHelpers(Bool_t verbose, Bool_t force, Bool_t debug)
+{
+ gSystem->AddIncludePath("-I$ALICE_ROOT/include");
+ gSystem->Load("libANALYSIS");
+ gSystem->Load("libANALYSISalice");
+ const char* scripts[] = { "AvailableSoftware",
+ "ChainBuilder",
+ "ParUtilities",
+ "OutputUtilities",
+ "Option",
+ "Helper",
+ "LocalHelper",
+ "ProofHelper",
+ "LiteHelper",
+ "AAFHelper",
+ "PluginHelper",
+ "AAFPluginHelper",
+ "GridHelper",
+ "TrainSetup",
+ 0 };
+ const char** ptr = scripts;
+ while ((*ptr)) {
+ if (!BuildScript(*ptr, verbose, force, debug)) return false;
+ ptr++;
+ }
+ return true;
+}
+
+/**
+ * Show the usage
+ *
+ *
+ * @ingroup pwglf_forward_trains
+ */
+void PlainUsage()
+{
+ std::cout << "Usage: .x RunTrain.C(NAME,CLASS,OPTIONS)\n\n"
+ << " NAME Name of train (free form)\n"
+ << " CLASS Name of class implementing TrainSetup\n"
+ << " OPTIONS Comma separated list of options\n"
+ << std::endl;
+}
+
+/**
+ * Function to run a train.
+ *
+ * @param name Name of the train.
+ * @param cls class name of train setup
+ * @param opts Optons
+ *
+ * @return true on success
+ *
+ * @ingroup pwglf_forward_trains
+ */
+Bool_t RunTrain(const TString& name, const TString& cls,
+ const TString& uri, const TString& opts)
+{
+ // Check for help
+ if (name.IsNull() || name.EqualTo("help", TString::kIgnoreCase) ||
+ cls.IsNull() || cls.EqualTo("help", TString::kIgnoreCase)) {
+ PlainUsage();
+ return true;
+ }
+
+ Bool_t verb = opts.Contains("verbose");
+ // Build our helpers
+ if (!BuildHelpers(verb, false, true)) return false;
+
+ // Tokenize options
+ if (!opts.EndsWith(",")) opts.Append(",");
+ opts.Append("url=");
+ opts.Append(uri);
+ TObjArray* optList = opts.Tokenize(",");
+ return TrainSetup::Main(name, cls, optList);
+}
+/*
+ * EOF
+ */
+
--- /dev/null
+/**
+ * @defgroup pwglf_forward_trains Trains
+ *
+ * Train specifications
+ *
+ * @ingroup pwglf_forward
+ */
+/**
+ * @file TrainSetup.C
+ * @author Christian Holm Christensen <cholm@master.hehi.nbi.dk>
+ * @date Tue Oct 16 17:56:57 2012
+ *
+ * @brief Base classs for train specifications
+ *
+ * @ingroup pwglf_forward_trains
+ */
+#ifndef TRAINSETUP_C
+#define TRAINSETUP_C
+#ifndef __CINT__
+# include "Helper.C"
+# include "Option.C"
+# include <TDatime.h>
+# include <TUrl.h>
+# include <TString.h>
+# include <TApplication.h>
+# include <AliAnalysisManager.h>
+# include <AliVEventHandler.h>
+# include <AliPhysicsSelection.h>
+# include <AliPhysicsSelectionTask.h>
+# include <AliCentralitySelectionTask.h>
+# include <AliESDInputHandler.h>
+# include <AliAODInputHandler.h>
+# include <AliAODHandler.h>
+# include <AliMCEventHandler.h>
+#else
+struct Helper;
+struct OptionList;
+class TDatime;
+class TUrl;
+class TString;
+class AliVEventHandler;
+class AliAnalysisManager;
+class AliInputEventHandler;
+#endif
+
+//====================================================================
+/**
+ * Generic set-up of an analysis train using the grid-handler (AliEn plugin).
+ *
+ * See also @ref train_setup_doc
+ *
+ * @ingroup pwglf_forward_trains
+ *
+ */
+struct TrainSetup
+{
+ /**
+ * Constructor
+ *
+ * @param name Name of the train
+ */
+ TrainSetup(const TString& name)
+ : fName(name),
+ fEscapedName(name),
+ fHelper(0)
+ {
+ fOptions.Add("help", "Show help");
+ fOptions.Add("date", "YYYY-MM-DD HH:MM", "Set date", "now");
+ fOptions.Add("mc", "Assume MC input");
+ fOptions.Add("bare-ps", "Use bare physics selection w/o task");
+ fOptions.Add("verbose", "LEVEL", "Set verbosity level", "0");
+ fOptions.Add("url", "URL", "Job location & input URL", "");
+ fOptions.Add("overwrite", "Allow overwrite");
+ fOptions.Add("events", "N", "Number of events to analyse", "-1");
+ fOptions.Add("type", "ESD|AOD|USER", "Input data stype", "");
+ fEscapedName = EscapeName(fName, "");
+ }
+ /**
+ * Destructor
+ */
+ virtual ~TrainSetup() {}
+ /* @} */
+ //__________________________________________________________________
+ /**
+ * @{
+ * @name Execution
+ */
+ /**
+ * Initialize
+ *
+ * @return true on success
+ */
+ Bool_t Init()
+ {
+ // --- Create the helper -----------------------------------------
+ TString url = fOptions.Get("url");
+ Int_t verbose = fOptions.AsInt("verbose");
+ Bool_t mc = fOptions.AsBool("mc");
+
+ fHelper = Helper::Create(url.Data(), verbose);
+ if (!fHelper) {
+ Error("Init", "Failed to make the worker for URL %s", url.Data());
+ return false;
+ }
+
+ UShort_t type = fHelper->InputType();
+ if (fOptions.Has("type")) {
+ const TString& it = fOptions.Get("type");
+ if (it.EqualTo("ESD",TString::kIgnoreCase)) type = Helper::kESD;
+ else if (it.EqualTo("AOD",TString::kIgnoreCase)) type = Helper::kAOD;
+ else if (it.EqualTo("user",TString::kIgnoreCase))
+ type = Helper::kUser;
+ }
+
+ // --- Get current directory and set-up sub-directory ------------
+ TString cwd = gSystem->WorkingDirectory();
+ if (!SetupWorkingDirectory()) return false;
+
+ // --- Do initial helper setup -----------------------------------
+ if (!fHelper->PreSetup()) return false;
+
+ // --- Load ROOT libraries ---------------------------------------
+ if (!fHelper->LoadROOT()) return false;
+
+ // --- Load AliROOT libraries ------------------------------------
+ if (!fHelper->LoadAliROOT()) return false;
+
+ // --- Create analysis manager -----------------------------------
+ AliAnalysisManager *mgr = CreateAnalysisManager(fName);
+
+ // In test mode, collect system information on every event
+ // if (oper == kTest) mgr->SetNSysInfo(1);
+ if (verbose > 0) mgr->SetDebugLevel(verbose);
+ if (fHelper->Mode() == Helper::kLocal)
+ mgr->SetUseProgressBar(kTRUE, 100);
+
+ // --- ESD input handler ------------------------------------------
+ AliVEventHandler* inputHandler = CreateInputHandler(type);
+ if (inputHandler) mgr->SetInputEventHandler(inputHandler);
+
+ // --- Monte-Carlo ------------------------------------------------
+ AliVEventHandler* mcHandler = CreateMCHandler(type,mc);
+ if (mcHandler) mgr->SetMCtruthEventHandler(mcHandler);
+
+ // --- AOD output handler -----------------------------------------
+ AliVEventHandler* outputHandler = CreateOutputHandler(type);
+ if (outputHandler) mgr->SetOutputEventHandler(outputHandler);
+
+ // --- Include analysis macro path in search path ----------------
+ gROOT->SetMacroPath(Form("%s:%s:$ALICE_ROOT/ANALYSIS/macros",
+ cwd.Data(), gROOT->GetMacroPath()));
+
+ // --- Physics selction - only for ESD ---------------------------
+ if (type == Helper::kESD) CreatePhysicsSelection(mc, mgr);
+
+ // --- Create centrality task ------------------------------------
+ CreateCentralitySelection(mc, mgr);
+
+ // --- Create tasks ----------------------------------------------
+ CreateTasks(mgr);
+
+ // --- Post set-up initialization of helper ----------------------
+ if (!fHelper->PostSetup()) return false;
+
+ // --- Set debug level on defined tasks --------------------------
+ if (verbose > 0) {
+ TIter next(mgr->GetTasks());
+ AliAnalysisTask* sub = 0;
+ while ((sub = static_cast<AliAnalysisTask*>(next()))) {
+ AliAnalysisTaskSE* se = dynamic_cast<AliAnalysisTaskSE*>(sub);
+ if (!se) continue;
+ se->SetDebugLevel(verbose);
+ }
+ }
+
+ // --- Print this setup ------------------------------------------
+ Print();
+
+ // --- Initialise the train --------------------------------------
+ if (!mgr->InitAnalysis()) {
+ gSystem->ChangeDirectory(cwd.Data());
+ Error("Init","Failed to initialise train");
+ return false;
+ }
+
+ // --- Enable progress bar ---------------------------------------
+ if (fHelper->Mode() != Helper::kGrid)
+ mgr->SetUseProgressBar(true, 100);
+
+ // --- Save setup to disk ----------------------------------------
+ SaveSetup(true);
+
+ // Some information
+ mgr->PrintStatus();
+
+ return true;
+ }
+ Bool_t Run(Bool_t doExit=false)
+ {
+ TString cwd = gSystem->WorkingDirectory();
+ Bool_t status = false;
+ try {
+ if (!Init()) throw TString("Failed to intialize the train");
+
+ // if (r) SaveSetup(*r, nEvents, asShell);
+
+ Long64_t nEvents = fOptions.AsLong("events", -1);
+ Long64_t ret = fHelper->Run(nEvents);
+
+ // Make sure we go back
+ gSystem->ChangeDirectory(cwd.Data());
+
+ // Return.
+ if (ret < 0) throw TString("Analysis failed");
+
+ status = true;
+ }
+ catch (TString& e) {
+ Error("Main", e);
+ status = false;
+ }
+ if (gApplication && doExit) {
+ gSystem->Sleep(3);
+ gApplication->Terminate(status ? 0 : 1);
+ }
+ return true;
+ }
+ /**
+ * Get the options
+ *
+ *
+ * @return Reference ot the options
+ */
+ OptionList& Options() { return fOptions; }
+ /**
+ * Print information to standard output
+ *
+ */
+ void Print(Option_t* ="") const
+ {
+ std::cout << "Train: " << fName << " (" << fEscapedName << ")"
+ << std::endl;
+ fOptions.Show(std::cout);
+ if (fHelper) fHelper->Print();
+ }
+ /**
+ * Show the help
+ *
+ * @param o
+ *
+ * @return
+ */
+ Bool_t Help(std::ostream& o=std::cout, bool asProg=false)
+ {
+ if (!fOptions.Has("help")) return true;
+
+ if (asProg)
+ o << "Usage: runTrain --name=NAME --class=CLASS [OPTIONS]";
+ else
+ o << "Usage: RunTrain(NAME, CLASS, OPTIONS)";
+
+ o << "\n\nOptions:\n\n";
+ if (asProg) {
+ OptionList tmp(fOptions);
+ tmp.Add("name", "STRING", "Name of train", fName);
+ tmp.Add("class", "NAME", "Name of setup class", "");
+ tmp.Help(o," --");
+ }
+ else
+ fOptions.Help(o, " ");
+
+ o << "\n";
+
+ if (!fHelper && fOptions.Has("url")) {
+ TString url = fOptions.Get("url");
+ fHelper = Helper::Create(url.Data());
+ }
+ if (fHelper) {
+ o << fHelper->Desc() << " URL form:\n\n"
+ << " " << fHelper->UrlHelp() << "\n\n"
+ << "Options:\n";
+ fHelper->Options().Help(o, " ");
+ o << "\n";
+ }
+ else {
+ o << "Possible URL forms:\n\n";
+ Helper::ShowUrlHelp("LocalHelper");
+ Helper::ShowUrlHelp("ProofHelper");
+ Helper::ShowUrlHelp("LiteHelper");
+ Helper::ShowUrlHelp("AAFHelper");
+ Helper::ShowUrlHelp("AAFPluginHelper");
+ Helper::ShowUrlHelp("GridHelper");
+ o << "\n";
+ }
+ return false;
+ }
+ /**
+ * Run train. This will AcLic compile the setup script, create
+ * an object of that type with the given name, and then pass the
+ * options to it. Then, it will run the setup.
+ *
+ * @param name Train name
+ * @param cls Class name
+ * @param opts Comma seperated list of options
+ *
+ * @return true on success
+ */
+ static Bool_t Main(const TString& name, const TString& cls,
+ const TCollection* opts,
+ Bool_t asProg=true)
+ {
+ if (cls.IsNull()) {
+ Error("Main", "No class name specified");
+ return false;
+ }
+ if (name.IsNull()) {
+ Error("Main", "No train name specified");
+ return false;
+ }
+ Int_t error = 0;
+ Int_t r1 = gROOT->LoadMacro(Form("%s.C++g", cls.Data()), &error);
+ if (r1 < 0 || error) {
+ Error("Main", "Failed to load setup %s: %d", cls.Data(), error);
+ return false;
+ }
+
+ // Make our object using the interpreter
+ TString create = TString::Format("new %s(\"%s\")",
+ cls.Data(), name.Data());
+ gROOT->ProcessLine("gSystem->RedirectOutput(\"/dev/null\",\"w\");");
+ Long_t ret = gROOT->ProcessLine(create, &error);
+ gROOT->ProcessLine("gSystem->RedirectOutput(0);");
+ if (!ret || error) {
+ Error("Main", "Failed to make object of class %s: 0x%08lx/%d\n\t%s",
+ cls.Data(), ret, error, create.Data());
+ return false;
+ }
+ TrainSetup* train = reinterpret_cast<TrainSetup*>(ret);
+
+ // Now parse the options
+ if (!train->Options().Parse(opts)) {
+ Error("Main", "Failed to parse options");
+ return false;
+ }
+
+ // Check if we got a help request
+ if (train->Options().Has("help")) {
+ train->Help(std::cout, asProg);
+ return true;
+ }
+ // return train->Init();
+ return train->Run(asProg);
+ }
+protected:
+ //__________________________________________________________________
+ /**
+ * @{
+ * @Name Overloadable behaviour
+ */
+ //------------------------------------------------------------------
+ /**
+ * Create the analysis manager
+ *
+ * @param name Name of the analysis
+ *
+ * @return Created analysis manager
+ */
+ virtual AliAnalysisManager* CreateAnalysisManager(const char* name)
+ {
+ return new AliAnalysisManager(name,"Analysis Train");
+ }
+ //------------------------------------------------------------------
+ /**
+ * Create input handler
+ *
+ * @param type
+ *
+ * @return
+ */
+ virtual AliVEventHandler* CreateInputHandler(UShort_t type)
+ {
+ switch (type) {
+ case Helper::kESD: return new AliESDInputHandler();
+ case Helper::kAOD: return new AliAODInputHandler();
+ case Helper::kUser: return 0;
+ }
+ return 0;
+ }
+ //------------------------------------------------------------------
+ /**
+ * Create MC input handler
+ *
+ * @param type Run type (ESD or AOD)
+ * @param mc Assume monte-carlo input
+ *
+ * @return
+ */
+ virtual AliVEventHandler* CreateMCHandler(UShort_t /*type*/, bool mc)
+ {
+ if (!mc) return 0;
+ AliMCEventHandler* mcHandler = new AliMCEventHandler();
+ mcHandler->SetReadTR(true);
+ return mcHandler;
+ }
+ //------------------------------------------------------------------
+ /**
+ * Create output event handler
+ *
+ * @param type
+ *
+ * @return
+ */
+ virtual AliVEventHandler* CreateOutputHandler(UShort_t type)
+ {
+ AliAODHandler* ret = new AliAODHandler();
+ switch (type) {
+ case Helper::kESD:
+ ret->SetOutputFileName("AliAOD.root");
+ break;
+ case Helper::kAOD:
+ ret->SetOutputFileName("AliAOD.pass2.root");
+ break;
+ case Helper::kUser:
+ break;
+ }
+
+ return ret;
+ }
+ //------------------------------------------------------------------
+ /**
+ * Create physics selection, and add to manager
+ *
+ * @param mc Whether this is for MC
+ * @param mgr Manager
+ */
+ virtual void CreatePhysicsSelection(Bool_t mc, AliAnalysisManager* mgr)
+ {
+ if (fOptions.Has("bare-ps")) {
+ AliInputEventHandler* input =
+ dynamic_cast<AliInputEventHandler*> (mgr->GetInputEventHandler());
+ if (!input) return;
+
+ AliPhysicsSelection* ps = new AliPhysicsSelection();
+ if (mc) ps->SetAnalyzeMC();
+
+ input->SetEventSelection(ps);
+
+ return;
+ }
+ gROOT->Macro(Form("AddTaskPhysicsSelection.C(%d)", mc));
+ mgr->RegisterExtraFile("event_stat.root");
+ }
+ //------------------------------------------------------------------
+ /**
+ * Create centrality selection, and add to manager
+ *
+ * @param mc Whether this is for MC
+ * @param mgr Manager
+ */
+ virtual void CreateCentralitySelection(Bool_t mc, AliAnalysisManager* mgr)
+ {
+ gROOT->Macro("AddTaskCentrality.C");
+ const char* name = "CentralitySelection";
+ AliCentralitySelectionTask* ctask =
+ dynamic_cast<AliCentralitySelectionTask*>(mgr->GetTask(name));
+ if (!ctask) return;
+ if (mc) ctask->SetMCInput();
+ }
+ //------------------------------------------------------------------
+ /**
+ * Create analysis tasks. Must be overloaded by sub-class
+ *
+ * @param mgr Manager
+ */
+ virtual void CreateTasks(AliAnalysisManager* mgr)=0;
+ virtual const Char_t* ClassName() const = 0;
+ /* @} */
+ //__________________________________________________________________
+ /**
+ * @{
+ * @name Utility functions
+ */
+ /**
+ * Escape bad elements of the name
+ *
+ * @param name Name to escape
+ * @param datime Date and Time
+ *
+ * @return escaped name
+ */
+ static TString EscapeName(const char* name, const TString& datimeStr)
+ {
+ TString escaped = name;
+ char c[] = { ' ', '/', '@', 0 };
+ char* p = c;
+ while (*p) {
+ escaped.ReplaceAll(Form("%c", *p), "_");
+ p++;
+ }
+ if (!datimeStr.IsNull()) {
+ TDatime datime;
+ if (datimeStr.EqualTo("now", TString::kIgnoreCase))
+ datime.Set();
+ else
+ datime.Set(datimeStr.Data());
+ if (datime.GetYear() <= 1995 ||
+ datime.GetMonth() == 0 ||
+ datime.GetDay() == 0) return escaped;
+ escaped.Append(Form("_%04d%02d%02d_%02d%02d",
+ datime.GetYear(),
+ datime.GetMonth(),
+ datime.GetDay(),
+ datime.GetHour(),
+ datime.GetMinute()));
+ }
+ return escaped;
+ }
+ /**
+ * Make our working directory if so requested
+ *
+ * @return true on success
+ */
+ Bool_t SetupWorkingDirectory()
+ {
+ // Get the name of the target directory
+ TString& nam = fEscapedName;
+
+ // Check if the directory exists already
+ Bool_t exists = gSystem->AccessPathName(nam.Data()) == 0;
+ if (fHelper->Operation() == Helper::kTerminate && !exists) {
+ Error("SetupWorkingDirectory", "File/directory %s does not exists",
+ nam.Data());
+ return false;
+ }
+
+ Bool_t overwrite = fOptions.Has("overwrite");
+ // If we're not allowed to overwrite, then complain
+ if (!overwrite && exists) {
+ Error("SetupWorkingDirectory", "File/directory %s already exists",
+ nam.Data());
+ return false;
+ }
+
+ // Make the target directory if it doesn't exists
+ if (!exists) {
+ if (gSystem->MakeDirectory(nam.Data())) {
+ Error("SetupWorkingDirectory", "Failed to make directory '%s'",
+ nam.Data());
+ return false;
+ }
+ }
+
+ // Change directory to target directory
+ if (!gSystem->ChangeDirectory(nam.Data())) {
+ Error("SetupWorkingDirectory", "Failed to change directory to %s",
+ nam.Data());
+ return false;
+ }
+ Info("SetupWorkingDirectory", "Made subdirectory %s, and cd'ed there",
+ nam.Data());
+ return true;
+ }
+ /**
+ * Save the setup as a ROOT script and possibly also a shell script
+ *
+ * @param asShellScript If true, also save as shell script
+ */
+ virtual void SaveSetup(Bool_t asShellScript)
+ {
+ if (asShellScript)
+ SaveSetupShell("rerun", ClassName(), fName, fOptions);
+ SaveSetupROOT("ReRun", ClassName(), fName, fOptions);
+ }
+ /**
+ * Save a setup as a shell script
+ *
+ * @param out Output name of shell script
+ * @param cls Class of the train
+ * @param name Name of the train
+ * @param opts Option list
+ */
+ static void SaveSetupShell(const TString& out, const TString& cls,
+ const TString& name, const OptionList& opts)
+ {
+ std::ofstream o(Form("%s.sh", out.Data()));
+ o << "#!/bin/bash\n\n"
+ << "class=\"" << cls << "\"\n"
+ << "name=\"" << name << "\"\n\n"
+ << "# Available options\n"
+ << "# \n";
+ opts.Help(o, "# --");
+ o << "#\n"
+ << "opts=(--class=$class \\\n"
+ << " --name=$name";
+ opts.Store(o, " \\\n --", "", true);
+ o << ")\n\n"
+ << "echo \"Running runTrain ${opts[@]} $@\"\n"
+ << "runTrain \"${opts[@]}\" $@\n\n"
+ << "# EOF" << std::endl;
+ o.close();
+ gSystem->Exec(Form("chmod a+x %s.sh", out.Data()));
+ }
+ /**
+ * Save a setup as a ROOT script
+ *
+ * @param out Output name of shell script
+ * @param cls Class of the train
+ * @param name Name of the train
+ * @param opts Option list
+ */
+ static void SaveSetupROOT(const TString& out, const TString& cls,
+ const TString& name, const OptionList& opts)
+ {
+ OptionList tmp(opts);
+ tmp.Remove("url");
+ std::ofstream o(Form("%s.C", out.Data()));
+ o << "/* Available options:\n"
+ << " *\n";
+ tmp.Help(o, " * ");
+ o << " */\n"
+ << "Bool_t " << out << "()\n"
+ << "{\n"
+ << " TString name(\"" << name << "\");\n"
+ << " TString cls(\"" << cls << "\");\n"
+ << " TString uri(\"" << opts.Get("url") << "\");\n"
+ << " TString opts(";
+ tmp.Store(o, "\"", ",\"\n ", false);
+ o << ");\n\n"
+ << " gROOT->LoadMacro(\"RunTrain.C\");\n\n"
+ << " return RunTrain(name, cls, uri, opts);\n"
+ << "}\n"
+ << "//\n"
+ << "// EOF\n"
+ << "//" << std::endl;
+ o.close();
+ }
+ /* @} */
+ TString fName;
+ TString fEscapedName;
+ OptionList fOptions;
+ Helper* fHelper;
+};
+#endif
--- /dev/null
+#!/bin/sh
+
+type=
+proto=
+host=
+file=
+opts=
+anchor="esdTree"
+dbg=
+ex=
+par=0
+dir=/data/alice/data/ppb/LHC12g/pass1/188359/
+
+usage()
+{
+cat<<EOF
+Usage: $0 -t TYPE [OPTIONS]
+
+Options:
+ -t,--type TYPE Set type of job [$type]
+ -v,--verbose LEVEL Set verbosity
+ -d,--debug Run in debugger [$dbg]
+ -b,--batch Run batch mode [$ex]
+ -p,--par Run with PAR files [$par]
+ -h,--help Show this help
+
+TYPE is one of
+
+ local Run over local files
+ lite Run in Proof-lite
+ hehi Run on hehi Proof farm
+ caf Run on CAF
+ caf plugin Run on CAF using plugin
+ grid Run in AliEn - Real data
+ grid hijing Run in AliEn - Hijing simulation
+ grid dpmjet Run in AliEn - DPMJet simulation
+EOF
+}
+
+while test $# -gt 0 ; do
+ case $1 in
+ -t|--type) type=$2 ; shift ;;
+ -d|--debug) dbg="gdb --args" ;;
+ -b|--batch) ex="$ex --batch" ;;
+ -v|--verbose) ex="$ex --verbose=$2" ; shift ;;
+ -p|--par) par=1 ;;
+ -h|--help) usage ; exit 0 ;;
+ esac
+ shift
+done
+case $type in
+ local|lite)
+ proto=$type
+ file="$dir"
+ if test "x$type" = "xlite" ; then opts="workers=10" ; fi
+ ;;
+ hehi*)
+ proto=proof
+ host="hehi00.nbi.dk";
+ file="/default/cholm/LHC12g_pass1_uncalibrated_ESD_188359_partial";
+ opts="mode=default&dsname"
+ if test $par -gt 0 ; then opts="$opts&par=tasks" ; fi
+ ;;
+ caf*)
+ proto=proof
+ host="alice-caf.cern.ch";
+ file="/alice/data/LHC12g_000188359_ESDs_p1_uncalibrated";
+ opts="mode=default&workers=60&aliroot=v5-03-68-AN&dsname"
+ if test $par -gt 0 ; then opts="$opts&par=tasks" ; fi
+ case $type in
+ *plugin*) opts="${opts}&plugin" ;;
+ esac
+ ;;
+ grid*)
+ proto=alien
+ opts="run=188359-188359"
+ case $type in
+ *hijing*)
+ file="/alice/sim/2012/LHC12g1/";
+ opts="$opts&pattern=*/AliESDs.root&mc"
+ ;;
+ *dpmjet*)
+ file="/alice/sim/2012/LHC12g4a/";
+ opts="$opts&pattern=*/AliESDs.root&mc"
+ ;;
+ *)
+ file="/alice/data/2012/LHC12g";
+ opts="$opts&pattern=ESDs/pass1_uncalibrated/*/AliESDs.root"
+ ;;
+ esac
+ if test $par -gt 0 ; then opts="$opts&par=tasks" ; fi
+ ;;
+ help*)
+ ;;
+esac
+
+echo "Building runTrain ..."
+bld="g++ -g `root-config --cflags --glibs` \
+ -lVMC -lGeom -lMinuit -lXMLIO -lTree -lTreePlayer \
+ -I$ALICE_ROOT/include -L$ALICE_ROOT/lib/tgt_${ALICE_TARGET} \
+ -lSTEERBase -lESD -lAOD -lANALYSIS -lOADB -lANALYSISalice \
+ trainMain.cxx -o runTrain"
+echo $bld
+$bld || exit 1
+
+echo "Cleaning previous run ($name) ..."
+name=test_`echo $type | tr ' \t&/' '_'`
+rm -rf $name
+
+echo "Running the job ..."
+cmd="./runTrain --class=MakeAODTrain --name=$name \
+ --url=${proto}://${host}/${file}?${opts}#${anchor} \
+ --sys=3 --snn=5023 --field=-5 --cent \
+ $ex $@"
+echo "$dbg $cmd"
+$dbg $cmd
+
+echo "done"
--- /dev/null
+/*
+ To compile, do
+
+ rootcint -f OptionDict.C -c Option.C
+ g++ `root-config --cflags --libs` \
+ -lVMC -lGeom -lMinuit -lXMLIO -lTree -lTreePlayer \
+ -I$ALICE_ROOT/include -L$ALICE_ROOT/lib/tgt_${ALICE_TARGET} \
+ -lSTEERBase -lESD -lAOD -lANALYSIS -lOADB -lANALYSISalice \
+ trainMain.cxx -o runTrain
+*/
+
+#include "AvailableSoftware.C"
+#include "ChainBuilder.C"
+#include "ParUtilities.C"
+#include "OutputUtilities.C"
+#include "Option.C"
+#include "Helper.C"
+#include "LocalHelper.C"
+#include "ProofHelper.C"
+#include "LiteHelper.C"
+#include "AAFHelper.C"
+#include "PluginHelper.C"
+#include "AAFPluginHelper.C"
+#include "GridHelper.C"
+#include "TrainSetup.C"
+
+#include <TGApplication.h>
+#include <TROOT.h>
+#include <TList.h>
+#include <TObjString.h>
+#include <TString.h>
+
+#include <iostream>
+#include <iomanip>
+
+/**
+ * Custom timer to do a deferred start after the application
+ * has been started
+ */
+struct Deferred : public TTimer
+{
+ Deferred(const TString& name, const TString& cls,
+ const TCollection* opts)
+ : TTimer(1000, false),
+ fName(name),
+ fClass(cls),
+ fOptions(opts)
+ {
+ Start(1000, true);
+ }
+ Bool_t Notify()
+ {
+ // gSystem->RemoveTimer(this);
+ Info("Notify", "Will run train setup: %s (%s)",
+ fName.Data(), fClass.Data());
+ return TrainSetup::Main(fName, fClass, fOptions);
+ }
+ TString fName;
+ TString fClass;
+ const TCollection* fOptions;
+};
+
+/**
+ * Append directory to header and script search path
+ *
+ * @param dir Directory
+ *
+ * @ingroup pwglf_forward_trains_run
+ */
+void AppendPath(const char* dir)
+{
+ gROOT->SetMacroPath(Form("%s:%s",gROOT->GetMacroPath(), dir));
+ gSystem->AddIncludePath(Form("-I%s", dir));
+}
+/**
+ * Print a fake option description. Used for options specific to this
+ * program.
+ *
+ * @param o Output stream
+ * @param opt Option (including meta argument)
+ * @param desc Option description.
+ *
+ * @ingroup pwglf_forward_trains_run
+ */
+void PrintFakeOption(std::ostream& o, const char* opt, const char* desc)
+{
+ o << " --" << std::left << std::setw(30) << opt << " " << desc << std::endl;
+}
+
+/**
+ * Print usage information
+ *
+ * @param progname Program name
+ * @param o Output stream
+ * @param r Optional runner.
+ *
+ * @ingroup pwglf_forward_trains_run
+ */
+void Usage(const char* progname, std::ostream& o)
+{
+ o << "Usage: " << progname << " --class=CLASS --name=NAME [OPTIONS]\n\n"
+ << "PROGRAM OPTIONS:\n";
+ PrintFakeOption(o, "class=CLASS", "Train class");
+ PrintFakeOption(o, "name=NAME", "Name of train");
+ PrintFakeOption(o, "include=DIRECTORY", "Append dir to macro/header path");
+ PrintFakeOption(o, "batch", "Batch mode");
+}
+
+int
+main(int argc, char** argv)
+{
+ TList optList;
+ TString name;
+ TString cls;
+ Bool_t batch = false;
+ Bool_t help = false;
+
+ // --- Parse options -----------------------------------------------
+ for (int i = 1; i < argc; i++) {
+ if (argv[i][0] == '-' && argv[i][1] == '-') {
+ TString arg(argv[i]);
+ TString val("");
+ arg.ReplaceAll("\"'", "");
+ Int_t eq = arg.Index("=");
+ if (eq != kNPOS) val = arg(eq+1, arg.Length()-eq-1);
+ if (arg.BeginsWith("--class")) cls = val;
+ else if (arg.BeginsWith("--name")) name = val;
+ else if (arg.BeginsWith("--include")) AppendPath(val);
+ else if (arg.BeginsWith("--batch")) batch = true;
+ else if (arg.BeginsWith("--help")) help = true;
+ else optList.Add(new TObjString(&(argv[i][2])));
+ }
+ }
+ // --- check for help ----------------------------------------------
+ if (help && cls.IsNull()) {
+ if (cls.IsNull()) {
+ Usage(argv[0], std::cout);
+ return 0;
+ }
+ optList.Add(new TObjString("help"));
+ }
+
+ // --- Check name and class ----------------------------------------
+ if (name.IsNull()) {
+ Error("main", "No name specified");
+ return 1;
+ }
+ if (cls.IsNull()) {
+ Error("main", "No class specified");
+ return 1;
+ }
+
+ // --- Setup script path -------------------------------------------
+ const char* aliPath = gSystem->ExpandPathName("$ALICE_ROOT");
+ const char* fwdPath = gSystem->ExpandPathName("$ALICE_ROOT/PWGLF/FORWARD/");
+ AppendPath(aliPath);
+ AppendPath(Form("%s/include", aliPath));
+ AppendPath(Form("%s/trains", fwdPath));
+ AppendPath(Form("%s/analysis2", fwdPath));
+
+
+ // --- Set-up Application ------------------------------------------
+ TApplication* app = 0;
+ gROOT->SetBatch(true);
+ if (!batch) {
+ gROOT->SetBatch(false);
+ app = new TGApplication("runTrain", 0, 0);
+ app->InitializeGraphics();
+ }
+
+ // --- run, possibly in a timer ------------------------------------
+ Bool_t ret = true;
+ if (batch)
+ ret = TrainSetup::Main(name, cls, &optList);
+ else {
+ new Deferred(name, cls, &optList);
+ Info("main", "Running application (%s)", gROOT->IsBatch()
+ ? "batch" : "normal");
+ gApplication->Run();
+ }
+
+ // --- Return ------------------------------------------------------
+ return ret ? 0 : 1;
+}
+//
+// EOF
+//
+
+
+