--- /dev/null
+/**
+ * @file AOD.C
+ * @author Christian Holm Christensen <cholm@nbi.dk>
+ * @date Wed Sep 24 15:02:00 2014
+ *
+ * @brief Master script for AOD production.
+ *
+ * @note Do not modify this script.
+ *
+ * This script reads in two other scripts
+ *
+ * - GRP.C to load the global run parameters for the selected run,
+ * such as collision system, energy, etc.
+ *
+ * - AODConfig.C which defines a number of functions that return
+ * either true or false. The tasks added depends on these functions
+ */
+/** Path to CDB */
+const char *cdbPath = "raw://";
+
+/**
+ * Interface (pure virtual) that all configuration classes must
+ * implement.
+ */
+struct VirtualAODCfg
+{
+ /**
+ * @{
+ * @name Plug-in settings
+ * Settings that make sense when using the Alien plugin
+ */
+ /** @return Connect to CDB */
+ virtual Bool_t UseCDBconnect() const = 0;
+ /** @return use physics selection */
+ virtual Bool_t UsePhysicsSelection() const = 0;
+ /** @return use tender wagon */
+ virtual Bool_t UseTender() const = 0;
+ /** @return centrality */
+ virtual Bool_t UseCentrality() const = 0;
+ /** @return use V0 correction in tender */
+ virtual Bool_t UseV0tender() const = 0;
+ /** @return activate debugging */
+ virtual Bool_t UseDBG() const = 0;
+ /** @return use MC info */
+ virtual Bool_t UseMC() const = 0;
+ /** @return use Kinematics filter */
+ virtual Bool_t UseKFILTER() const = 0;
+ /** @return use track references */
+ virtual Bool_t UseTR() const = 0;
+ /** @return do not change */
+ virtual Bool_t UseCORRFW() const = 0;
+ /** @return use AOD tags */
+ virtual Bool_t UseAODTAGS() const = 0;
+ /** @return use sys info */
+ virtual Bool_t UseSysInfo() const = 0;
+ /* @} */
+
+ /**
+ * @{
+ * @name Modules
+ * Analysis modules to be included. Some may not be yet fully implemented.
+ */
+ /** @return Analysis produces an AOD or dAOD's */
+ virtual Bool_t UseAODhandler() const = 0;
+ /** @return ESD to AOD filter (barrel + muon tracks) */
+ virtual Bool_t UseESDfilter() const = 0;
+ /** @return Use Muon train */
+ virtual Bool_t UsePWGMuonTrain() const = 0;
+ /** @return Task that copies only muon events */
+ virtual Bool_t UseMUONcopyAOD() const = 0;
+ /** @return Jet analysis (PWG4) */
+ virtual Bool_t UseJETAN() const = 0;
+ /** @return Jet delta AODs */
+ virtual Bool_t UseJETANdelta() const = 0;
+ /** @return Vertexing HF task (PWG3) */
+ virtual Bool_t UsePWGHFvertexing() const = 0;
+ /** @return JPSI filtering (PWG3) */
+ virtual Bool_t UsePWGDQJPSIfilter() const = 0;
+ /** @return D0->2 hadrons (PWG3) */
+ virtual Bool_t UsePWGHFd2h() const = 0;
+ /** @return PID response */
+ virtual Bool_t UsePIDResponse() const = 0;
+ /** @return Forward mult task (PWGLF) */
+ virtual Bool_t UsePWGLFForward() const = 0;
+ /* @} */
+};
+
+VirtualAODCfg* aodCfg = 0;
+
+//====================================================================
+/**
+ * Load a library/module
+ *
+ * @param module Library/module name
+ *
+ * @return true on success
+ */
+Bool_t LoadLibrary(const char *module)
+{
+ // Load a module library in a given mode. Reports success.
+ Int_t result = 0;
+ TString mod(module);
+ ::Info("LoadLibrary", "Loading %s", module);
+ gROOT->IncreaseDirLevel();
+
+ if (mod.IsNull()) {
+ ::Error("AnalysisTrainNew.C::LoadLibrary", "Empty module name");
+ gROOT->DecreaseDirLevel();
+ return kFALSE;
+ }
+
+ // If a library is specified, just load it
+ if (mod.EndsWith(".so")) {
+ mod.Remove(mod.Index(".so"));
+ ::Info("LoadLibrary", "Loading .so: %s", mod.Data());
+ result = gSystem->Load(mod);
+ if (result < 0) {
+ ::Error("AnalysisTrainNew.C::LoadLibrary",
+ "Could not load library %s", module);
+ }
+ gROOT->DecreaseDirLevel();
+ return (result >= 0);
+ }
+ // Check if the library is already loaded
+ if (strlen(gSystem->GetLibraries(Form("%s.so", module), "", kFALSE)) > 0) {
+ ::Info("LoadLibrary", "Module %s.so already loaded", module);
+ gROOT->DecreaseDirLevel();
+ return kTRUE;
+ }
+
+ ::Info("LoadLibrary", "Trying to load lib%s.so", module);
+ result = gSystem->Load(Form("lib%s.so", module));
+ if (result < 0)
+ ::Error("AnalysisTrainNew.C::LoadLibrary",
+ "Could not load module %s", module);
+ ::Info("LoadLibrary", "Module %s, successfully loaded", module);
+ gROOT->DecreaseDirLevel();
+ return (result >= 0);
+}
+
+//====================================================================
+/**
+ * Load common libraries
+ *
+ * @return true on sucess
+ */
+Bool_t LoadCommonLibraries()
+{
+ // Load common analysis libraries.
+ if (!gSystem->Getenv("ALICE_ROOT")) {
+ ::Error("AnalysisTrainNew.C::LoadCommonLibraries",
+ "Analysis train requires that analysis libraries are "
+ "compiled with a local AliRoot");
+ return kFALSE;
+ }
+
+ Bool_t success = kTRUE;
+ // Load framework classes. Par option ignored here.
+ success &= LoadLibrary("libSTEERBase.so");
+ success &= LoadLibrary("libESD.so");
+ success &= LoadLibrary("libAOD.so");
+ success &= LoadLibrary("libANALYSIS.so");
+ success &= LoadLibrary("libOADB.so");
+ success &= LoadLibrary("libANALYSISalice.so");
+ success &= LoadLibrary("libESDfilter.so");
+ success &= LoadLibrary("libCORRFW.so");
+ gROOT->ProcessLine(".include $ALICE_ROOT/include");
+ if (success) {
+ ::Info("AnalysisTrainNew.C::LoadCommodLibraries",
+ "Load common libraries: SUCCESS");
+ ::Info("AnalysisTrainNew.C::LoadCommodLibraries",
+ "Include path for Aclic compilation:\n%s",
+ gSystem->GetIncludePath());
+ } else {
+ ::Info("AnalysisTrainNew.C::LoadCommodLibraries",
+ "Load common libraries: FAILED");
+ }
+ return success;
+}
+
+//====================================================================
+/**
+ * Load libraries needed by the train
+ *
+ * @param useTender
+ * @param doCDBconnect
+ * @param iESDfilter
+ * @param iPWGMuonTrain
+ * @param iJETAN
+ * @param iJETANdelta
+ * @param iPWGHFvertexing
+ * @param iPWGHFd2h
+ * @param iPWGDQJPSIfilter
+ *
+ * @return true on success
+ */
+Bool_t LoadAnalysisLibraries()
+{
+ // Load common analysis libraries.
+ if (aodCfg->UseTender() || aodCfg->UseCDBconnect()) {
+ if (!LoadLibrary("TENDER") ||!LoadLibrary("TENDERSupplies")) return kFALSE;
+ }
+ // CDBconnect
+ if ((aodCfg->UseCDBconnect() && !aodCfg->UseTender())
+ && !LoadLibrary("PWGPP")) return false;
+ if ((aodCfg->UseESDfilter() || aodCfg->UsePWGMuonTrain())
+ && !LoadLibrary("PWGmuon")) return kFALSE;
+ // JETAN
+ if ((aodCfg->UseJETAN() || aodCfg->UseJETANdelta())
+ && !LoadLibrary("JETAN")) return kFALSE;
+ if (aodCfg->UseJETANdelta()) { // CINT doesn't like long '||' chains
+ if (!LoadLibrary("CGAL")) return false;
+ if (!LoadLibrary("fastjet")) return false;
+ if (!LoadLibrary("siscone")) return false;
+ if (!LoadLibrary("SISConePlugin")) return false;
+ if (!LoadLibrary("FASTJETAN")) return false;
+ }
+
+ // PWG3 Vertexing HF
+ if ((aodCfg->UsePWGHFvertexing() || aodCfg->UsePWGHFd2h())) {
+ // CINT doesn't like long '||' chains
+ if (!LoadLibrary("PWGflowBase")) return false;
+ if (!LoadLibrary("PWGflowTasks")) return false;
+ // if (!LoadLibrary("PWGTRD")) return false;
+ if (!LoadLibrary("PWGHFvertexingHF")) return false;
+ }
+
+ // PWG3 dielectron
+ if (aodCfg->UsePWGDQJPSIfilter() &&
+ !LoadLibrary("PWGDQdielectron")) return kFALSE;
+
+ ::Info("AnalysisTrainNew.C::LoadAnalysisLibraries",
+ "Load other libraries: SUCCESS");
+ return kTRUE;
+}
+
+//====================================================================
+/**
+ * Add tasks to the train
+ *
+ * @param cdb_location
+ */
+void AddAnalysisTasks(const char *cdb_location)
+{
+ // === Add all analysis task wagons to the train ===================
+ //
+ // --- Some constants ----------------------------------------------
+ TString ali = "$(ALICE_ROOT)";
+ TString ana = ali + "/ANALYSIS";
+ TString pwghf = ali + "/PWGHF";
+ TString pwglf = ali + "/PWGLF";
+ TString pwgje = ali + "/PWGJE";
+ TString pwgdq = ali + "/PWGDQ";
+ TString pwgpp = ali + "/PWGPP";
+
+ // --- Get the analysis manager ------------------------------------
+ AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
+ AliAnalysisManager::SetCommonFileName("AODQA.root");
+
+ // --- PIDResponse(JENS) -------------------------------------------
+ if (aodCfg->UsePIDResponse()) {
+ gROOT->LoadMacro(ana+"/macros/AddTaskPIDResponse.C");
+ AliAnalysisTaskPIDResponse *PIDResponse = AddTaskPIDResponse(kTRUE);
+ }
+
+ // --- CDB connection ----------------------------------------------
+ if (aodCfg->UseCDBconnect() && !aodCfg->UseTender()) {
+ gROOT->LoadMacro(pwgpp+"/PilotTrain/AddTaskCDBconnect.C");
+ AliTaskCDBconnect *taskCDB = AddTaskCDBconnect(cdb_location, grp->run);
+ if (!taskCDB) return;
+
+ AliCDBManager *cdb = AliCDBManager::Instance();
+ // cdb->SetDefaultStorage(cdb_location);
+ cdb->SetDefaultStorageFromRun(grp->run);
+ }
+ if (aodCfg->UseTender()) {
+ gROOT->LoadMacro(ana+"/TenderSupplies/AddTaskTender.C");
+ AliAnalysisTaskSE *tender = AddTaskTender(aodCfg->UseV0tender());
+ }
+
+ // --- Physics selection -------------------------------------------
+ if (aodCfg->UsePhysicsSelection()) {
+ // Physics selection task
+ gROOT->LoadMacro(ana+"/macros/AddTaskPhysicsSelection.C");
+ mgr->RegisterExtraFile("event_stat.root");
+ AliPhysicsSelectionTask *physSelTask =
+ AddTaskPhysicsSelection(aodCfg->UseMC());
+ }
+
+ // --- Centrality (only Pb-Pb) -------------------------------------
+ if (aodCfg->UseCentrality()) {
+ gROOT->LoadMacro(ana+"/macros/AddTaskCentrality.C");
+ AliCentralitySelectionTask *taskCentrality = AddTaskCentrality();
+ taskCentrality->SetMCInput();
+ }
+
+ // --- PWGLF - Forward (cholm@nbi.dk) -----------------------------
+ if (aodCfg->UsePWGLFForward() && aodCfg->UsePhysicsSelection()) {
+ gROOT->LoadMacro(pwglf+"/FORWARD/analysis2/AddTaskForwardMult.C");
+ // Arguments are
+ // mc Assume MC input
+ // runNo Run number to do local initialization - not used
+ // sys Collision system (1:pp,2:PbPb,3:pPb/Pbp) - not used
+ // sNN Collision energy in GeV - not used
+ // field L3 magnetic field strength - not used
+ // config Configuration script
+ // corrdir Possible directory containing custom OADB corrections
+ // HACK load custom corrections
+ Info("", "Adding forward AOD task with mc=%d",aodCfg->UseMC() && aodCfg->UseTR());
+ AddTaskForwardMult(aodCfg->UseMC() && aodCfg->UseTR(),0,0,0,0,
+ "ForwardAODConfig.C",".");
+ gROOT->LoadMacro(pwglf+"/FORWARD/analysis2/AddTaskCentralMult.C");
+ AddTaskCentralMult(aodCfg->UseMC() && aodCfg->UseTR(),0,0,0,0,
+ "CentralAODConfig.C");
+ const char* hack2="AliForwardCorrectionManager::Instance().Print(\"R\")";
+ gROOT->ProcessLine(hack2);
+ }
+
+
+ // --- ESD filter --------------------------------------------------
+ if (aodCfg->UseESDfilter()) {
+ // ESD filter task configuration.
+ gROOT->LoadMacro(ana+"/ESDfilter/macros/AddTaskESDFilter.C");
+ if (aodCfg->UseMUONcopyAOD()) {
+ printf("Registering delta AOD file\n");
+ mgr->RegisterExtraFile("AliAOD.Muons.root");
+ mgr->RegisterExtraFile("AliAOD.Dimuons.root");
+ }
+ UInt_t runFlag = (grp->Year()%100)*100;
+ AliAnalysisTaskESDfilter *taskesdfilter =
+ AddTaskESDFilter(aodCfg->UseKFILTER(),
+ aodCfg->UseMUONcopyAOD(), // write Muon AOD
+ kFALSE, // write dimuon AOD
+ kFALSE, // usePhysicsSelection
+ kFALSE, // centrality OBSOLETE
+ kTRUE, // enable TPS only tracks
+ kFALSE, // disable cascades
+ kFALSE, // disable kinks
+ runFlag); // run flag (YY00)
+ }
+
+ TString configPWGHFd2h =
+ (grp->IsPP() ?
+ pwghf+"/vertexingHF/ConfigVertexingHF.C" :
+ pwghf+"/vertexingHF/ConfigVertexingHF_Pb_AllCent.C");
+
+ // --- PWG3 vertexing ----------------------------------------------
+ if (aodCfg->UsePWGHFvertexing()) {
+ gROOT->LoadMacro(pwghf+"/vertexingHF/macros/AddTaskVertexingHF.C");
+
+ if (!aodCfg->UsePWGHFd2h())
+ TFile::Cp(gSystem->ExpandPathName(configPWG3d2h.Data()),
+ "file:ConfigVertexingHF.C");
+
+ AliAnalysisTaskSEVertexingHF *taskvertexingHF = AddTaskVertexingHF();
+ if (!taskvertexingHF)
+ ::Warning("AnalysisTrainNew",
+ "AliAnalysisTaskSEVertexingHF cannot run for this train "
+ "conditions - EXCLUDED");
+ else
+ mgr->RegisterExtraFile("AliAOD.VertexingHF.root");
+
+ taskvertexingHF->SelectCollisionCandidates(0);
+ }
+
+ // ---- PWG3 JPSI filtering (only pp) ------------------------------
+ if (aodCfg->UsePWGDQJPSIfilter() && (iCollision==0)) {
+ gROOT->LoadMacro(pwgdq+"/dielectron/macros/AddTaskJPSIFilter.C");
+ AliAnalysisTaskSE *taskJPSIfilter = AddTaskJPSIFilter();
+
+ if (!taskJPSIfilter)
+ ::Warning("AnalysisTrainNew",
+ "AliAnalysisTaskDielectronFilter cannot run for this train "
+ "conditions - EXCLUDED");
+ else
+ mgr->RegisterExtraFile("AliAOD.Dielectron.root");
+
+ taskJPSIfilter->SelectCollisionCandidates(0);
+ }
+
+ // --- PWG3 D2h ----------------------------------------------------
+ if (aodCfg->UsePWGHFd2h()) {
+ gROOT->LoadMacro(pwghf+"/vertexingHF/AddD2HTrain.C");
+ TFile::Cp(gSystem->ExpandPathName(configPWGHFd2h.Data()),
+ "file:ConfigVertexingHF.C");
+ AddD2HTrain(kFALSE, 1,0,0,0,0,0,0,0,0,0,0);
+ }
+
+ // --- Jet analysis ------------------------------------------------
+
+ // Configurations flags, move up?
+ if (aodCfg->UseJETAN()) {
+#if 1
+ Warning("", "JET analysis disabled - major restructuring ofg JETAN");
+#else
+ TString jetAOD = "AliAOD.Jets.root";
+ UInt_t highPtMask = 768;// from esd filter
+ TString subtractBranches = "";
+ UInt_t psFlag = 0;
+
+ Info("", "Loading macro %s/macros/AddTaskJets.C", pwgje.Data());
+ gROOT->LoadMacro(pwgje+"/macros/AddTaskJets.C");
+ // Default jet reconstructor running on ESD's
+ // no background subtraction
+ AliAnalysisTask* task = AddTaskJets("AOD","UA1",0.4F,highPtMask,1.F,0);
+ if (!task)
+ ::Fatal("AnalysisTrainNew",
+ "AliAnalysisTaskJets cannot run for this train "
+ "conditions - EXCLUDED");
+
+ AliAnalysisTaskJets* taskjets = static_cast<AliAnalysisTaskJets*>(task);
+ if(!jetAOD.IsNull()) taskjets->SetNonStdOutputFile(jetAOD);
+
+ if (aodCfg->UseJETANdelta()) {
+ // need to modify this accordingly in the add task jets
+ // AddTaskJetsDelta("AliAOD.Jets.root");
+ mgr->RegisterExtraFile(jetAOD);
+ TString cTmp("");
+
+ if(grp->IsAA()){
+ // UA1 intrinsic background subtraction
+ // background subtraction
+ taskjets = AddTaskJets("AOD","UA1",0.4,highPtMask,1.,2);
+ if(!jetAOD.IsNull()) taskjets->SetNonStdOutputFile(jetAOD);
+ }
+ // SICONE
+ //no background subtration to be done later....
+ taskjets = AddTaskJets("AOD","SISCONE",0.4,highPtMask,0.15,0);
+ if(!jetAOD.IsNull()) taskjets->SetNonStdOutputFile(jetAOD.Data());
+ cTmp = taskjets->GetNonStdBranch();
+ if(!cTmp.IsNull()) subtractBranches += Form("%s ",cTmp.Data());
+
+ // Add the clusters..
+ gROOT->LoadMacro(pwgje+"/macros/AddTaskJetCluster.C");
+ AliAnalysisTaskJetCluster *taskCl = 0;
+ Float_t fCenUp = 0;
+ Float_t fCenLo = 0;
+ Float_t fTrackEtaWindow = 0.9;
+ // this one is for the background and random jets, random cones
+ // with no skip
+ taskCl = AddTaskJetCluster("AOD","",highPtMask,
+ psFlag,"KT",0.4,0,1,
+ jetAOD,0.15,
+ fTrackEtaWindow,0);
+ taskCl->SetBackgroundCalc(kTRUE);
+ taskCl->SetNRandomCones(10);
+ taskCl->SetCentralityCut(fCenLo,fCenUp);
+ taskCl->SetGhostEtamax(fTrackEtaWindow);
+ TString bkgBranch = Form("%s_%s",
+ AliAODJetEventBackground::StdBranchName(),
+ taskCl->GetJetOutputBranch());
+
+ taskCl = AddTaskJetCluster("AOD", "", highPtMask, psFlag, "ANTIKT",
+ 0.4, 2, 1, jetAOD, 0.15);
+ taskCl->SetCentralityCut(fCenLo,fCenUp);
+ if(grp->IsAA()) taskCl->SetBackgroundBranch(bkgBranch.Data());
+
+ taskCl->SetNRandomCones(10);
+ subtractBranches += Form("%s ",taskCl->GetJetOutputBranch());
+
+ taskCl = AddTaskJetCluster("AOD", "", highPtMask, psFlag, "ANTIKT",
+ 0.2, 0 , 1, jetAOD, 0.15);
+ taskCl->SetCentralityCut(fCenLo,fCenUp);
+ if(grp->IsAA())taskCl->SetBackgroundBranch(bkgBranch);
+
+ subtractBranches += Form("%s ",taskCl->GetJetOutputBranch());
+
+ // DO THE BACKGROUND SUBTRACTION
+ if(grp->IsAA() && !subtractBranches.IsNull()) {
+ gROOT->LoadMacro(pwgje+"/macros/AddTaskJetBackgroundSubtract.C");
+ AliAnalysisTaskJetBackgroundSubtract *taskSubtract = 0;
+ taskSubtract = AddTaskJetBackgroundSubtract(subtractBranches,1,
+ "B0","B%d");
+ taskSubtract->SetBackgroundBranch(bkgBranch);
+ if(!jetAOD.IsNull()) taskSubtract->SetNonStdOutputFile(jetAOD.Data());
+ }
+ }
+#endif
+ }
+}
+
+
+
+//====================================================================
+/**
+ * Create the input chain
+ *
+ *
+ * @return Pointer to newly allocated train
+ */
+TChain *CreateChain()
+{
+ // Create the input chain
+ chain = new TChain("esdTree");
+ if (gSystem->AccessPathName("AliESDs.root"))
+ ::Error("AnalysisTrainNew.C::CreateChain",
+ "File: AliESDs.root not in ./data dir");
+ else
+ chain->Add("AliESDs.root");
+ if (chain->GetNtrees()) return chain;
+ return NULL;
+}
+
+//====================================================================
+/**
+ * Merge AOD output
+ *
+ */
+void AODMerge()
+{
+ // Merging method. No staging and no terminate phase.
+ TStopwatch timer; timer.Start();
+ TString outputDir = "wn.xml";
+ TString outputFiles = ("EventStat_temp.root," +
+ "AODQA.root," +
+ "AliAOD.root," +
+ "AliAOD.VertexingHF.root," +
+ "AliAOD.Muons.root," +
+ "AliAOD.Jets.root," +
+ "pyxsec_hists.root");
+ TString mergeExcludes = "";
+ TObjArray* tokens = outputFiles.Tokenize(",");
+ TIter iter(tokens);
+ TObjString* str = 0;
+ TString outputFile;
+ Bool_t merged = kTRUE;
+ while ((str = static_cast<TObjString*>(iter()))) {
+ outputFile = str->GetString();
+ // Skip already merged outputs
+ if (!gSystem->AccessPathName(outputFile)) {
+ printf("Output file <%s> found. Not merging again.",outputFile.Data());
+ continue;
+ }
+ if (mergeExcludes.Contains(outputFile.Data())) continue;
+ merged = AliAnalysisAlien::MergeOutput(outputFile, outputDir, 10, 0);
+ if (!merged) {
+ printf("ERROR: Cannot merge %s\n", outputFile.Data());
+ continue;
+ }
+ }
+ // all outputs merged, validate
+ ofstream out;
+ out.open("outputs_valid", ios::out);
+ out.close();
+ timer.Print();
+}
+
+//====================================================================
+/**
+ * Set-up and run AOD train
+ *
+ * @param run Run number
+ * @param xmlfile Collection
+ * @param stage Stage
+ */
+void AOD(UInt_t run, const char* xmlfile=0, Int_t stage=0)
+{
+ // -----------------------------------------------------------------
+ //
+ // Get GRP parameters. Defines global "grp" as a pointer to GRPData
+ //
+ gROOT->Macro(Form("GRP.C(%d)", run));
+ gROOT->Macro("AODConfig.C");
+
+ // --- Some settings -----------------------------------------------
+ // Set temporary merging directory to current one
+ gSystem->Setenv("TMPDIR", gSystem->pwd());
+ // Set temporary compilation directory to current one
+ gSystem->SetBuildDir(gSystem->pwd(), kTRUE);
+
+ // --- Friendly message --------------------------------------------
+ printf("===================================================\n");
+ printf("=========== RUNNING FILTERING TRAIN ==========\n");
+ printf("===================================================\n");
+ printf("= Configuring analysis train for:\n");
+ if (aodCfg->UsePhysicsSelection()) printf("= Physics selection");
+ if (aodCfg->UseTender()) printf("= TENDER");
+ if (aodCfg->UseESDfilter()) printf("= ESD filter");
+ if (aodCfg->UseMUONcopyAOD()) printf("= MUON copy AOD");
+ if (aodCfg->UseJETAN()) printf("= Jet analysis");
+ if (aodCfg->UseJETANdelta()) printf("= Jet delta AODs");
+ if (aodCfg->UsePWGHFvertexing()) printf("= PWGHF vertexing");
+ if (aodCfg->UsePWGDQJPSIfilter()) printf("= PWGDQ j/psi filter");
+ if (aodCfg->UsePWGHFd2h()) printf("= PWGHF D0->2 hadrons QA");
+
+ // Load common libraries and set include path
+ if (!LoadCommonLibraries()) {
+ ::Error("AnalysisTrain", "Could not load common libraries");
+ return;
+ }
+
+ // === Make the analysis manager and connect event handlers ========
+ //
+ // --- Analysis manager and load libraries -------------------------
+ AliAnalysisManager *mgr = new AliAnalysisManager("Filter","Production train");
+ if (aodCfg->UseSysInfo()) mgr->SetNSysInfo(100);
+ if (!LoadAnalysisLibraries()) {
+ ::Error("AnalysisTrain", "Could not load analysis libraries");
+ return;
+ }
+
+ // --- Create ESD input handler ------------------------------------
+ AliESDInputHandler *esdHandler = new AliESDInputHandler();
+ mgr->SetInputEventHandler(esdHandler);
+
+ // --- Monte Carlo handler -----------------------------------------
+ if (aodCfg->UseMC()) {
+ AliMCEventHandler* mcHandler = new AliMCEventHandler();
+ mgr->SetMCtruthEventHandler(mcHandler);
+ mcHandler->SetPreReadMode(1);
+ mcHandler->SetReadTR(aodCfg->UseTR());
+ }
+
+ // --- AOD output handler ------------------------------------------
+ if (aodCfg->UseAODhandler()) {
+ AliAODHandler* aodHandler = new AliAODHandler();
+ aodHandler->SetOutputFileName("AliAOD.root");
+ mgr->SetOutputEventHandler(aodHandler);
+ }
+
+ // --- Debugging if needed -----------------------------------------
+ if (aodCfg->UseDBG()) mgr->SetDebugLevel(3);
+
+ // === Set up tasks ================================================
+ //
+ // --- Create tasks ------------------------------------------------
+ AddAnalysisTasks(cdbPath);
+
+ // --- If merging, do so here and exit -----------------------------
+ if (stage > 0) {
+ AODMerge();
+ mgr->InitAnalysis();
+ mgr->SetGridHandler(new AliAnalysisAlien);
+ mgr->StartAnalysis("gridterminate",0);
+ return;
+ }
+ // === Run the analysis ============================================
+ //
+ // --- Make our chain ----------------------------------------------
+ TChain *chain = CreateChain();
+ if (!chain) return;
+
+ // --- Run the thing -----------------------------------------------
+ TStopwatch timer;
+ timer.Start();
+ mgr->SetSkipTerminate(kTRUE);
+ if (mgr->InitAnalysis()) {
+ mgr->PrintStatus();
+ mgr->StartAnalysis("local", chain);
+ }
+ timer.Print();
+}
+
+//
+// EOF
+//
+
--- /dev/null
+struct AODCfg : public VirtualAODCfg
+{
+ /**
+ * @{
+ * @name Plug-in settings
+ * Settings that make sense when using the Alien plugin
+ */
+ /** @return Connect to CDB */
+ virtual Bool_t UseCDBconnect() const { return true; }
+ /** @return use physics selection */
+ virtual Bool_t UsePhysicsSelection() const { return kTRUE; }
+ /** @return use tender wagon */
+ virtual Bool_t UseTender() const { return kFALSE; }
+ /** @return centrality */
+ virtual Bool_t UseCentrality() const { return kTRUE; }
+ /** @return use V0 correction in tender */
+ virtual Bool_t UseV0tender() const { return kFALSE; }
+ /** @return activate debugging */
+ virtual Bool_t UseDBG() const { return kTRUE; }
+ /** @return use MC info */
+ virtual Bool_t UseMC() const { return kTRUE; }
+ /** @return use Kinematics filter */
+ virtual Bool_t UseKFILTER() const { return kTRUE; }
+ /** @return use track references */
+ virtual Bool_t UseTR() const { return kTRUE; }
+ /** @return do not change */
+ virtual Bool_t UseCORRFW() const { return kFALSE; }
+ /** @return use AOD tags */
+ virtual Bool_t UseAODTAGS() const { return kFALSE; }
+ /** @return use sys info */
+ virtual Bool_t UseSysInfo() const { return kFALSE; }
+ /* @} */
+
+ /**
+ * @{
+ * @name Modules
+ * Analysis modules to be included. Some may not be yet fully implemented.
+ */
+ /** @return Analysis produces an AOD or dAOD's */
+ virtual Bool_t UseAODhandler() const { return true; }
+ /** @return ESD to AOD filter (barrel + muon tracks) */
+ virtual Bool_t UseESDfilter() const { return true; }
+ /** @return Use Muon train */
+ virtual Bool_t UsePWGMuonTrain() const { return true; }
+ /** @return Task that copies only muon events */
+ virtual Bool_t UseMUONcopyAOD() const { return true; }
+ /** @return Jet analysis (PWG4) */
+ virtual Bool_t UseJETAN() const { return false; }
+ /** @return Jet delta AODs */
+ virtual Bool_t UseJETANdelta() const { return false; }
+ /** @return Vertexing HF task (PWG3) */
+ virtual Bool_t UsePWGHFvertexing() const { return true; }
+ /** @return JPSI filtering (PWG3) */
+ virtual Bool_t UsePWGDQJPSIfilter() const { return false; }
+ /** @return D0->2 hadrons (PWG3) */
+ virtual Bool_t UsePWGHFd2h() const { return true; }
+ /** @return PID response */
+ virtual Bool_t UsePIDResponse() const { return true; }
+ /** @return Forward mult task (PWGLF) */
+ virtual Bool_t UsePWGLFForward() const { return true; }
+ /* @} */
+};
+
+void AODConfig()
+{
+ Info("AODConfig", "Creating configuration object");
+ // MUST create the global object "aodCfg" here!
+ aodCfg = new AODCfg();
+}
+//
+// EOF
+//
--- /dev/null
+#if !defined( __CINT__) || defined(__MAKECINT__)
+#include <TROOT.h>
+#include <TFile.h>
+#include <TError.h>
+#include <TH1.h>
+#include <TH2.h>
+#include <TF1.h>
+#include <TCanvas.h>
+#include <TVector3.h>
+#include <TPDGCode.h>
+#include <TParticle.h>
+
+#include "AliRunLoader.h"
+#include "AliLoader.h"
+#include "AliESDEvent.h"
+#include "AliESDv0.h"
+#include "AliESDcascade.h"
+#include "AliESDMuonTrack.h"
+#include "AliESDCaloCluster.h"
+#include "AliRun.h"
+#include "AliStack.h"
+#include "AliHeader.h"
+#include "AliGenEventHeader.h"
+#include "AliPID.h"
+#endif
+
+TH1F* CreateHisto(const char* name, const char* title,
+ Int_t nBins, Double_t xMin, Double_t xMax,
+ const char* xLabel = NULL, const char* yLabel = NULL)
+{
+// create a histogram
+
+ TH1F* result = new TH1F(name, title, nBins, xMin, xMax);
+ result->SetOption("E");
+ if (xLabel) result->GetXaxis()->SetTitle(xLabel);
+ if (yLabel) result->GetYaxis()->SetTitle(yLabel);
+ result->SetMarkerStyle(kFullCircle);
+ return result;
+}
+
+TH1F* CreateEffHisto(TH1F* hGen, TH1F* hRec)
+{
+// create an efficiency histogram
+
+ Int_t nBins = hGen->GetNbinsX();
+ TH1F* hEff = (TH1F*) hGen->Clone("hEff");
+ hEff->SetTitle("");
+ hEff->SetStats(kFALSE);
+ hEff->SetMinimum(0.);
+ hEff->SetMaximum(110.);
+ hEff->GetYaxis()->SetTitle("#epsilon [%]");
+
+ for (Int_t iBin = 0; iBin <= nBins; iBin++) {
+ Double_t nGen = hGen->GetBinContent(iBin);
+ Double_t nRec = hRec->GetBinContent(iBin);
+ if (nGen > 0) {
+ Double_t eff = nRec/nGen;
+ hEff->SetBinContent(iBin, 100. * eff);
+ Double_t error = sqrt(eff*(1.-eff) / nGen);
+ if (error == 0) error = 0.0001;
+ hEff->SetBinError(iBin, 100. * error);
+ } else {
+ hEff->SetBinContent(iBin, -100.);
+ hEff->SetBinError(iBin, 0);
+ }
+ }
+
+ return hEff;
+}
+
+Bool_t FitHisto(TH1* histo, Double_t& res, Double_t& resError)
+{
+// fit a gaussian to a histogram
+
+ static TF1* fitFunc = new TF1("fitFunc", "gaus");
+ fitFunc->SetLineWidth(2);
+ fitFunc->SetFillStyle(0);
+ Double_t maxFitRange = 2;
+
+ if (histo->Integral() > 50) {
+ Float_t mean = histo->GetMean();
+ Float_t rms = histo->GetRMS();
+ fitFunc->SetRange(mean - maxFitRange*rms, mean + maxFitRange*rms);
+ fitFunc->SetParameters(mean, rms);
+ histo->Fit(fitFunc, "QRI0");
+ histo->GetFunction("fitFunc")->ResetBit(1<<9);
+ res = TMath::Abs(fitFunc->GetParameter(2));
+ resError = TMath::Abs(fitFunc->GetParError(2));
+ return kTRUE;
+ }
+
+ return kFALSE;
+}
+
+
+Bool_t Check(const char* gAliceFileName = "galice.root",
+ const char* esdFileName = "AliESDs.root")
+{
+// check the content of the ESD
+
+ // check values
+ Int_t checkNGenLow = 1;
+
+ Double_t checkEffLow = 0.5;
+ Double_t checkEffSigma = 3;
+ Double_t checkFakeHigh = 0.5;
+ Double_t checkFakeSigma = 3;
+
+ Double_t checkResPtInvHigh = 5;
+ Double_t checkResPtInvSigma = 3;
+ Double_t checkResPhiHigh = 10;
+ Double_t checkResPhiSigma = 3;
+ Double_t checkResThetaHigh = 10;
+ Double_t checkResThetaSigma = 3;
+
+ Double_t checkPIDEffLow = 0.5;
+ Double_t checkPIDEffSigma = 3;
+ Double_t checkResTOFHigh = 500;
+ Double_t checkResTOFSigma = 3;
+
+ Double_t checkPHOSNLow = 5;
+ Double_t checkPHOSEnergyLow = 0.3;
+ Double_t checkPHOSEnergyHigh = 1.0;
+ Double_t checkEMCALNLow = 50;
+ Double_t checkEMCALEnergyLow = 0.05;
+ Double_t checkEMCALEnergyHigh = 1.0;
+
+ Double_t checkMUONNLow = 1;
+ Double_t checkMUONPtLow = 0.5;
+ Double_t checkMUONPtHigh = 10.;
+
+ Double_t cutPtV0 = 0.3;
+ Double_t checkV0EffLow = 0.02;
+ Double_t checkV0EffSigma = 3;
+ Double_t cutPtCascade = 0.5;
+ Double_t checkCascadeEffLow = 0.01;
+ Double_t checkCascadeEffSigma = 3;
+
+ // open run loader and load gAlice, kinematics and header
+ AliRunLoader* runLoader = AliRunLoader::Open(gAliceFileName);
+ if (!runLoader) {
+ Error("CheckESD", "getting run loader from file %s failed",
+ gAliceFileName);
+ return kFALSE;
+ }
+ runLoader->LoadgAlice();
+ gAlice = runLoader->GetAliRun();
+ if (!gAlice) {
+ Error("CheckESD", "no galice object found");
+ return kFALSE;
+ }
+ runLoader->LoadKinematics();
+ runLoader->LoadHeader();
+
+ // open the ESD file
+ TFile* esdFile = TFile::Open(esdFileName);
+ if (!esdFile || !esdFile->IsOpen()) {
+ Error("CheckESD", "opening ESD file %s failed", esdFileName);
+ return kFALSE;
+ }
+ AliESDEvent * esd = new AliESDEvent;
+ TTree* tree = (TTree*) esdFile->Get("esdTree");
+ if (!tree) {
+ Error("CheckESD", "no ESD tree found");
+ return kFALSE;
+ }
+ esd->ReadFromTree(tree);
+
+ // efficiency and resolution histograms
+ Int_t nBinsPt = 15;
+ Float_t minPt = 0.1;
+ Float_t maxPt = 3.1;
+ TH1F* hGen = CreateHisto("hGen", "generated tracks",
+ nBinsPt, minPt, maxPt, "p_{t} [GeV/c]", "N");
+ TH1F* hRec = CreateHisto("hRec", "reconstructed tracks",
+ nBinsPt, minPt, maxPt, "p_{t} [GeV/c]", "N");
+ Int_t nGen = 0;
+ Int_t nRec = 0;
+ Int_t nFake = 0;
+
+ TH1F* hResPtInv = CreateHisto("hResPtInv", "", 100, -10, 10,
+ "(p_{t,rec}^{-1}-p_{t,sim}^{-1}) / p_{t,sim}^{-1} [%]", "N");
+ TH1F* hResPhi = CreateHisto("hResPhi", "", 100, -20, 20,
+ "#phi_{rec}-#phi_{sim} [mrad]", "N");
+ TH1F* hResTheta = CreateHisto("hResTheta", "", 100, -20, 20,
+ "#theta_{rec}-#theta_{sim} [mrad]", "N");
+
+ // PID
+ Int_t partCode[AliPID::kSPECIES] =
+ {kElectron, kMuonMinus, kPiPlus, kKPlus, kProton};
+ const char* partName[AliPID::kSPECIES+1] =
+ {"electron", "muon", "pion", "kaon", "proton", "other"};
+ Double_t partFrac[AliPID::kSPECIES] =
+ {0.01, 0.01, 0.85, 0.10, 0.05};
+ Int_t identified[AliPID::kSPECIES+1][AliPID::kSPECIES];
+ for (Int_t iGen = 0; iGen < AliPID::kSPECIES+1; iGen++) {
+ for (Int_t iRec = 0; iRec < AliPID::kSPECIES; iRec++) {
+ identified[iGen][iRec] = 0;
+ }
+ }
+ Int_t nIdentified = 0;
+
+ // dE/dx and TOF
+ TH2F* hDEdxRight = new TH2F("hDEdxRight", "", 300, 0, 3, 100, 0, 400);
+ hDEdxRight->SetStats(kFALSE);
+ hDEdxRight->GetXaxis()->SetTitle("p [GeV/c]");
+ hDEdxRight->GetYaxis()->SetTitle("dE/dx_{TPC}");
+ hDEdxRight->SetMarkerStyle(kFullCircle);
+ hDEdxRight->SetMarkerSize(0.4);
+ TH2F* hDEdxWrong = new TH2F("hDEdxWrong", "", 300, 0, 3, 100, 0, 400);
+ hDEdxWrong->SetStats(kFALSE);
+ hDEdxWrong->GetXaxis()->SetTitle("p [GeV/c]");
+ hDEdxWrong->GetYaxis()->SetTitle("dE/dx_{TPC}");
+ hDEdxWrong->SetMarkerStyle(kFullCircle);
+ hDEdxWrong->SetMarkerSize(0.4);
+ hDEdxWrong->SetMarkerColor(kRed);
+ TH1F* hResTOFRight = CreateHisto("hResTOFRight", "", 100, -1000, 1000,
+ "t_{TOF}-t_{track} [ps]", "N");
+ TH1F* hResTOFWrong = CreateHisto("hResTOFWrong", "", 100, -1000, 1000,
+ "t_{TOF}-t_{track} [ps]", "N");
+ hResTOFWrong->SetLineColor(kRed);
+
+ // calorimeters
+ TH1F* hEPHOS = CreateHisto("hEPHOS", "PHOS", 100, 0, 50, "E [GeV]", "N");
+ TH1F* hEEMCAL = CreateHisto("hEEMCAL", "EMCAL", 100, 0, 50, "E [GeV]", "N");
+
+ // muons
+ TH1F* hPtMUON = CreateHisto("hPtMUON", "MUON", 100, 0, 20,
+ "p_{t} [GeV/c]", "N");
+
+ // V0s and cascades
+ TH1F* hMassK0 = CreateHisto("hMassK0", "K^{0}", 100, 0.4, 0.6,
+ "M(#pi^{+}#pi^{-}) [GeV/c^{2}]", "N");
+ TH1F* hMassLambda = CreateHisto("hMassLambda", "#Lambda", 100, 1.0, 1.2,
+ "M(p#pi^{-}) [GeV/c^{2}]", "N");
+ TH1F* hMassLambdaBar = CreateHisto("hMassLambdaBar", "#bar{#Lambda}",
+ 100, 1.0, 1.2,
+ "M(#bar{p}#pi^{+}) [GeV/c^{2}]", "N");
+ Int_t nGenV0s = 0;
+ Int_t nRecV0s = 0;
+ TH1F* hMassXi = CreateHisto("hMassXi", "#Xi", 100, 1.2, 1.5,
+ "M(#Lambda#pi) [GeV/c^{2}]", "N");
+ TH1F* hMassOmega = CreateHisto("hMassOmega", "#Omega", 100, 1.5, 1.8,
+ "M(#LambdaK) [GeV/c^{2}]", "N");
+ Int_t nGenCascades = 0;
+ Int_t nRecCascades = 0;
+
+ // loop over events
+ for (Int_t iEvent = 0; iEvent < runLoader->GetNumberOfEvents(); iEvent++) {
+ runLoader->GetEvent(iEvent);
+
+ // select simulated primary particles, V0s and cascades
+ AliStack* stack = runLoader->Stack();
+ Int_t nParticles = stack->GetNtrack();
+ TArrayF vertex(3);
+ runLoader->GetHeader()->GenEventHeader()->PrimaryVertex(vertex);
+ TObjArray selParticles;
+ TObjArray selV0s;
+ TObjArray selCascades;
+ for (Int_t iParticle = 0; iParticle < nParticles; iParticle++) {
+ TParticle* particle = stack->Particle(iParticle);
+ if (!particle) continue;
+ if (particle->Pt() < 0.001) continue;
+ if (TMath::Abs(particle->Eta()) > 0.9) continue;
+ TVector3 dVertex(particle->Vx() - vertex[0],
+ particle->Vy() - vertex[1],
+ particle->Vz() - vertex[2]);
+ if (dVertex.Mag() > 0.0001) continue;
+
+ switch (TMath::Abs(particle->GetPdgCode())) {
+ case kElectron:
+ case kMuonMinus:
+ case kPiPlus:
+ case kKPlus:
+ case kProton: {
+ if (particle->Pt() > minPt) {
+ selParticles.Add(particle);
+ nGen++;
+ hGen->Fill(particle->Pt());
+ }
+ break;
+ }
+ case kK0Short:
+ case kLambda0: {
+ if (particle->Pt() > cutPtV0) {
+ nGenV0s++;
+ selV0s.Add(particle);
+ }
+ break;
+ }
+ case kXiMinus:
+ case kOmegaMinus: {
+ if (particle->Pt() > cutPtCascade) {
+ nGenCascades++;
+ selCascades.Add(particle);
+ }
+ break;
+ }
+ default: break;
+ }
+ }
+
+ // get the event summary data
+ tree->GetEvent(iEvent);
+ if (!esd) {
+ Error("CheckESD", "no ESD object found for event %d", iEvent);
+ return kFALSE;
+ }
+
+ // loop over tracks
+ for (Int_t iTrack = 0; iTrack < esd->GetNumberOfTracks(); iTrack++) {
+ AliESDtrack* track = esd->GetTrack(iTrack);
+
+ // select tracks of selected particles
+ Int_t label = TMath::Abs(track->GetLabel());
+ if (label > stack->GetNtrack()) continue; // background
+ TParticle* particle = stack->Particle(label);
+ if (!selParticles.Contains(particle)) continue;
+ if ((track->GetStatus() & AliESDtrack::kITSrefit) == 0) continue;
+ if (track->GetConstrainedChi2() > 1e9) continue;
+ selParticles.Remove(particle); // don't count multiple tracks
+
+ nRec++;
+ hRec->Fill(particle->Pt());
+ if (track->GetLabel() < 0) nFake++;
+
+ // resolutions
+ hResPtInv->Fill(100. * (TMath::Abs(track->GetSigned1Pt()) - 1./particle->Pt()) *
+ particle->Pt());
+ hResPhi->Fill(1000. * (track->Phi() - particle->Phi()));
+ hResTheta->Fill(1000. * (track->Theta() - particle->Theta()));
+
+ // PID
+ if ((track->GetStatus() & AliESDtrack::kESDpid) == 0) continue;
+ Int_t iGen = 5;
+ for (Int_t i = 0; i < AliPID::kSPECIES; i++) {
+ if (TMath::Abs(particle->GetPdgCode()) == partCode[i]) iGen = i;
+ }
+ Double_t probability[AliPID::kSPECIES];
+ track->GetESDpid(probability);
+ Double_t pMax = 0;
+ Int_t iRec = 0;
+ for (Int_t i = 0; i < AliPID::kSPECIES; i++) {
+ probability[i] *= partFrac[i];
+ if (probability[i] > pMax) {
+ pMax = probability[i];
+ iRec = i;
+ }
+ }
+ identified[iGen][iRec]++;
+ if (iGen == iRec) nIdentified++;
+
+ // dE/dx and TOF
+ Double_t time[AliPID::kSPECIES];
+ track->GetIntegratedTimes(time);
+ if (iGen == iRec) {
+ hDEdxRight->Fill(particle->P(), track->GetTPCsignal());
+ if ((track->GetStatus() & AliESDtrack::kTOFpid) != 0) {
+ hResTOFRight->Fill(track->GetTOFsignal() - time[iRec]);
+ }
+ } else {
+ hDEdxWrong->Fill(particle->P(), track->GetTPCsignal());
+ if ((track->GetStatus() & AliESDtrack::kTOFpid) != 0) {
+ hResTOFWrong->Fill(track->GetTOFsignal() - time[iRec]);
+ }
+ }
+ }
+
+ // loop over muon tracks
+ {
+ for (Int_t iTrack = 0; iTrack < esd->GetNumberOfMuonTracks(); iTrack++) {
+ AliESDMuonTrack* muonTrack = esd->GetMuonTrack(iTrack);
+ Double_t ptInv = TMath::Abs(muonTrack->GetInverseBendingMomentum());
+ if (ptInv > 0.001) {
+ hPtMUON->Fill(1./ptInv);
+ }
+ }
+ }
+
+ // loop over V0s
+ for (Int_t iV0 = 0; iV0 < esd->GetNumberOfV0s(); iV0++) {
+ AliESDv0* v0 = esd->GetV0(iV0);
+ if (v0->GetOnFlyStatus()) continue;
+ v0->ChangeMassHypothesis(kK0Short);
+ hMassK0->Fill(v0->GetEffMass());
+ v0->ChangeMassHypothesis(kLambda0);
+ hMassLambda->Fill(v0->GetEffMass());
+ v0->ChangeMassHypothesis(kLambda0Bar);
+ hMassLambdaBar->Fill(v0->GetEffMass());
+
+ Int_t negLabel = TMath::Abs(esd->GetTrack(v0->GetNindex())->GetLabel());
+ if (negLabel > stack->GetNtrack()) continue; // background
+ Int_t negMother = stack->Particle(negLabel)->GetMother(0);
+ if (negMother < 0) continue;
+ Int_t posLabel = TMath::Abs(esd->GetTrack(v0->GetPindex())->GetLabel());
+ if (posLabel > stack->GetNtrack()) continue; // background
+ Int_t posMother = stack->Particle(posLabel)->GetMother(0);
+ if (negMother != posMother) continue;
+ TParticle* particle = stack->Particle(negMother);
+ if (!selV0s.Contains(particle)) continue;
+ selV0s.Remove(particle);
+ nRecV0s++;
+ }
+
+ // loop over Cascades
+ for (Int_t iCascade = 0; iCascade < esd->GetNumberOfCascades();
+ iCascade++) {
+ AliESDcascade* cascade = esd->GetCascade(iCascade);
+ Double_t v0q;
+ cascade->ChangeMassHypothesis(v0q,kXiMinus);
+ hMassXi->Fill(cascade->GetEffMassXi());
+ cascade->ChangeMassHypothesis(v0q,kOmegaMinus);
+ hMassOmega->Fill(cascade->GetEffMassXi());
+
+ Int_t negLabel = TMath::Abs(esd->GetTrack(cascade->GetNindex())
+ ->GetLabel());
+ if (negLabel > stack->GetNtrack()) continue; // background
+ Int_t negMother = stack->Particle(negLabel)->GetMother(0);
+ if (negMother < 0) continue;
+ Int_t posLabel = TMath::Abs(esd->GetTrack(cascade->GetPindex())
+ ->GetLabel());
+ if (posLabel > stack->GetNtrack()) continue; // background
+ Int_t posMother = stack->Particle(posLabel)->GetMother(0);
+ if (negMother != posMother) continue;
+ Int_t v0Mother = stack->Particle(negMother)->GetMother(0);
+ if (v0Mother < 0) continue;
+ Int_t bacLabel = TMath::Abs(esd->GetTrack(cascade->GetBindex())
+ ->GetLabel());
+ if (bacLabel > stack->GetNtrack()) continue; // background
+ Int_t bacMother = stack->Particle(bacLabel)->GetMother(0);
+ if (v0Mother != bacMother) continue;
+ TParticle* particle = stack->Particle(v0Mother);
+ if (!selCascades.Contains(particle)) continue;
+ selCascades.Remove(particle);
+ nRecCascades++;
+ }
+
+ // loop over the clusters
+ {
+ for (Int_t iCluster=0; iCluster<esd->GetNumberOfCaloClusters(); iCluster++) {
+ AliESDCaloCluster * clust = esd->GetCaloCluster(iCluster);
+ if (clust->IsPHOS()) hEPHOS->Fill(clust->E());
+ if (clust->IsEMCAL()) hEEMCAL->Fill(clust->E());
+ }
+ }
+
+ }
+
+ // perform checks
+ if (nGen < checkNGenLow) {
+ Warning("CheckESD", "low number of generated particles: %d", Int_t(nGen));
+ }
+
+ TH1F* hEff = CreateEffHisto(hGen, hRec);
+
+ Info("CheckESD", "%d out of %d tracks reconstructed including %d "
+ "fake tracks", nRec, nGen, nFake);
+ if (nGen > 0) {
+ // efficiency
+ Double_t eff = nRec*1./nGen;
+ Double_t effError = TMath::Sqrt(eff*(1.-eff) / nGen);
+ Double_t fake = nFake*1./nGen;
+ Double_t fakeError = TMath::Sqrt(fake*(1.-fake) / nGen);
+ Info("CheckESD", "eff = (%.1f +- %.1f) %% fake = (%.1f +- %.1f) %%",
+ 100.*eff, 100.*effError, 100.*fake, 100.*fakeError);
+
+ if (eff < checkEffLow - checkEffSigma*effError) {
+ Warning("CheckESD", "low efficiency: (%.1f +- %.1f) %%",
+ 100.*eff, 100.*effError);
+ }
+ if (fake > checkFakeHigh + checkFakeSigma*fakeError) {
+ Warning("CheckESD", "high fake: (%.1f +- %.1f) %%",
+ 100.*fake, 100.*fakeError);
+ }
+
+ // resolutions
+ Double_t res, resError;
+ if (FitHisto(hResPtInv, res, resError)) {
+ Info("CheckESD", "relative inverse pt resolution = (%.1f +- %.1f) %%",
+ res, resError);
+ if (res > checkResPtInvHigh + checkResPtInvSigma*resError) {
+ Warning("CheckESD", "bad pt resolution: (%.1f +- %.1f) %%",
+ res, resError);
+ }
+ }
+
+ if (FitHisto(hResPhi, res, resError)) {
+ Info("CheckESD", "phi resolution = (%.1f +- %.1f) mrad", res, resError);
+ if (res > checkResPhiHigh + checkResPhiSigma*resError) {
+ Warning("CheckESD", "bad phi resolution: (%.1f +- %.1f) mrad",
+ res, resError);
+ }
+ }
+
+ if (FitHisto(hResTheta, res, resError)) {
+ Info("CheckESD", "theta resolution = (%.1f +- %.1f) mrad",
+ res, resError);
+ if (res > checkResThetaHigh + checkResThetaSigma*resError) {
+ Warning("CheckESD", "bad theta resolution: (%.1f +- %.1f) mrad",
+ res, resError);
+ }
+ }
+
+ // PID
+ if (nRec > 0) {
+ Double_t eff = nIdentified*1./nRec;
+ Double_t effError = TMath::Sqrt(eff*(1.-eff) / nRec);
+ Info("CheckESD", "PID eff = (%.1f +- %.1f) %%",
+ 100.*eff, 100.*effError);
+ if (eff < checkPIDEffLow - checkPIDEffSigma*effError) {
+ Warning("CheckESD", "low PID efficiency: (%.1f +- %.1f) %%",
+ 100.*eff, 100.*effError);
+ }
+ }
+
+ printf("%9s:", "gen\\rec");
+ for (Int_t iRec = 0; iRec < AliPID::kSPECIES; iRec++) {
+ printf("%9s", partName[iRec]);
+ }
+ printf("\n");
+ for (Int_t iGen = 0; iGen < AliPID::kSPECIES+1; iGen++) {
+ printf("%9s:", partName[iGen]);
+ for (Int_t iRec = 0; iRec < AliPID::kSPECIES; iRec++) {
+ printf("%9d", identified[iGen][iRec]);
+ }
+ printf("\n");
+ }
+
+ if (FitHisto(hResTOFRight, res, resError)) {
+ Info("CheckESD", "TOF resolution = (%.1f +- %.1f) ps", res, resError);
+ if (res > checkResTOFHigh + checkResTOFSigma*resError) {
+ Warning("CheckESD", "bad TOF resolution: (%.1f +- %.1f) ps",
+ res, resError);
+ }
+ }
+
+ // calorimeters
+ if (hEPHOS->Integral() < checkPHOSNLow) {
+ Warning("CheckESD", "low number of PHOS particles: %d",
+ Int_t(hEPHOS->Integral()));
+ } else {
+ Double_t mean = hEPHOS->GetMean();
+ if (mean < checkPHOSEnergyLow) {
+ Warning("CheckESD", "low mean PHOS energy: %.1f GeV", mean);
+ } else if (mean > checkPHOSEnergyHigh) {
+ Warning("CheckESD", "high mean PHOS energy: %.1f GeV", mean);
+ }
+ }
+
+ if (hEEMCAL->Integral() < checkEMCALNLow) {
+ Warning("CheckESD", "low number of EMCAL particles: %d",
+ Int_t(hEEMCAL->Integral()));
+ } else {
+ Double_t mean = hEEMCAL->GetMean();
+ if (mean < checkEMCALEnergyLow) {
+ Warning("CheckESD", "low mean EMCAL energy: %.1f GeV", mean);
+ } else if (mean > checkEMCALEnergyHigh) {
+ Warning("CheckESD", "high mean EMCAL energy: %.1f GeV", mean);
+ }
+ }
+
+ // muons
+ if (hPtMUON->Integral() < checkMUONNLow) {
+ Warning("CheckESD", "low number of MUON particles: %d",
+ Int_t(hPtMUON->Integral()));
+ } else {
+ Double_t mean = hPtMUON->GetMean();
+ if (mean < checkMUONPtLow) {
+ Warning("CheckESD", "low mean MUON pt: %.1f GeV/c", mean);
+ } else if (mean > checkMUONPtHigh) {
+ Warning("CheckESD", "high mean MUON pt: %.1f GeV/c", mean);
+ }
+ }
+
+ // V0s
+ if (nGenV0s > 0) {
+ Double_t eff = nRecV0s*1./nGenV0s;
+ Double_t effError = TMath::Sqrt(eff*(1.-eff) / nGenV0s);
+ if (effError == 0) effError = checkV0EffLow / TMath::Sqrt(1.*nGenV0s);
+ Info("CheckESD", "V0 eff = (%.1f +- %.1f) %%",
+ 100.*eff, 100.*effError);
+ if (eff < checkV0EffLow - checkV0EffSigma*effError) {
+ Warning("CheckESD", "low V0 efficiency: (%.1f +- %.1f) %%",
+ 100.*eff, 100.*effError);
+ }
+ }
+
+ // Cascades
+ if (nGenCascades > 0) {
+ Double_t eff = nRecCascades*1./nGenCascades;
+ Double_t effError = TMath::Sqrt(eff*(1.-eff) / nGenCascades);
+ if (effError == 0) effError = checkV0EffLow /
+ TMath::Sqrt(1.*nGenCascades);
+ Info("CheckESD", "Cascade eff = (%.1f +- %.1f) %%",
+ 100.*eff, 100.*effError);
+ if (eff < checkCascadeEffLow - checkCascadeEffSigma*effError) {
+ Warning("CheckESD", "low Cascade efficiency: (%.1f +- %.1f) %%",
+ 100.*eff, 100.*effError);
+ }
+ }
+ }
+
+ // draw the histograms if not in batch mode
+ if (!gROOT->IsBatch()) {
+ new TCanvas;
+ hEff->DrawCopy();
+ new TCanvas;
+ hResPtInv->DrawCopy("E");
+ new TCanvas;
+ hResPhi->DrawCopy("E");
+ new TCanvas;
+ hResTheta->DrawCopy("E");
+ new TCanvas;
+ hDEdxRight->DrawCopy();
+ hDEdxWrong->DrawCopy("SAME");
+ new TCanvas;
+ hResTOFRight->DrawCopy("E");
+ hResTOFWrong->DrawCopy("SAME");
+ new TCanvas;
+ hEPHOS->DrawCopy("E");
+ new TCanvas;
+ hEEMCAL->DrawCopy("E");
+ new TCanvas;
+ hPtMUON->DrawCopy("E");
+ new TCanvas;
+ hMassK0->DrawCopy("E");
+ new TCanvas;
+ hMassLambda->DrawCopy("E");
+ new TCanvas;
+ hMassLambdaBar->DrawCopy("E");
+ new TCanvas;
+ hMassXi->DrawCopy("E");
+ new TCanvas;
+ hMassOmega->DrawCopy("E");
+ }
+
+ // write the output histograms to a file
+ TFile* outputFile = TFile::Open("check.root", "recreate");
+ if (!outputFile || !outputFile->IsOpen()) {
+ Error("CheckESD", "opening output file check.root failed");
+ return kFALSE;
+ }
+ hEff->Write();
+ hResPtInv->Write();
+ hResPhi->Write();
+ hResTheta->Write();
+ hDEdxRight->Write();
+ hDEdxWrong->Write();
+ hResTOFRight->Write();
+ hResTOFWrong->Write();
+ hEPHOS->Write();
+ hEEMCAL->Write();
+ hPtMUON->Write();
+ hMassK0->Write();
+ hMassLambda->Write();
+ hMassLambdaBar->Write();
+ hMassXi->Write();
+ hMassOmega->Write();
+ outputFile->Close();
+ delete outputFile;
+
+ // clean up
+ delete hGen;
+ delete hRec;
+ delete hEff;
+ delete hResPtInv;
+ delete hResPhi;
+ delete hResTheta;
+ delete hDEdxRight;
+ delete hDEdxWrong;
+ delete hResTOFRight;
+ delete hResTOFWrong;
+ delete hEPHOS;
+ delete hEEMCAL;
+ delete hPtMUON;
+ delete hMassK0;
+ delete hMassLambda;
+ delete hMassLambdaBar;
+ delete hMassXi;
+ delete hMassOmega;
+
+ delete esd;
+ esdFile->Close();
+ delete esdFile;
+
+ runLoader->UnloadHeader();
+ runLoader->UnloadKinematics();
+ delete runLoader;
+
+ // result of check
+ Info("CheckESD", "check of ESD was successfull");
+ return kTRUE;
+}
--- /dev/null
+// -------------------------------------------------------------------
+struct Setup
+{
+ TString runType; // Event generator chosen
+ UInt_t seed; // Random number seed - (env)
+ Float_t minB; // Least imp.param. (env)
+ Float_t maxB; // Largest imp.param. (env)
+ Int_t hftype; // Heavy flavour type (random)
+ /**
+ * Get the value of an environment variable as a float
+ *
+ * @param envName Enviroment variable name
+ * @param def Default value
+ *
+ * @return As float, or default
+ */
+ static Float_t Env2Float(const char* envName, Float_t def)
+ {
+ TString val(gSystem->Getenv(envName));
+ if (val.IsNull()) return def;
+ return val.Atof();
+ }
+ /**
+ * Get the value of an environment variable as a unsigned int
+ *
+ * @param envName Enviroment variable name
+ * @param def Default value
+ *
+ * @return As unsigned int, or default
+ */
+ static UInt_t Env2UInt(const char* envName, UInt_t def)
+ {
+ TString val(gSystem->Getenv(envName));
+ if (val.IsNull()) return def;
+ return UInt_t(val.Atoll());
+ }
+ /**
+ * Get the value of an environment variable as a int
+ *
+ * @param envName Enviroment variable name
+ * @param def Default value
+ *
+ * @return As int, or default
+ */
+ static UInt_t Env2Int(const char* envName, Int_t def)
+ {
+ TString val(gSystem->Getenv(envName));
+ if (val.IsNull()) return def;
+ return val.Atoi();
+ }
+
+ /**
+ * Constructor - retrieves needed information from CDB manager and
+ * environment.
+ */
+ Setup()
+ : runType(""),
+ seed(0),
+ minB(0),
+ maxB(100),
+ hftype(-1)
+ {
+ TDatime now;
+ runType = gSystem->Getenv("CONFIG_RUN_TYPE");
+ seed = Env2UInt("CONFIG_SEED", now.Get());
+ minB = Env2Float("CONFIG_BMIN", 0);
+ maxB = Env2Float("CONFIG_BMAX", 100);
+ if (runType[0] == 'k') runType.Remove(0,1);
+ runType.ToLower();
+
+ // gROOT->Macro("GetGRP.C");
+
+ Int_t pytR = gRandom->Rndm();
+ if (pytR < 0.16) hftype = 0;
+ else if (pytR < 0.32) hftype = 1;
+ else if (pytR < 0.48) hftype = 2;
+ else if (pytR < 0.64) hftype = 3;
+ else if (pytR < 0.72) hftype = 4;
+ else if (pytR < 0.80) hftype = 5;
+ else hftype = 6;
+
+ if (runType.IsNull() || runType == "default") DeduceRunType();
+
+ Print();
+ }
+ void Print()
+ {
+ Printf("=======================================================\n"
+ " Set-up of the simulation\n");
+ grp->Print();
+ Printf("Run type: '%s'", runType.Data());
+ Printf("Seed: %d", seed);
+ Printf("\n"
+ "=======================================================");
+ }
+ /**
+ * Set the default generator based on the beam type
+ *
+ * - p-p PYTHIA
+ * - p-A or A-p DPMJet
+ * - A-A Hijing
+ */
+ void DeduceRunType()
+ {
+ if (grp->IsPP()) runType = "pythia";
+ else if (grp->IsPA() || grp->IsAP()) runType = "dpmjet";
+ else if (grp->IsAA()) runType = "hijing";
+ }
+ void LoadGen() {
+ if (!gROOT->GetClass("AliStructFuncType"))
+ gSystem->Load("liblhapdf"); // Parton density functions
+ if (!gROOT->GetClass("TPythia6"))
+ gSystem->Load("libEGPythia6") // TGenerator interface
+ if (!runType.EqualTo("hydjet"))
+ LoadPythia(false);
+ }
+ /**
+ * Load the pythia libraries
+ *
+ * @param vers Optional version post-fix
+ */
+ void LoadPythia(Bool_t gen=true, const char* vers="6.4.21")
+ {
+ if (gen) LoadGen();
+ char m = vers[0];
+ if (gROOT->GetClass(Form("AliPythia6%c", m))) return;
+ gSystem->Load(Form("libpythia%s", vers));
+ gSystem->Load(Form("libAliPythia%c", m));
+ }
+ /**
+ * Load HIJING libraries
+ */
+ void LoadHijing()
+ {
+ LoadPythia();
+ if (gROOT->GetClass("THijing")) return;
+ gSystem->Load("libhijing");
+ gSystem->Load("libTHijing");
+ AliPDG::AddParticlesToPdgDataBase();
+ }
+ /**
+ * Load HydJet libraries
+ */
+ void LoadHydjet()
+ {
+ if (gROOT->GetClass("TUHKMgen")) return;
+ gSystem->Load("libTUHKMgen");
+ }
+ /**
+ * Load DPMJet libraries
+ */
+ void LoadDpmjet()
+ {
+ LoadPythia();
+ if (gROOT->GetClass("TDPMjet")) return;
+ gSystem->Load("libdpmjet");
+ gSystem->Load("libTDPMjet");
+ }
+ /**
+ * Load AMPT libraries
+ */
+ void LoadAmpt()
+ {
+ LoadPythia();
+ if (gROOT->GetClass("TAmpt")) return;
+ gSystem->Load("libampt");
+ gSystem->Load("libTAmpt");
+ }
+ /**
+ * Make the generator
+ *
+ * @return Point to newly allocated generator or null
+ */
+ AliGenerator* MakeGenerator()
+ {
+ Bool_t asym = grp->IsPA()||grp->IsAP();
+ TString& rt = runType;
+ if (rt.EndsWith("perugia0chadr")) return PythiaHF(0);
+ if (rt.EndsWith("perugia0bchadr")) return PythiaHF(1);
+ if (rt.EndsWith("perugia0cele")) return PythiaHF(2);
+ if (rt.EndsWith("perugia0bele")) return PythiaHF(3);
+ if (rt.EndsWith("perugia0jspi2e")) return PythiaHF(4);
+ if (rt.EndsWith("perugia0btojspi2e")) return PythiaHF(5);
+ if (rt.BeginsWith("pythia")) return Pythia(rt);
+ if (rt.BeginsWith("hijing2000hf")) return HFCocktail(rt);
+ if (rt.BeginsWith("hijing2000")) return Hijing(asym,
+ false, 2.3);
+ if (rt.BeginsWith("hijing")) return Hijing(asym,
+ grp->IsAA(), 0);
+ if (rt.BeginsWith("ampthf")) return HFCocktail(rt);
+ if (rt.BeginsWith("ampt")) return Ampt();
+ if (rt.BeginsWith("dpmjet")) return Dpmjet();
+ if (rt.BeginsWith("phojet")) return Dpmjet();
+ if (rt.BeginsWith("hydjet")) return Hydjet();
+
+ Fatal("", "Invalid run type \"%s\" specified", runType.Data());
+ return 0;
+ }
+ TVirtualMCDecayer* MakeDecayer()
+ {
+ if (runType.BeginsWith("hydjet")) return 0;
+
+ LoadPythia();
+ TVirtualMCDecayer* decayer = new AliDecayerPythia();
+ if (runType.EqualTo("hijing2000hf") && hftype < 2)
+ decayer->SetForceDecay(kHadronicD);
+ else
+ decayer->SetForceDecay(kAll);
+ decayer->Init();
+ return decayer;
+ }
+
+ // === PYTHIA ========================================================
+ // Normal
+ AliGenerator* Pythia(const TString & tune)
+ {
+ // Int_t kCTEQ6l = 8;
+ if (!grp->IsPP()) Fatal("Setup", "Pythia6 only works for pp");
+
+ TString t(tune);
+ t.ToUpper();
+ t.ReplaceAll("PYTHIA6", "");
+ t.ReplaceAll("PYTHIA", "");
+ Info("Setup", "Making Pythia6 event generator (tune: %s)", t.Data());
+
+ LoadPythia();
+ AliGenPythia* pythia = new AliGenPythia(-1);
+ pythia->SetMomentumRange(0, 999999.);
+ pythia->SetThetaRange(0., 180.);
+ pythia->SetYRange(-12.,12.);
+ pythia->SetPtRange(0,1000.);
+ pythia->SetProcess(kPyMb);
+ pythia->SetEnergyCMS(grp->energy);
+
+ if (t == "D6T") {
+ // Tune
+ // 109 D6T : Rick Field's CDF Tune D6T
+ // (NB: needs CTEQ6L pdfs externally)
+ pythia->SetTune(109); // F I X
+ pythia->SetStrucFunc(kCTEQ6l);
+ }
+ else if (t == "PERUGIA0") {
+ // Tune
+ // 320 Perugia 0
+ pythia->SetTune(320);
+ pythia->UseNewMultipleInteractionsScenario();
+ }
+ else if (t == "ATLAS") {
+ // Tune
+ // C 306 ATLAS-CSC: Arthur Moraes' (new) ATLAS tune
+ // (needs CTEQ6L externally)
+ pythia->SetTune(306);
+ pythia->SetStrucFunc(kCTEQ6l);
+ }
+ else if (t == "JETS") {
+ pythia->SetProcess(kPyJets);
+ pythia->SetStrucFunc(kCTEQ6l);
+ pythia->SetJetEtaRange(-1.5, 1.5);
+ pythia->SetJetEtRange(50., 800.);
+ pythia->SetPtHard(45., 1000.);
+ pythia->SetPycellParameters(2.2, 300, 432, 0., 4., 5., 0.7);
+ }
+ else if (t == "ATLAS_FLAT") {
+ // set high multiplicity trigger
+ // this weight achieves a flat multiplicity distribution
+ TH1 *weight = new TH1D("weight","weight",201,-0.5,200.5);
+ weight->SetBinContent(1,5.49443);
+ weight->SetBinContent(2,8.770816);
+ weight->SetBinContent(6,0.4568624);
+ weight->SetBinContent(7,0.2919915);
+ weight->SetBinContent(8,0.6674189);
+ weight->SetBinContent(9,0.364737);
+ weight->SetBinContent(10,0.8818444);
+ weight->SetBinContent(11,0.531885);
+ weight->SetBinContent(12,1.035197);
+ weight->SetBinContent(13,0.9394057);
+ weight->SetBinContent(14,0.9643193);
+ weight->SetBinContent(15,0.94543);
+ weight->SetBinContent(16,0.9426507);
+ weight->SetBinContent(17,0.9423649);
+ weight->SetBinContent(18,0.789456);
+ weight->SetBinContent(19,1.149026);
+ weight->SetBinContent(20,1.100491);
+ weight->SetBinContent(21,0.6350525);
+ weight->SetBinContent(22,1.351941);
+ weight->SetBinContent(23,0.03233504);
+ weight->SetBinContent(24,0.9574557);
+ weight->SetBinContent(25,0.868133);
+ weight->SetBinContent(26,1.030998);
+ weight->SetBinContent(27,1.08897);
+ weight->SetBinContent(28,1.251382);
+ weight->SetBinContent(29,0.1391099);
+ weight->SetBinContent(30,1.192876);
+ weight->SetBinContent(31,0.448944);
+ for (Int_t i = 32; i <= 201; i++) weight->SetBinContent(i,1);
+ weight->SetEntries(526);
+
+ Int_t limit = weight->GetRandom();
+ pythia->SetTriggerChargedMultiplicity(limit, 1.4);
+ }
+ return pythia;
+ }
+ AliGenerator* PythiaHF(Int_t type, Bool_t harder=0)
+ {
+ LoadPythia();
+ if (type == 6) return Pythia("jets");
+ if (type == 4) {
+ AliGenParam *jpsi = AliGenParam(1, AliGenMUONlib::kJpsi,
+ (harder?"CDF pp 8.8":"CDF pp 7"),"Jpsi");
+ jpsi->SetPtRange(0.,999.);
+ jpsi->SetYRange(-1.0, 1.0);
+ jpsi->SetPhiRange(0.,360.);
+ jpsi->SetForceDecay(kDiElectron);
+ return jpsi;
+ }
+ AliGenPythia* pythia = static_cast<AliGenPythia*>(Pythia("PERUGIA0"));
+ switch (type) {
+ case 0: // chadr
+ pythia->SetProcess(kPyCharmppMNRwmi);
+ pythia->SetForceDecay(kHadronicD);
+ break;
+ case 1: // bchadr
+ pythia->SetProcess(kPyBeautyppMNRwmi);
+ pythia->SetForceDecay(kHadronicD);
+ break;
+ case 2: // cele
+ pythia->SetProcess(kPyCharmppMNRwmi);
+ pythia->SetCutOnChild(1);
+ pythia->SetPdgCodeParticleforAcceptanceCut(11);
+ pythia->SetChildYRange(-1.2,1.2);
+ pythia->SetChildPtRange(0,10000.);
+ break;
+ case 3: // bele
+ pythia->SetProcess(kPyBeautyppMNRwmi);
+ pythia->SetCutOnChild(1);
+ pythia->SetPdgCodeParticleforAcceptanceCut(11);
+ pythia->SetChildYRange(-1.2,1.2);
+ pythia->SetChildPtRange(0,10000.);
+ break;
+ case 5:
+ pythia->SetProcess(kPyBeautyppMNRwmi);
+ pythia->SetCutOnChild(1);
+ pythia->SetPdgCodeParticleforAcceptanceCut(443);
+ pythia->SetChildYRange(-2,2);
+ pythia->SetChildPtRange(0,10000.);
+ }
+ return pythia;
+ }
+ /**
+ * Make a Min-Bias AA, pA, or Ap Hijing generator
+ *
+ * @param slowN If true, make a cocktail with slow neutrons
+ *
+ * @return Generator
+ */
+ AliGenerator* Hijing(Bool_t slowN=false, Bool_t quench=1, Float_t ptHard=0)
+ {
+ LoadHijing();
+ AliGenHijing *gener = new AliGenHijing(-1);
+ // centre of mass energy
+ gener->SetEnergyCMS(grp->energy);
+ gener->SetImpactParameterRange(minB, maxB);
+ // reference frame
+ gener->SetReferenceFrame("CMS");
+ // projectil
+ gener->SetProjectile(grp->beam1.Name(), grp->beam1.a, grp->beam1.z);
+ gener->SetTarget (grp->beam2.Name(), grp->beam2.a, grp->beam2.z);
+ // tell hijing to keep the full parent child chain
+ gener->KeepFullEvent();
+ // enable jet quenching
+ gener->SetJetQuenching(quench);
+ // enable shadowing
+ gener->SetShadowing(slowN);
+ // Don't track spectators
+ gener->SetSpectators(!slowN);
+ //
+ if (ptHard > 0) hi->SetPtHardMin(ptHard);
+
+ // kinematic selection
+ gener->SetSelectAll(0);
+ // Boosted CMS
+ gener->SetBoostLHC(grp->IsPA() || grp->IsAP());
+ // No need for cocktail
+ if (!slowN || !grp->IsPA() || !grp->IsAP()) return gener;
+
+ AliGenCocktail* cocktail = new AliGenCocktail();
+ cocktail->SetProjectile(grp->beam1.Name(), grp->beam1.a, grp->beam1.z);
+ cocktail->SetTarget (grp->beam2.Name(), grp->beam2.a, grp->beam2.z);
+ cocktail->SetEnergyCMS(grp->energy);
+
+ AliGenSlowNucleons* gray = new AliGenSlowNucleons(1);
+ AliCollisionGeometry* coll = gener->CollisionGeometry();
+ AliSlowNucleonModelExp* model = new AliSlowNucleonModelExp();
+ // Not yet in the release...
+ // model->SetSaturation(kTRUE);
+ gray->SetSlowNucleonModel(model);
+ gray->SetTarget(grp->beam2.a, grp->beam2.z);
+ gray->SetThetaDist(1);
+ gray->SetProtonDirection(grp->beam1.IsP() ? 1 : 2);
+ // gray->SetDebug(1);
+ gray->SetNominalCmsEnergy(2*grp->beamEnergy);
+ gray->NeedsCollisionGeometry();
+ gray->SetCollisionGeometry(coll);
+
+ cocktail->AddGenerator(gener, "Hijing pPb", 1);
+ cocktail->AddGenerator(gray, "Gray Particles", 1);
+
+ return cocktail;
+ }
+ /**
+ * Make a DPMJet generator for AA, pA, or Ap.
+ *
+ * @param fragments If true, make fragments
+ *
+ * @return Generator
+ */
+ AliGenerator* Dpmjet(Bool_t fragments=0)
+ {
+ LoadDpmjet();
+ AliGenDPMjet* dpmjet = new AliGenDPMjet(-1);
+ dpmjet->SetEnergyCMS(grp->energy);
+ dpmjet->SetProjectile(grp->beam1.Name(), grp->beam1.a, grp->beam1.z);
+ dpmjet->SetTarget (grp->beam2.Name(), grp->beam2.a, grp->beam2.z);
+ dpmjet->SetImpactParameterRange(minB, maxB);
+ dpmjet->SetProjectileBeamEnergy(grp->beam1.z*grp->beamEnergy/grp->beam1.a);
+ if (grp->IsAA()) {
+ dpmjet->SetPi0Decay(0);
+ }
+ else if (grp->IsPA() || grp->IsAP()) {
+ dpmjet->SetTriggerParticle(3312, 1.2, 2.0);
+ dpmjet->SetFragmentProd(fragments); // Alwas disabled
+ }
+ else if (grp->IsPP()) { // PhoJet
+ dpmjet->SetMomentumRange(0, 999999.);
+ dpmjet->SetThetaRange(0., 180.);
+ dpmjet->SetYRange(-12.,12.);
+ dpmjet->SetPtRange(0,1000.);
+ }
+ return dpmjet;
+ }
+ /**
+ * Make an AMPT generator for AA collisions
+ *
+ * @return Generator
+ */
+ AliGenerator* Ampt()
+ {
+ LoadAmpt();
+ AliGenAmpt *genHi = new AliGenAmpt(-1);
+ genHi->SetEnergyCMS(grp->energy);
+ genHi->SetReferenceFrame("CMS");
+ genHi->SetProjectile(grp->beam1.Name(), grp->beam1.a, grp->beam1.z);
+ genHi->SetTarget (grp->beam2.Name(), grp->beam2.a, grp->beam2.z);
+ genHi->SetPtHardMin (2);
+ genHi->SetImpactParameterRange(bMin,bMax);
+ // disable jet quenching
+ genHi->SetJetQuenching(0);
+ // enable shadowing
+ genHi->SetShadowing(1);
+ // neutral pion and heavy particle decays switched off
+ genHi->SetDecaysOff(1);
+ genHi->SetSpectators(0); // track spectators
+ genHi->KeepFullEvent();
+ genHi->SetSelectAll(0);
+ return genHi;
+ }
+ /**
+ * Make an HydJet generator for A-A
+ *
+ * @return Generator
+ */
+ AliGenerator* Hydjet()
+ {
+ LoadHydjet();
+ AliGenUHKM *genHi = new AliGenUHKM(-1);
+ genHi->SetAllParametersLHC();
+ genHi->SetProjectile(grp->beam1.Name(), grp->beam1.a, grp->beam1.z);
+ genHi->SetTarget (grp->beam2.Name(), grp->beam2.a, grp->beam2.z);
+ genHi->SetEcms(grp->energy);
+ genHi->SetEnergyCMS(grp->energy);
+ genHi->SetBmin(bMin);
+ genHi->SetBmax(bMax);
+ genHi->SetPyquenPtmin(9);
+ return genHi;
+ }
+ /**
+ * Make a heavy flavour cocktail
+ *
+ * @param base Underlying event.
+ *
+ * @return Generator
+ */
+ AliGeneator* HFCocktail(const TString& base)
+ {
+
+ AliGenCocktail *cocktail = new AliGenCocktail();
+ cocktail->SetProjectile(grp->beam1.Name(), grp->beam1.a, grp->beam1.z);
+ cocktail->SetTarget (grp->beam2.Name(), grp->beam2.a, grp->beam2.z);
+ cocktail->SetEnergyCMS(grp->energy);
+
+ // Add underlying event
+ if (base.BeginsWith("ampt", TString::kIgnoreCase)) {
+ hi = Ampt();
+ cocktail->AddGenerator(hi,"ampt",1);
+ }
+ else {
+ hi = Hijing(grp->IsPA() || grp->IsAP(), false, 2.3);
+ cocktail->AddGenerator(hi,"hijing",1);
+
+ }
+
+ // --- Default formula -------------------------------------------
+ TForumla* one = new TFormula("one", "1.");
+
+ // --- Pythia ----------------------------------------------------
+ AliGenerator* pythia = PythiaHF(hftype);
+ switch (hftype) {
+ case 6:
+ cocktail->AddGenerator(pythia, "pythiaJets", 1, one);
+ break;
+ defualt:
+ cocktail
+ ->AddGenerator(pythia, "pythiaHF", 1,
+ new TFormula("Signals",
+ "20.*(x<5.)+80./3.*(1.-x/20.)*(x>5.)"));
+ break;
+ }
+ // --- Dummy -----------------------------------------------------
+ AliGenParam* param = 0;
+
+ // --- Phos stuff ------------------------------------------------
+ AliGenPHOSlib *plib = new AliGenPHOSlib();
+ Double_t lower[] = { 0, 3, 6, 9, 12, -1 };
+ Double_t *pLow = lower;
+ for (Int_t i = 0; i < 5; i++) {
+ param = new AliGenParam(5, plib, AliGenPHOSlib::kPi0);
+ param->SetPhiRange(0., 360.) ;
+ param->SetYRange(-1.2, 1.2) ;
+ param->SetPtRange(lower[i], 30.) ;
+ cocktail->AddGenerator(param,Form("Pi0HagPt%d", i), 1., one);
+ }
+
+ // --- Jpsi->mu+ mu-----------------------------------------------
+ param = new AliGenParam(1, AliGenMUONlib::kJpsi, "CDF pp 3.94", "Jpsi");
+ param->SetPtRange(0.,999.);
+ param->SetYRange(-4.2, -2.3);
+ param->SetPhiRange(0.,360.);
+ param->SetForceDecay(kDiMuon);
+ param->SetCutOnChild(1);
+ param->SetChildPhiRange(0.,360.);
+ param->SetChildThetaRange(168.5,178.5);
+ cocktail->AddGenerator(param, "Jpsi2M", 1, one);
+
+ // --- Chi_c -> J/Psi + gamma, J/Psi -> e+e- ---------------------
+ Float_t thmin = (180./TMath::Pi())*2.*atan(exp(-1.2));
+ Float_t thmax = (180./TMath::Pi())*2.*atan(exp( 1.2));
+ param = new AliGenParam(1, AliGenMUONlib::kChic,"default","Chic");
+ param->SetMomentumRange(0, 999.); // Wide cut on the momentum
+ param->SetPtRange(0, 100.); // Wide cut on Pt
+ param->SetYRange(-2.5, 2.5);
+ param->SetCutOnChild(1); // Enable cuts on decay products
+ param->SetChildPhiRange(0., 360.);
+ // In the acceptance of the Central Barrel
+ param->SetChildThetaRange(thmin, thmax);
+ // Chi_c -> J/Psi + gamma, J/Psi -> e+e-
+ param->SetForceDecay(kChiToJpsiGammaToElectronElectron);
+ cocktail->AddGenerator(param, "Chi_c", 1, one);
+
+ // --- Dummy -----------------------------------------------------
+ AliGenBox* box = 0;
+
+ // --- Some particles --------------------------------------------
+ Double_t boxR = gRandom->Integer(3)+1;
+ Int_t boxP[] = { 310, 3122, 3312, 3322,
+ (boxR==1 ?3334: boxR==2 ?-3334: -3312) };
+ Int_t boxN[] = { 1, 1, 3, 3, 1 }
+ const char* boxT[] = { "K0s", "Lambda", "Xi-", "Xi0",
+ (boxR==1 ? "Omega-": boxR==2 ? "Omega+": "Xi+") };
+ for (Int_t i = 0; i < 5; i++) {
+ box = new AliGenBox(boxN[i]);
+ box->SetPart(boxP[i]);
+ box->SetPtRange(0,13);
+ box->SetThetaRange(45, 135);
+ cocktail->AddGenerator(box, boxT[i], 1, one);
+ }
+
+ // --- High pT charged particle ----------------------------------
+ TFormula* hptF = new TFormula("High Pt",
+ "5.*(x<5.)+20./3.*(1.-x/20.)*(x > 5.)");
+ Int_t hptP[] = { 211, 321, 2212 };
+ const char* hptT[] = { "pi", "K", "p" };
+ for (Int_t i = 0; i < 3; i++) {
+ for (Int_t j = -1; j <= 1; j++) {
+ box->SetPart(j*hptP[i]);
+ box->SetPtRange(2., 50.);
+ box->SetThetaRange(thmin, thmax);
+ cocktail->AddGenerator(box, Form("%s%c",hptT[i],(j<0,'-','+')),1,hptF);
+ }
+ }
+ return cocktail;
+ }
+};
+
+
+
+
+
+void Config()
+{
+ // --- Get settings from environment variables --------------------
+ Setup s;
+
+ // ---- Seed random number generator -------------------------------
+ gRandom->SetSeed(s.seed);
+ std::cerr << "Seed for random number generation= " << s.seed << std::endl;
+
+ //------------------------------------------------------------------
+ //
+ // Geometry and tracking
+ //
+ // --- Libraries required by geant321 ------------------------------
+ s.LoadGen();
+ gSystem->Load("libgeant321");
+ new TGeant3TGeo("C++ Interface to Geant3");
+
+ // -----------------------------------------------------------------
+ // Create the output file
+ std::cout<< "Config.C: Creating Run Loader ..." << std::endl;
+ AliRunLoader* rl = AliRunLoader::Open("galice.root",
+ AliConfig::GetDefaultEventFolderName(),
+ "recreate");
+ if (!rl) Fatal("Config","Can not instatiate the Run Loader");
+
+ rl->SetCompressionLevel(2);
+ rl->SetNumberOfEventsPerFile(1000);
+ gAlice->SetRunLoader(rl);
+
+ // --- Trigger configuration ---------------------------------------
+ // AliSimulation::Instance()->SetTriggerConfig(grp->IsAA() ? "Pb-Pb" : "p-p");
+
+ //
+ //=======================================================================
+ // Steering parameters for ALICE simulation
+ //
+ // --- Specify event type to be tracked through the ALICE setup
+ // --- All positions are in cm, angles in degrees, and P and E in GeV
+
+ // --- Process switches --------------------------------------------
+ gMC->SetProcess("DCAY",1);
+ gMC->SetProcess("PAIR",1);
+ gMC->SetProcess("COMP",1);
+ gMC->SetProcess("PHOT",1);
+ gMC->SetProcess("PFIS",0);
+ gMC->SetProcess("DRAY",0);
+ gMC->SetProcess("ANNI",1);
+ gMC->SetProcess("BREM",1);
+ gMC->SetProcess("MUNU",1);
+ gMC->SetProcess("CKOV",1);
+ gMC->SetProcess("HADR",1);
+ gMC->SetProcess("LOSS",2);
+ gMC->SetProcess("MULS",1);
+ gMC->SetProcess("RAYL",1);
+
+ Float_t cut = 1.e-3; // 1MeV cut by default
+ Float_t tofmax = 1.e10;
+
+ // --- Tracking cuts -----------------------------------------------
+ gMC->SetCut("CUTGAM", cut);
+ gMC->SetCut("CUTELE", cut);
+ gMC->SetCut("CUTNEU", cut);
+ gMC->SetCut("CUTHAD", cut);
+ gMC->SetCut("CUTMUO", cut);
+ gMC->SetCut("BCUTE", cut);
+ gMC->SetCut("BCUTM", cut);
+ gMC->SetCut("DCUTE", cut);
+ gMC->SetCut("DCUTM", cut);
+ gMC->SetCut("PPCUTM", cut);
+ gMC->SetCut("TOFMAX", tofmax);
+
+ // --- Set External decayer ----------------------------------------
+ TVirtualMCDecayer* decayer = s.MakeDecayer();
+ if (decayer) gMC->SetExternalDecayer(decayer);
+
+ //------------------------------------------------------------------
+ //
+ // Generator Configuration
+ //
+ // --- Make the generator - this loads libraries
+ AliGenerator* gener = s.MakeGenerator();
+ gener->Init();
+
+ // --- Go back to galice.root --------------------------------------
+ rl->CdGAFile();
+
+ // --- Switch on and off detectors ---------------------------------
+ Int_t iABSO = 1;
+ Int_t iACORDE= 0;
+ Int_t iDIPO = 1;
+ Int_t iEMCAL = 1;
+ Int_t iFMD = 1;
+ Int_t iFRAME = 1;
+ Int_t iHALL = 1;
+ Int_t iITS = 1;
+ Int_t iMAG = 1;
+ Int_t iMUON = 1;
+ Int_t iPHOS = 1;
+ Int_t iPIPE = 1;
+ Int_t iPMD = 1;
+ Int_t iHMPID = 1;
+ Int_t iSHIL = 1;
+ Int_t iT0 = 1;
+ Int_t iTOF = 1;
+ Int_t iTPC = 1;
+ Int_t iTRD = 1;
+ Int_t iVZERO = 1;
+ Int_t iZDC = 1;
+
+
+ //=================== Alice BODY parameters =============================
+ AliBODY *BODY = new AliBODY("BODY", "Alice envelop");
+
+
+ if (iMAG) new AliMAG("MAG", "Magnet");
+ if (iABSO) new AliABSOv3("ABSO", "Muon Absorber");
+ if (iDIPO) new AliDIPOv3("DIPO", "Dipole version 3");
+ if (iHALL) new AliHALLv3("HALL", "Alice Hall");
+ if (iFRAME) (new AliFRAMEv2("FRAME", "Space Frame"))->SetHoles(1);
+ if (iSHIL) new AliSHILv3("SHIL", "Shielding Version 3");
+ if (iPIPE) new AliPIPEv3("PIPE", "Beam Pipe");
+ if (iITS) new AliITSv11("ITS","ITS v11");
+ // if (iITS) new AliITSv11Hybrid("ITS","ITS v11Hybrid");
+ if (iTPC) new AliTPCv2("TPC", "Default");
+ if (iTOF) new AliTOFv6T0("TOF", "normal TOF");
+ if (iHMPID) new AliHMPIDv3("HMPID", "normal HMPID");
+ if (iZDC) {
+ AliZDC *ZDC = 0;
+ if (grp->period.EqualTo("LHC10h")) {
+ // Need to use older ZDC for PbPb
+ ZDC = new AliZDCv3("ZDC", "normal ZDC");
+ ZDC->SetSpectatorsTrack();
+ }
+ else
+ ZDC = new AliZDCv4("ZDC", "normal ZDC");
+ if (grp->Year() < 2011) { //?
+ // What are these? Do they need to be set properly?
+ //Collimators aperture
+ ZDC->SetVCollSideCAperture(0.85);
+ ZDC->SetVCollSideCCentre(0.);
+ ZDC->SetVCollSideAAperture(0.75);
+ ZDC->SetVCollSideACentre(0.);
+ //Detector position
+ ZDC->SetYZNC(1.6);
+ ZDC->SetYZNA(1.6);
+ ZDC->SetYZPC(1.6);
+ ZDC->SetYZPA(1.6);
+ }
+ ZDC->SetLumiLength(0.);
+ if (grp->IsPA() || grp->IsAP()) {
+ ZDC->SetpAsystem();
+ ZDC->SetBeamEnergy(82.*grp->beamEnergy/208.);
+ }
+ }
+ if (iTRD) {
+ AliTRD *TRD = new AliTRDv1("TRD", "TRD slow simulator");
+ AliTRDgeometry *geoTRD = TRD->GetGeometry();
+ // Total of 18 super modules. We turn them all off by default
+ for (Int_t i = 0; i < 18; i++) geoTRD->SetSMstatus(i, 0);
+
+ // '09-'10 had 7 super modules
+ geoTRD->SetSMstatus( 0,1);
+ geoTRD->SetSMstatus( 1,1);
+ geoTRD->SetSMstatus( 7,1);
+ geoTRD->SetSMstatus( 8,1);
+ geoTRD->SetSMstatus( 9,1);
+ geoTRD->SetSMstatus(14,1);//?
+ geoTRD->SetSMstatus(17,1);
+
+ // In jan '11 3 more were added
+ if (grp->Year() > 2010) {
+ geoTRD->SetSMstatus(11, 1);
+ geoTRD->SetSMstatus(15, 1);
+ geoTRD->SetSMstatus(16, 1);//?
+ }
+
+ // In the 2012 shutdow 3 more were added
+ if (grp->Year() > 2012) {
+ geoTRD->SetSMstatus( 2,1);
+ geoTRD->SetSMstatus( 3,1);
+ geoTRD->SetSMstatus( 6,1);
+ }
+ if (grp->Year() > 2014) {
+ geoTRD->SetSMstatus( 4,1);
+ geoTRD->SetSMstatus( 5,1);
+ geoTRD->SetSMstatus(10,1);
+ geoTRD->SetSMstatus(12,1);
+ geoTRD->SetSMstatus(13,1);
+ }
+ }
+ if (iFMD) new AliFMDv1("FMD", "normal FMD");
+ if (iMUON) {
+ AliMUON *MUON = new AliMUONv1("MUON", "default");
+ MUON->SetTriggerEffCells(1); // not needed if raw masks
+ MUON->SetTriggerResponseV1(2);
+ }
+ if (iPHOS) new AliPHOSv1("PHOS", "noCPV_Modules123");
+ if (iPMD) new AliPMDv1("PMD", "normal PMD");
+ if (iT0) new AliT0v1("T0", "T0 Detector");
+ if (iEMCAL) new AliEMCALv2("EMCAL", "EMCAL_COMPLETE12SMV1");
+ if (iACORDE) new AliACORDEv1("ACORDE", "normal ACORDE");
+ if (iVZERO) new AliVZEROv7("VZERO", "normal VZERO");
+}
+
+
+
+
+//
+// EOF
+//
--- /dev/null
+#
+# To submit this JDL:
+#
+# alien_submit alien:@data@/Merge.jdl \
+# <run number> <N_jobs> <N_events> <tag> <what>
+#
+# where
+#
+# <run number> is the run number
+# <stage> is the stage number
+# <tag> is a single-word tag
+# <what> what to merge (QA or AOD)
+#
+# The output is written to alien:$HOME/test/<tag>
+#
+# Before this is done, one must make the appropriate XML file. For stage=1
+#
+# alien_find -x <what>Stage_1.xml \
+# @out@/<tag>/<run> \
+# */QA_archive.zip > <what>Stage_1.xml
+#
+# For stage > 1
+#
+# alien_find -x <what>_Stage_<stage>.xml \
+# @out@/<tag>/<run>/<what>Stage_<stage-1> \
+# */QA_archive.zip > <what>_Stage_<stage>.xml
+#
+# and then the XML file should be copied to alien
+#
+# alien_cp file:<what>_Stage_<stage>.xml alien:@out@/<tag>/<run>/<what>_Stage_<stage>.xml
+#
+
+Jobtag={
+ "comment:$3 ($1) MC for FMD stage $4 final merge"
+};
+Packages = {
+ "VO_ALICE@AliRoot::@aliroot@",
+ "VO_ALICE@ROOT::@root@",
+ "VO_ALICE@APISCONFIG::V1.1x"
+};
+Executable = "@bin@/merge.sh";
+Arguments = "$4 $1 $4_Stage_$2.xml $2";
+InputFile = {
+ "LF:@data@/$4.C",
+ "LF:@data@/$4Config.C",
+ "LF:@data@/GRP.C",
+ "LF:@data@/fmd_correcions.root,"
+ "LF:@out@/$3/$1/$4_Stage_$2.xml"
+};
+OutputDir = "@out@/$3/$1/";
+OutputArchive = {
+ "$4_merge_log_archive.zip:std*,fileinfo*.log@disk=1",
+ "$4_merge_archive.zip:*.root,*.stat*@disk=2"
+};
+TTL = "36000";
+Price = "20";
+Validationcommand = "/alice/cern.ch/user/a/aliprod/QA/validation_merge.sh";
+Workdirectorysize = {"5000MB"};
+JDLVariables =
+{
+ "Packages",
+ "OutputDir"
+};
+Workdirectorysize = {"10000MB"};
--- /dev/null
+/**
+ * @file GRP.C
+ * @author Christian Holm Christensen <cholm@nbi.dk>
+ * @date Wed Aug 20 10:00:39 2014
+ *
+ * @brief Class that hold summary of GRP data.
+ *
+ *
+ */
+// #include <fstream>
+
+/**
+ * Class that hold summary of GRP data, and has methods to obtain
+ * these, either from a previously dumped file, or directly from OCDB.
+ *
+ * This is used by the simulation setup to ensure we have the proper
+ * beam settings for an anchor run.
+ */
+struct GRPData
+{
+ /**
+ * A beam
+ */
+ struct Beam
+ {
+ UInt_t z;
+ UInt_t a;
+ Float_t GetEnergy(Float_t e) const
+ {
+ return e * sqrt(float(z)/a);
+ }
+ /**
+ * Check if this is a proton
+ *
+ * @return True if z and a are 1
+ */
+ Bool_t IsP() const { return z == 1 && a == 1; }
+ /**
+ * Check if this is a nucleus
+ *
+ * @return true if not P
+ */
+ Bool_t IsA() const { return !IsP(); }
+ /**
+ * Get the beam type name
+ *
+ * @return P or A
+ */
+ const char* Name() { return (IsP() ? "P" : IsA() ? "A" : ""); }
+ /**
+ * Set the beam type from single beam spec from LHC
+ *
+ * @param b Beam type from LHC
+ */
+ void Set(UInt_t b)
+ {
+ z = b % 1000;
+ a = b / 1000;
+ }
+ /**
+ * Set from either a full LHC spec or from ALICE spec
+ *
+ * @param b Beam
+ */
+ void Set(const TString& b)
+ {
+ b.ToUpper();
+ a = 0;
+ z = 0;
+ if (b.EqualTo("P") || b.EqualTo("PROTON")) {
+ z = a = 1;
+ }
+ else if (b.EqualTo("A") || b.BeginsWidth("PB")) {
+ z = 82;
+ a = 208;
+ }
+ }
+ };
+ UInt_t beamEnergy;
+ UInt_t energy;
+ TString period;
+ UInt_t run;
+ Beam beam1;
+ Beam beam2;
+ /**
+ * Constructor.
+ *
+ * @param r Run number
+ */
+ GRPData(UInt_t r)
+ : beamEnergy(0), energy(0), period(""), beam1(), beam2(), run(r)
+ {
+ Info("GRP", "Will try from file %s", FileName());
+ if (!ReadFromFile()) {
+ Warning("GRP", "Failed to read from file, trying from OCDB");
+ if (!ReadFromOCDB(run))
+ Fatal("GRP", "Failed to get GRP values");
+ }
+ Print();
+ }
+ /**
+ * Print information
+ *
+ */
+ void Print()
+ {
+ Printf("%s run %d\n"
+ " Beam energy: %d GeV\n"
+ " sqrt(s_NN): %d GeV\n"
+ " Beam 1: %s (%d %d)\n"
+ " Beam 2: %s (%d %d)",
+ period.Data(), run, beamEnergy, energy,
+ beam1.Name(), beam1.a, beam1.z,
+ beam2.Name(), beam2.a, beam2.z);
+ }
+ /**
+ * Check if this run was a p-p run
+ *
+ * @return Return true if both beams are p
+ */
+ Bool_t IsPP() const { return beam1.IsP() && beam2.IsP(); }
+ /**
+ * Check if this run was a p-A run
+ *
+ * @return Return true beam 1 is p and 2 is A
+ */
+ Bool_t IsPA() const { return beam1.IsP() && beam2.IsA(); }
+ /**
+ * Check if this run was a A-p run
+ *
+ * @return Return true beam 1 is A and 2 is p
+ */
+ Bool_t IsAP() const { return beam1.IsA() && beam2.IsP(); }
+ /**
+ * Check if this run was a A-A run
+ *
+ * @return Return true if both beams are A
+ */
+ Bool_t IsAA() const { return beam1.IsA() && beam2.IsA(); }
+ /**
+ * Get the year
+ *
+ * @return Year
+ */
+ UInt_t Year() const
+ {
+ TString tmp = period(3,2);
+ return tmp.Atoi() + 2000;
+ }
+ const char* FileName() const { return "grp.dat"; }
+ /**
+ * Get unsigned int value from string value of TObjString
+ *
+ * @param o Object
+ *
+ * @return value
+ */
+ static UInt_t Obj2UInt(const TObject* o)
+ {
+ return (static_cast<TObjString*>(o))->String().Atoi();
+ }
+ /**
+ * Read values from a file
+ *
+ * @return true on success
+ */
+ Bool_t ReadFromFile()
+ {
+ if (gSystem->AccessPathName(FileName())) {
+ Info("GRP", "Cannot open file %s", FileName());
+ return false;
+ }
+
+ std::ifstream* pin = new std::ifstream("grp.dat");
+ std::ifstream& in = *pin;
+ TString line;
+ TString env;
+ do {
+ line.ReadLine(in);
+ if (line.IsNull()) continue;
+ if (line[0] == '#') continue;
+ env = line;
+ break;
+ } while (!in.eof());
+ if (env.IsNull()) {
+ Info("GRP", "No line found");
+ return false;
+ }
+ Info("GRP", "Got the line %s", env.Data());
+ TObjArray* tokens = env.Tokenize(":");
+ if (tokens->GetEntries() < 8) {
+ Warning("GRP", "Failed to get enough field from GRP_SUMMARY=%s",
+ env.Data());
+ return false;
+ }
+ period = tokens->At(0)->GetName();
+ run = Obj2UInt(tokens->At(1));
+ beamEnergy = Obj2UInt(tokens->At(2));
+ energy = Obj2UInt(tokens->At(3));
+ beam1.a = Obj2UInt(tokens->At(4));
+ beam1.z = Obj2UInt(tokens->At(5));
+ beam2.a = Obj2UInt(tokens->At(6));
+ beam2.z = Obj2UInt(tokens->At(7));
+ pin->close();
+ delete pin;
+ return true;
+ }
+ /**
+ * Read values from OCDB. Also dumps values to file.
+ *
+ * @param r run number
+ *
+ * @return true on success
+ */
+ Bool_t ReadFromOCDB(UInt_t r)
+ {
+ AliCDBManager* cdb = AliCDBManager::Instance();
+ cdb->SetDefaultStorageFromRun(r);
+ cdb->SetRun(r);
+ AliCDBEntry* ent = cdb->Get("GRP/GRP/Data");
+ if (!ent) {
+ Warning("GRP", "No GRP data found");
+ cdb->SetRun(-1);
+ return false;
+ }
+ Info("GRP", "Got GRP:");
+ ent->PrintMetaData();
+
+ AliGRPObject* obj = static_cast<AliGRPObject*>(ent->GetObject());
+ obj->Print();
+ run = r;
+ period = obj->GetLHCPeriod();
+ beamEnergy = TMath::Ceil(obj->GetBeamEnergy());
+ TString beam1T = obj->GetSingleBeamType(0);
+ TString beam2T = obj->GetSingleBeamType(1);
+
+ if (!beam1T.IsNull() && !beam2T.IsNull()) {
+ beam1.Set(beam1T.Atoi());
+ beam2.Set(beam2T.Atoi());
+ }
+ else {
+ TString beamType = obj->GetBeamType();
+ if (beamType.IsNull()) {
+ Warning("GRP", "No beam type");
+ cdb->SetRun(-1);
+ return false;
+ }
+
+ TObjArray* ab = beamType.Tokenize("-");
+ ab->ls();
+ beam1T = ab->At(0)->GetName();
+ beam2T = ab->At(1)->GetName();
+ beam1.Set(beam1T);
+ beam2.Set(beam2T);
+ }
+ // Massage the beam energy in case we had sqrt{s_NN} instead of
+ // beam energy.
+ if (TMath::Abs(beamEnergy - 1379.8) < 10 && beam1.IsA() && beam2.IsA())
+ beamEnergy = 3500;
+ energy = TMath::Ceil(2*beamEnergy * TMath::Sqrt(Float_t(beam1.z*beam2.z)/
+ (beam1.a*beam2.a)));
+
+ const char* fn = FileName();
+ std::ofstream* pout = new std::ofstream(fn);
+ std::ofstream& out = *pout;
+ out << "# PERIOD:RUN:BEAMENERGY:ENERGY:BEAM1A:BEAM1Z:BEAM2A:BEAM2Z\n"
+ << period << ":"
+ << run << ":"
+ << beamEnergy << ":"
+ << energy << ":"
+ << beam1.a << ":"
+ << beam1.z << ":"
+ << beam2.a << ":"
+ << beam2.z << "\n"
+ << "# EOF " << std::endl;
+ pout->close();
+ delete pout;
+ cdb->SetRun(-1);
+ return true;
+ }
+ /**
+ * Get the value of an environment variable as a unsigned int
+ *
+ * @param envName Enviroment variable name
+ * @param def Default value
+ *
+ * @return As unsigned int, or default
+ */
+ static UInt_t Env2UInt(const char* envName, UInt_t def)
+ {
+ TString val(gSystem->Getenv(envName));
+ if (val.IsNull()) return def;
+ return UInt_t(val.Atoll());
+ }
+};
+GRPData* grp;
+void GRP(UInt_t run=0)
+{
+ grp = new GRPData(run);
+}
+//
+// EOF
+//
+
+
+
+
--- /dev/null
+#
+# To submit this JDL:
+#
+# alien_submit alien:@data@/Merge.jdl \
+# <run number> <N_jobs> <N_events> <tag> <what>
+#
+# where
+#
+# <run number> is the run number
+# <stage> is the stage number
+# <tag> is a single-word tag
+# <what> what to merge (QA or AOD)
+#
+# The output is written to alien:$HOME/test/<tag>
+#
+# Before this is done, one must make the appropriate XML file. For stage=1
+#
+# alien_find -x <what>Stage_1.xml \
+# @out@/<tag>/<run> \
+# */QA_archive.zip > <what>Stage_1.xml
+#
+# For stage > 1
+#
+# alien_find -x <what>_Stage_<stage>.xml \
+# @out@/<tag>/<run>/<what>Stage_<stage-1> \
+# */QA_archive.zip > <what>_Stage_<stage>.xml
+#
+# and then the XML file should be copied to alien
+#
+# alien_cp file:<what>_Stage_<stage>.xml alien:@out@/<tag>/<run>/<what>_Stage_<stage>.xml
+#
+Jobtag={
+ "comment:$4 $3 ($1) MC stage $2 intermittent merge"
+};
+# "VO_ALICE@GEANT3::@geant@",
+Packages={
+ "VO_ALICE@AliRoot::@aliroot@",
+ "VO_ALICE@ROOT::@root@",
+ "VO_ALICE@APISCONFIG::V1.1x"
+};
+Executable="@bin@/merge.sh";
+InputDataCollection={
+ "LF:@out@/$3/$1/$4_Stage_$2.xml,nodownload"
+};
+InputFile={
+ "LF:@data@/$4.C",
+ "LF:@data@/$4Config.C",
+ "LF:@data@/GRP.C",
+ "LF:@data@/fmd_corrections.root"
+
+};
+InputDataListFormat="xml-single";
+InputDataList="wn.xml";
+OutputDir="@out@/$3/$1/$4_Stage_$2/#alien_counter_03i#";
+OutputArchive={
+ "$4_log_archive.zip:std*,fileinfo*.log@disk=1",
+ "$4_archive.zip:*.root,*.stat*@disk=2"
+};
+Split="se";
+SplitMaxInputFileNumber="20";
+SplitArguments="$4 $1 wn.xml $2 #alien_counter#";
+Validationcommand="/alice/cern.ch/user/a/aliprod/QA/validation_merge.sh";
+TTL="36000";
+Price="1";
+Workdirectorysize={"5000MB"};
+JDLVariables={
+ "Packages",
+ "OutputDir"
+};
+LPMActivity="86400";
+
+#
+# EOF
+#
+
--- /dev/null
+/**
+ * @file QA.C
+ * @author Christian Holm Christensen <cholm@nbi.dk>
+ * @date Wed Sep 24 15:04:38 2014
+ *
+ * @brief Master script for QA train
+ *
+ * @note Do not modify this script.
+ *
+ *
+ * This script reads in two other scripts
+ *
+ * - GRP.C to load the global run parameters for the selected run,
+ * such as collision system, energy, etc.
+ *
+ * - AODConfig.C which defines a number of functions that return
+ * either true or false. The tasks added depends on these functions
+ *
+ */
+// Trigger mask.
+UInt_t kTriggerInt = AliVEvent::kAnyINT;
+UInt_t kTriggerMuonAll = (AliVEvent::kMUL7 |
+ AliVEvent::kMUSH7 |
+ AliVEvent::kMUU7 |
+ AliVEvent::kMUS7 |
+ AliVEvent::kMUSPB |
+ AliVEvent::kMUSHPB |
+ AliVEvent::kMuonLikePB |
+ AliVEvent::kMuonUnlikePB);
+UInt_t kTriggerMuonBarell = AliVEvent::kMUU7;
+UInt_t kTriggerEMC = (AliVEvent::kEMC7 |
+ AliVEvent::kEMC8 |
+ AliVEvent::kEMCEJE |
+ AliVEvent::kEMCEGA);
+UInt_t kTriggerHM = AliVEvent::kHighMult;
+UInt_t kTriggerMask = kTriggerInt;
+
+/**
+ * Interface (pure virtual) that all configuration classes must
+ * implement.
+ */
+struct VirtualQACfg
+{
+ /** @return */
+ virtual Bool_t DoCDBconnect() const = 0;
+ /** @return */
+ virtual Bool_t DoEventStat() const = 0;
+ /** @return */
+ virtual Bool_t DoCentrality() const = 0;
+ /** @return */
+ virtual Bool_t DoQAsym() const = 0;
+ /** @return there is a 2nd file */
+ virtual Bool_t DoVZERO() const = 0;
+ /** @return */
+ virtual Bool_t DoVZEROPbPb() const = 0;
+ /** @return */
+ virtual Bool_t DoVertex() const = 0;
+ /** @return needs RP */
+ virtual Bool_t DoSPD() const = 0;
+ /** @return */
+ virtual Bool_t DoTPC() const = 0;
+ /** @return */
+ virtual Bool_t DoHLT() const = 0;
+ /** @return needs RP */
+ virtual Bool_t DoSDD() const = 0;
+ /** @return */
+ virtual Bool_t DoSSDdEdx() const = 0;
+ /** @return */
+ virtual Bool_t DoTRD() const = 0;
+ /** @return */
+ virtual Bool_t DoITS() const = 0;
+ /** @return */
+ virtual Bool_t DoITSsaTracks() const = 0;
+ /** @return */
+ virtual Bool_t DoITSalign() const = 0;
+ /** @return */
+ virtual Bool_t DoCALO() const = 0;
+ /** @return */
+ virtual Bool_t DoMUONTrig() const = 0;
+ /** @return */
+ virtual Bool_t DoImpParRes() const = 0;
+ /** @return */
+ virtual Bool_t DoMUON() const = 0;
+ /** @return */
+ virtual Bool_t DoTOF() const = 0;
+ /** @return */
+ virtual Bool_t DoHMPID() const = 0;
+ /** @return */
+ virtual Bool_t DoT0() const = 0;
+ /** @return */
+ virtual Bool_t DoZDC() const = 0;
+ /** @return */
+ virtual Bool_t DoPIDResponse() const = 0;
+ /** @return */
+ virtual Bool_t DoPIDqa() const = 0;
+ /** @return */
+ virtual Bool_t DoFWD() const = 0;
+ /** @return */
+ virtual Bool_t DoPHOS() const = 0;
+ /** @return */
+ virtual Bool_t DoPHOSTrig() const = 0;
+ /** @return */
+ virtual Bool_t DoEMCAL() const = 0;
+ /** @return */
+ virtual Bool_t DoFBFqa() const = 0;
+ /** @return NEEDS geometry */
+ virtual Bool_t DoMUONEff() const = 0;
+ /** @return NEEDS MCtruth */
+ virtual Bool_t DoV0() const = 0;
+ /** @return Get Debug level */
+ virtual Int_t DebugLevel() const = 0;
+};
+VirtualQACfg* qaCfg = 0;
+
+//====================================================================
+/**
+ * Load the needed libraries
+ *
+ */
+void LoadLibraries()
+{
+ Bool_t is10h = grp->period.EqualTo("LHC10h",TString::kIgnoreCase);
+ gSystem->SetIncludePath("-I. "
+ "-I$ROOTSYS/include "
+ "-I$ALICE_ROOT/include "
+ "-I$ALICE_ROOT "
+ "-I$ALICE_ROOT/ITS "
+ "-I$ALICE_ROOT/TRD "
+ "-I$ALICE_ROOT/PWGPP "
+ "-I$ALICE_ROOT/PWGPP/TRD");
+ gSystem->Load("libANALYSIS");
+ gSystem->Load("libANALYSISalice");
+ gSystem->Load("libOADB");
+ gSystem->Load("libESDfilter.so");
+ gSystem->Load("libCORRFW");
+ gSystem->Load("libTENDER");
+ gSystem->Load("libPWGPP.so");
+ gSystem->Load("libAliHLTTrigger.so");
+
+ if (qaCfg->DoEMCAL() || qaCfg->DoPHOS() ||
+ (qaCfg->DoCALO() && !is10h)) {
+ gSystem->Load("libEMCALUtils");
+ gSystem->Load("libPHOSUtils");
+ gSystem->Load("libPWGCaloTrackCorrBase");
+ gSystem->Load("libPWGGACaloTrackCorrelations");
+ gSystem->Load("libPWGGACaloTasks");
+ gSystem->Load("libPWGGAPHOSTasks");
+ gSystem->Load("libPWGTools");
+ gSystem->Load("libPWGEMCAL");
+ gSystem->Load("libPWGGAEMCALTasks");
+ }
+ if(qaCfg->DoMUON() || qaCfg->DoMUONTrig()) {
+ gSystem->Load("libPWGmuon");
+ gSystem->Load("libPWGPPMUONlite");
+ gSystem->Load("libPWGmuondep");
+ }
+ if (qaCfg->DoFWD()) {
+ gSystem->Load("libPWGLFforward2");
+ }
+}
+
+//====================================================================
+/**
+ * Add the analysis tasks
+ *
+ * @param cdb_location
+ */
+void AddAnalysisTasks(const char *cdb_location)
+{
+ AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
+ mgr->SetCommonFileName("QAresults.root");
+
+ Bool_t is10h = grp->period.EqualTo("LHC10h",TString::kIgnoreCase);
+ // --- Some short-hands --------------------------------------------
+ TString ali = "$ALICE_ROOT";
+ TString ana = ali + "/ANALYSIS";
+ TString pwghf = ali + "/PWGHF";
+ TString pwglf = ali + "/PWGLF";
+ TString pwgje = ali + "/PWGJE";
+ TString pwgdq = ali + "/PWGDQ";
+ TString pwgpp = ali + "/PWGPP";
+ TString pwgga = ali + "/PWGGA";
+
+ // --- Statistics task ---------------------------------------------
+ mgr->AddStatisticsTask(kTriggerMask);
+
+ // --- CDB connection ----------------------------------------------
+ if (qaCfg->DoCDBconnect()) {
+ gROOT->LoadMacro(pwgpp+"/PilotTrain/AddTaskCDBconnect.C");
+ AliTaskCDBconnect *taskCDB = AddTaskCDBconnect(cdb_location, grp->run);
+ if (!taskCDB) return;
+ }
+
+ // --- Event Statistics (Jan Fiete) --------------------------------
+ if (qaCfg->DoEventStat()) {
+ gROOT->LoadMacro(ana+"/macros/AddTaskPhysicsSelection.C");
+ AliPhysicsSelectionTask* physSelTask = AddTaskPhysicsSelection(kTRUE/*MC*/);
+ // Hack by Alexander for LHC10h
+ // gROOT->LoadMacro("LHC10hPS.C");
+ // AliOADBPhysicsSelection* ops = LHC10hPS(grp->period, grp->run);
+ // if (ops)
+ // physSelTask->GetPhysicsSelection()->SetCustomOADBObjects(ops,0);
+ }
+ // --- PIDResponse(JENS) -------------------------------------------
+ if (qaCfg->DoPIDResponse() && !is10h) {
+ gROOT->LoadMacro(ana+"/macros/AddTaskPIDResponse.C");
+ AliAnalysisTaskPIDResponse *PIDResponse = AddTaskPIDResponse(kTRUE);
+ PIDResponse->SelectCollisionCandidates(kTriggerMask);
+ }
+ // --- Centrality (A. Toia) ----------------------------------------
+ if (qaCfg->DoCentrality()) {
+ gROOT->LoadMacro(ana+"/macros/AddTaskCentrality.C");
+ AliCentralitySelectionTask *taskCentrality = AddTaskCentrality();
+ taskCentrality->SetMCInput();
+ }
+
+ // --- Vertexing (A. Dainese) --------------------------------------
+ if (qaCfg->DoVertex()) {
+ gROOT->LoadMacro(pwgpp+"/macros/AddTaskVertexESD.C");
+ // Specific setting for MC
+ AliAnalysisTaskVertexESD* taskvertexesd =
+ AddTaskVertexESD(kTRUE, kTriggerMask);
+ taskvertexesd->SelectCollisionCandidates(kTriggerMask);
+ }
+
+ // --- TPC QA (E. Sicking) -----------------------------------------
+ if (qaCfg->DoQAsym()) {
+ // offline trigger in AddTask
+ gROOT->LoadMacro(pwgpp+"/PilotTrain/AddTaskQAsym.C");
+ AliAnalysisTaskSE * taskqasim = AddTaskQAsym(0,
+ kTriggerMask,
+ kTriggerHM,
+ kTriggerEMC,
+ kTriggerMuonBarell);
+ }
+ // --- VZERO QA (C. Cheshkov) -------------------------------------
+ if (qaCfg->DoVZERO()) {
+ gROOT->LoadMacro(pwgpp+"/PilotTrain/AddTaskVZEROQA.C");
+ AliAnalysisTaskSE * taskv0qa = AddTaskVZEROQA(0);
+ }
+ if (qaCfg->DoVZEROPbPb() && grp->IsAA()) {
+ gROOT->LoadMacro(pwgpp+"/VZERO/AddTaskVZEROPbPb.C");
+ AliAnaVZEROPbPb* taskV0PbPb =
+ (AliAnaVZEROPbPb*)AddTaskVZEROPbPb(Int_t(grp->run));
+ }
+ // --- 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)
+ if (qaCfg->DoTPC()) {
+ gROOT->LoadMacro(pwgpp+"/TPC/macros/AddTaskPerformanceTPCdEdxQA.C");
+ AliPerformanceTask *tpcQA = 0;
+ if (grp->IsAA()) {
+ // High multiplicity Pb-Pb
+ tpcQA = AddTaskPerformanceTPCdEdxQA(kTRUE, kTRUE, kTRUE);
+ } else {
+ // Low multiplicity (pp)
+ tpcQA = AddTaskPerformanceTPCdEdxQA(kTRUE, kTRUE, kFALSE);
+ }
+ tpcQA->SelectCollisionCandidates(kTriggerMask);
+ AliPerformanceRes::SetMergeEntriesCut(5000000);
+ }
+
+ // --- HLT (Alberica Toia) -----------------------------------------
+ if (qaCfg->DoHLT()) {
+ gROOT->LoadMacro(pwgpp+"/TPC/macros/AddTaskPerformanceTPCdEdxQA.C");
+ AliPerformanceTask *hltQA = AddTaskPerformanceTPCdEdxQA(kTRUE, kTRUE, kFALSE,0,kTRUE);
+ hltQA->SelectCollisionCandidates(kTriggerMask);
+ }
+ // --- SPD (A. Mastroserio) ----------------------------------------
+ if (qaCfg->DoSPD()) {
+ gROOT->LoadMacro(pwgpp+"/PilotTrain/AddTaskSPDQA.C");
+ AliAnalysisTaskSPD* taskspdqa = (AliAnalysisTaskSPD*)AddTaskSPDQA();
+ // Request from Annalisa
+ if (grp->IsAA()) taskspdqa->SetHeavyIonMode();
+ taskspdqa->SelectCollisionCandidates(kTriggerMask);
+ taskspdqa->SetOCDBInfo(grp->run, "raw://");
+ }
+ // --- SDD (F. Prino) ----------------------------------------------
+ if (qaCfg->DoSDD()) {
+ gROOT->LoadMacro(pwgpp+"/PilotTrain/AddSDDPoints.C");
+ AliAnalysisTaskSE* tasksdd = AddSDDPoints();
+ tasksdd->SelectCollisionCandidates(kTriggerMask);
+ }
+ // --- SSD dEdx (Marek Chojnacki) ----------------------------------
+ if (qaCfg->DoSSDdEdx()) {
+ gROOT->LoadMacro(pwgpp+"/PilotTrain/AddTaskdEdxSSDQA.C");
+ AliAnalysisTaskSE* taskssddedx = AddTaskdEdxSSDQA();
+ taskssddedx->SelectCollisionCandidates(kTriggerMask);
+ }
+
+ // --- ITS ---------------------------------------------------------
+ if (qaCfg->DoITS()) {
+ // hardcoded non-zero trigger mask
+ gROOT->LoadMacro(pwgpp+"/macros/AddTaskPerformanceITS.C");
+ AliAnalysisTaskITSTrackingCheck *itsQA = 0;
+ AliAnalysisTaskITSTrackingCheck *itsQACent0010 = 0;
+ AliAnalysisTaskITSTrackingCheck *itsQACent3050 = 0;
+ AliAnalysisTaskITSTrackingCheck *itsQACent6080 = 0;
+ if(grp->IsPP()) {
+ itsQA = AddTaskPerformanceITS(kTRUE);
+ } else {
+ itsQA = AddTaskPerformanceITS(kTRUE);
+ itsQACent0010 = AddTaskPerformanceITS(kTRUE,kFALSE,kFALSE,3500,10000);
+ itsQACent3050 = AddTaskPerformanceITS(kTRUE,kFALSE,kFALSE,590,1570);
+ itsQACent6080 = AddTaskPerformanceITS(kTRUE,kFALSE,kFALSE,70,310);
+ }
+ }
+ // --- ITS saTracks, align (F.Prino) -------------------------------
+ if (qaCfg->DoITSsaTracks()) {
+ // offline trigger in AddTask
+ gROOT->LoadMacro(pwgpp+"/macros/AddTaskITSsaTracks.C");
+ AliAnalysisTaskITSsaTracks *itssaTracks = AddTaskITSsaTracks(kTRUE,kFALSE);
+ itssaTracks->SelectCollisionCandidates(kTriggerMask);
+ }
+ if (qaCfg->DoITSalign()) {
+ // no offline trigger selection
+ gROOT->LoadMacro(pwgpp+"/macros/AddTaskITSAlign.C");
+ AliAnalysisTaskITSAlignQA *itsAlign = AddTaskITSAlign(0,2011);
+ }
+
+ // --- TRD (Alex Bercuci, M. Fasel) --------------------------------
+ if(qaCfg->DoTRD()) {
+ // no offline trigger selection
+ gROOT->LoadMacro(pwgpp+"/macros/AddTrainPerformanceTRD.C");
+ // steer individual TRD tasks
+ Bool_t
+ doCheckESD(kTRUE), // AliTRDcheckESD
+ doCheckDET(kTRUE), // AliTRDcheckDET
+ doEffic(kTRUE), // AliTRDefficiency
+ doResolution(kTRUE),// AliTRDresolution
+ doCheckPID(kTRUE), // AliTRDcheckPID
+ doV0Monitor(kFALSE);// AliTRDv0Monitor
+ AddTrainPerformanceTRD(Translate(doCheckESD, doCheckDET, doEffic,
+ doResolution, doCheckPID, doV0Monitor));
+ }
+
+ // --- ZDC (Chiara Oppedisano) -------------------------------------
+ if(qaCfg->DoZDC()) {
+ // hardcoded kMB trigger mask
+ gROOT->LoadMacro(pwgpp+"/ZDC/AddTaskZDCQA.C");
+ AliAnalysisTaskSE *taskZDC = AddTaskZDCQA();
+ taskZDC->SelectCollisionCandidates(kTriggerMask);
+ }
+
+ // --- Calorimetry (Gustavo Conesa) --------------------------------
+ if(qaCfg->DoCALO() && !is10h) {
+ gROOT->LoadMacro(pwgga+
+ "/CaloTrackCorrelations/macros/QA/AddTaskCalorimeterQA.C");
+ AliAnalysisTaskCaloTrackCorrelation *taskCaloQA =
+ AddTaskCalorimeterQA("default");
+ taskCaloQA->SetDebugLevel(0);
+ // offline mask set in AddTask to kMB
+ taskCaloQA->SelectCollisionCandidates(kTriggerMask);
+ // Add a new calo task with EMC1 trigger only
+ if (!is10h) {
+ taskCaloQA = AddTaskCalorimeterQA("trigEMC");
+ taskCaloQA->SetDebugLevel(0);
+ taskCaloQA->SelectCollisionCandidates(kTriggerEMC);
+ }
+ }
+
+ // --- Muon Trigger ------------------------------------------------
+ if(qaCfg->DoMUONTrig()) {
+ // no offline trigger selection
+ gROOT->LoadMacro(pwgpp+"/macros/AddTaskMTRchamberEfficiency.C");
+ AliAnalysisTaskTrigChEff *taskMuonTrig = AddTaskMTRchamberEfficiency();
+ }
+
+ // --- Muon Efficiency (not used) ----------------------------------
+ if(qaCfg->DoMUONEff()) {
+ gROOT->LoadMacro(ali+"/PWG3/muondep/AddTaskMUONTrackingEfficiency.C");
+ AliAnalysisTaskMuonTrackingEff *taskMuonTrackEff =
+ AddTaskMUONTrackingEfficiency();
+ }
+
+ // --- V0-Decay Reconstruction (Ana Marin) (not used) --------------
+ if (qaCfg->DoV0()) {
+ gROOT->LoadMacro(pwgpp+"/macros/AddTaskV0QA.C");
+ AliAnalysisTaskV0QA *taskv0QA = AddTaskV0QA(kTRUE);
+ }
+
+ // -- Impact parameter resolution ----------------------------------
+ // (xianbao.yuan@pd.infn.it, andrea.dainese@pd.infn.it)
+ if (qaCfg->DoImpParRes()) {
+ gROOT->LoadMacro(pwgpp+"/macros/AddTaskImpParRes.C");
+ AliAnalysisTaskSE* taskimpparres=0;
+ // Specific setting for MC
+ if(grp->IsPP()) {
+ taskimpparres= AddTaskImpParRes(kTRUE);
+ } else {
+ taskimpparres= AddTaskImpParRes(kTRUE,-1,kTRUE,kFALSE);
+ }
+ taskimpparres->SelectCollisionCandidates(kTriggerMask);
+ }
+
+ // --- MUON QA (Philippe Pillot) -----------------------------------
+ if (qaCfg->DoMUON()) {
+ // trigger analysis internal
+ gROOT->LoadMacro(pwgpp+"/PilotTrain/AddTaskMuonQA.C");
+ AliAnalysisTaskSE* taskmuonqa= AddTaskMuonQA();
+ }
+
+ // --- TOF (Francesca Bellini) -------------------------------------
+ if (qaCfg->DoTOF()) {
+ gROOT->LoadMacro(pwgpp+"/TOF/AddTaskTOFQA.C");
+ AliAnalysisTaskTOFqa *tofQA = AddTaskTOFQA(kFALSE);
+ tofQA->SelectCollisionCandidates(kTriggerMask);
+ }
+
+ // --- PIDqa(JENS) -------------------------------------------------
+ if (qaCfg->DoPIDqa() && !is10h) {
+ gROOT->LoadMacro(ana+"/macros/AddTaskPIDqa.C");
+ AliAnalysisTaskPIDqa *PIDQA = AddTaskPIDqa();
+ PIDQA->SelectCollisionCandidates(kTriggerMask);
+ }
+
+ // --- HMPID QA (Giacomo Volpe) ------------------------------------
+ //
+ if (qaCfg->DoHMPID()) {
+ gROOT->LoadMacro(pwgpp+"/HMPID/AddTaskHmpidQA.C");
+ AliAnalysisTaskSE* taskhmpidqa= AddTaskHmpidQA(kTRUE);
+ // offline mask set in AddTask to kMB
+ taskhmpidqa->SelectCollisionCandidates(kTriggerMask);
+ }
+
+ // --- T0 QA (Alla Mayevskaya) -------------------------------------
+ if (qaCfg->DoT0()) {
+ // no offline trigger selection
+ gROOT->LoadMacro(pwgpp+"/T0/AddTaskT0QA.C");
+ AliT0AnalysisTaskQA* taskt0qa= AddTaskT0QA();
+ taskt0qa->SelectCollisionCandidates(kTriggerMask);
+ }
+
+ // ---- FMD QA (Christian Holm Christiansen) -----------------------
+ if (qaCfg->DoFWD()) {
+ gROOT->LoadMacro(pwglf+"/FORWARD/analysis2/AddTaskForwardQA.C");
+ // Parameters: usemc, usecentrality
+ // AliAnalysisTaskSE *forwardQA = (AliAnalysisTaskSE *)
+ AddTaskForwardQA(kTRUE, qaCfg->DoCentrality());
+ // HACK: to read corrections from current directory
+ const char* hack="AliForwardCorrectionManager::Instance().SetPrefix(\".\")";
+ gROOT->ProcessLine(hack);
+ const char* hack2="AliForwardCorrectionManager::Instance().Print(\"R\")";
+ gROOT->ProcessLine(hack2);
+ // No offline trigger config. needed (see #84077)
+ }
+
+ // --- PHOS QA (Boris Polishchuk) ----------------------------------
+ if (qaCfg->DoPHOS()) {
+ gROOT->LoadMacro(pwgga+"/PHOSTasks/CaloCellQA/macros/AddTaskCaloCellsQA.C");
+ AliAnalysisTaskCaloCellsQA *taskPHOSCellQA1 =
+ AddTaskCaloCellsQA(4, 1, NULL,"PHOSCellsQA_AnyInt");
+ taskPHOSCellQA1->SelectCollisionCandidates(kTriggerMask);
+ taskPHOSCellQA1->GetCaloCellsQA()->SetClusterEnergyCuts(0.3,0.3,1.0);
+
+ AliAnalysisTaskCaloCellsQA *taskPHOSCellQA2 =
+ AddTaskCaloCellsQA(4, 1, NULL,"PHOSCellsQA_PHI7");
+ taskPHOSCellQA2->SelectCollisionCandidates(AliVEvent::kPHI7);
+ taskPHOSCellQA2->GetCaloCellsQA()->SetClusterEnergyCuts(0.3,0.3,1.0);
+
+ // Pi0 QA fo PbPb
+ if (grp->IsAA()) {
+ gROOT->LoadMacro(pwgga+"/PHOSTasks/PHOS_PbPbQA/macros/AddTaskPHOSPbPb.C");
+ AliAnalysisTaskPHOSPbPbQA* phosPbPb = AddTaskPHOSPbPbQA(0);
+ }
+ }
+ if (qaCfg->DoPHOSTrig()) {
+ gROOT->LoadMacro(pwgga+
+ "/PHOSTasks/PHOS_TriggerQA/macros/AddTaskPHOSTriggerQA.C");
+ AliAnalysisTaskPHOSTriggerQA *taskPHOSTrig = AddTaskPHOSTriggerQA(0,0);
+ }
+
+ // --- EMCAL QA (Gustavo Conesa) -----------------------------------
+ if (qaCfg->DoEMCAL()) {
+ gROOT->LoadMacro(pwgga+"/EMCALTasks/macros/AddTaskEMCALTriggerQA.C");
+ AliAnalysisTaskEMCALTriggerQA *emctrig = AddTaskEMCALTriggerQA();
+ }
+
+ // --- FLOW and BF QA (C.Perez && A.Rodriguez) ---------------------
+ if (qaCfg->DoFBFqa()) {
+ gROOT->LoadMacro(pwgpp+"/macros/AddTaskFBFqa.C");
+ AliAnalysisTaskSE *qaFBFMB = (AliAnalysisTaskSE*)AddTaskFBFqa("qaFBFmb",
+ kFALSE);
+ qaFBFMB->SelectCollisionCandidates(AliVEvent::kMB);
+ AliAnalysisTaskSE *qaFBFSC = (AliAnalysisTaskSE*)AddTaskFBFqa("qaFBFsc",
+ kFALSE);
+ qaFBFSC->SelectCollisionCandidates(AliVEvent::kSemiCentral);
+ AliAnalysisTaskSE *qaFBFCE = (AliAnalysisTaskSE*)AddTaskFBFqa("qaFBFce",
+ kFALSE);
+ qaFBFCE->SelectCollisionCandidates(AliVEvent::kCentral);
+ }
+}
+
+//====================================================================
+/**
+ * Run QA merging
+ *
+ * @param dir directory
+ * @param stage stage
+ */
+void QAMerge(const char *dir, Int_t stage)
+{
+// Merging method
+ TStopwatch timer; timer.Start();
+ TString outputDir = dir;
+ TString outputFiles = "QAresults.root,EventStat_temp.root";
+ TString mergeExcludes = "";
+ TObjArray* tokens = outputFiles.Tokenize(",");
+ TIter iter(tokens);
+ TObjString* str = 0;
+ TString outputFile;
+ Bool_t merged = kTRUE;
+ while((str = static_cast<TObjString*>(iter()))) {
+ outputFile = str->GetString();
+ // Skip already merged outputs
+ if (!gSystem->AccessPathName(outputFile)) {
+ printf("Output file <%s> found. Not merging again.",
+ outputFile.Data());
+ continue;
+ }
+ if (mergeExcludes.Contains(outputFile.Data())) continue;
+ merged = AliAnalysisAlien::MergeOutput(outputFile,
+ outputDir,
+ 10,
+ stage);
+ if (!merged) {
+ printf("ERROR: Cannot merge %s\n", outputFile.Data());
+ continue;
+ }
+ }
+ TString infolog = "fileinfo.log";
+ AliAnalysisAlien::MergeInfo(infolog, dir);
+
+ if (!outputDir.Contains("Stage")) {
+ ofstream out;
+ out.open("outputs_valid", ios::out);
+ out.close();
+ return;
+ }
+ // --- Set up to run terminate -------------------------------------
+ AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
+ mgr->SetRunFromPath(mgr->GetRunFromAlienPath(dir));
+ mgr->SetSkipTerminate(kFALSE);
+ if (!mgr->InitAnalysis()) return;
+ mgr->PrintStatus();
+ AliLog::SetGlobalLogLevel(AliLog::kError);
+ TTree *tree = NULL;
+ gROOT->cd();
+ mgr->StartAnalysis("gridterminate", tree);
+ ofstream out;
+ out.open("outputs_valid", ios::out);
+ out.close();
+ timer.Print();
+}
+
+//====================================================================
+/**
+ * Run QA trains
+ *
+ * @param run Run number
+ * @param xmlfile Collection file
+ * @param stage Stage
+ * @param train Train
+ * @param cdb CDB location
+ */
+void QA(UInt_t run,
+ const char* xmlfile = "wn.xml",
+ Int_t stage = 0, /*0 = QA train, 1...n - merging stage*/
+ const char* cdb = "raw://")
+{
+ // -----------------------------------------------------------------
+ //
+ // Get GRP parameters. Defines global "grp" as a pointer to GRPData
+ //
+ gROOT->Macro(Form("GRP.C(%d)", run));
+ gROOT->Macro("QAConfig.C");
+ Int_t debug_level = qaCfg->DebugLevel(); // Debugging
+ TString cdbString(cdb);
+ if (cdbString.Contains("raw://")) {
+ TGrid::Connect("alien://");
+ if (!gGrid || !gGrid->IsConnected()) {
+ ::Error("QAtrain", "No grid connection");
+ return;
+ }
+ }
+
+ // --- Some settings -----------------------------------------------
+ // Set temporary merging directory to current one
+ gSystem->Setenv("TMPDIR", gSystem->pwd());
+ // Set temporary compilation directory to current one
+ gSystem->SetBuildDir(gSystem->pwd(), kTRUE);
+ // Load common libraries and set include path
+ LoadLibraries();
+ printf("Include path: %s\n", gSystem->GetIncludePath());
+
+ // === Make the analysis manager and connect event handlers ========
+ //
+ // --- Analysis manager and load libraries -------------------------
+ AliAnalysisManager *mgr = new AliAnalysisManager("QA", "Production train");
+ mgr->SetRunFromPath(grp->run);
+
+ // --- Create ESD input handler ------------------------------------
+ AliESDInputHandlerRP *esdHandler = new AliESDInputHandlerRP();
+ esdHandler->SetReadFriends(kTRUE);
+ esdHandler->SetActiveBranches("ESDfriend");
+ mgr->SetInputEventHandler(esdHandler);
+
+ // --- Monte Carlo handler -----------------------------------------
+ if (true) {
+ AliMCEventHandler* mcHandler = new AliMCEventHandler();
+ mgr->SetMCtruthEventHandler(mcHandler);
+ mcHandler->SetPreReadMode(1);
+ mcHandler->SetReadTR(true);
+ }
+
+ // === Set up tasks ================================================
+ //
+ // --- Create tasks ------------------------------------------------
+ AddAnalysisTasks(cdb);
+
+ // --- Debugging if needed -----------------------------------------
+ if (debug_level > 0) mgr->SetDebugLevel(debug_level);
+
+ // --- If merging, do so here and exit -----------------------------
+ if (stage>0) {
+ QAMerge(xmlfile, stage);
+ return;
+ }
+
+ // === Run the analysis ============================================
+ //
+ // --- Make our chain ----------------------------------------------
+ TChain *chain = new TChain("esdTree");
+ chain->Add("AliESDs.root");
+
+ // --- Run the thing -----------------------------------------------
+ TStopwatch timer;
+ timer.Start();
+ if (mgr->InitAnalysis()) {
+ mgr->PrintStatus();
+ mgr->SetSkipTerminate(kTRUE);
+ mgr->SetNSysInfo(1);
+ mgr->StartAnalysis("local", chain);
+ }
+ timer.Print();
+}
+
+//
+// EOF
+//
+
--- /dev/null
+struct QACfg : public VirtualQACfg
+{
+ /** @return */
+ virtual Bool_t DoCDBconnect() const { return true; }
+ /** @return */
+ virtual Bool_t DoEventStat() const { return true; }
+ /** @return */
+ virtual Bool_t DoCentrality() const { return true; }
+ /** @return */
+ virtual Bool_t DoQAsym() const { return false; }
+ /** @return there is a 2nd file */
+ virtual Bool_t DoVZERO() const { return true; }
+ /** @return */
+ virtual Bool_t DoVZEROPbPb() const { return false; }
+ /** @return */
+ virtual Bool_t DoVertex() const { return true; }
+ /** @return needs RP */
+ virtual Bool_t DoSPD() const { return true; }
+ /** @return */
+ virtual Bool_t DoTPC() const { return true; }
+ /** @return */
+ virtual Bool_t DoHLT() const { return true; }
+ /** @return needs RP */
+ virtual Bool_t DoSDD() const { return true; }
+ /** @return */
+ virtual Bool_t DoSSDdEdx() const { return true; }
+ /** @return */
+ virtual Bool_t DoTRD() const { return true; }
+ /** @return */
+ virtual Bool_t DoITS() const { return true; }
+ /** @return */
+ virtual Bool_t DoITSsaTracks() const { return true; }
+ /** @return */
+ virtual Bool_t DoITSalign() const { return true; }
+ /** @return */
+ virtual Bool_t DoCALO() const { return true; }
+ /** @return */
+ virtual Bool_t DoMUONTrig() const { return true; }
+ /** @return */
+ virtual Bool_t DoImpParRes() const { return true; }
+ /** @return */
+ virtual Bool_t DoMUON() const { return true; }
+ /** @return */
+ virtual Bool_t DoTOF() const { return true; }
+ /** @return */
+ virtual Bool_t DoHMPID() const { return true; }
+ /** @return */
+ virtual Bool_t DoT0() const { return true; }
+ /** @return */
+ virtual Bool_t DoZDC() const { return true; }
+ /** @return */
+ virtual Bool_t DoPIDResponse() const { return true; }
+ /** @return */
+ virtual Bool_t DoPIDqa() const { return true; }
+ /** @return */
+ virtual Bool_t DoFWD() const { return true; }
+ /** @return */
+ virtual Bool_t DoPHOS() const { return true; }
+ /** @return */
+ virtual Bool_t DoPHOSTrig() const { return true; }
+ /** @return */
+ virtual Bool_t DoEMCAL() const { return false; }
+ /** @return */
+ virtual Bool_t DoFBFqa() const { return true; }
+ /** @return NEEDS geometry */
+ virtual Bool_t DoMUONEff() const { return false; }
+ /** @return NEEDS MCtruth */
+ virtual Bool_t DoV0() const { return false; }
+ /** @return Get Debug level */
+ virtual Int_t DebugLevel() const { return 1; }
+};
+
+void QAConfig()
+{
+ Info("QAConfig", "Creating configuration object");
+ qaCfg = new QACfg();
+}
+
+//
+// EOF
+//
--- /dev/null
+# Simulation Files for PWGLF/FORWARD Production
+
+Christian Holm Christensen
+<cholm@nbi.dk>
+
+## Introduction
+
+The files in this archive represents a generic approach to running
+AliROOT based simulations. The idea is that the user/committer only
+specifies the run number for which an anchor run is needed, and
+possibly an event generator.
+
+## Considerations
+
+The shell and ROOT scripts, JDLs, and so on are based on previous
+"official" production files, but with some differences. The main
+difference comes about because we want to _automatically_ configure
+the simulation based on the relevant GRP OCDB entry as possible.
+
+To that end, I created the ROOT script `GRP.C` which will query the
+OCDB for GRP for a specified run. In this way, we can get the beam
+species, energy, and center of mass energy simply by passing a run
+number. We can also select a default event generator based on these
+settings.
+
+* For pp, the default generator is *Pythia6*
+* For PbPb, the default generator is *Hijing*
+* For pPb/Pbp, the default generator is *DpmJet*
+
+However, since all steps need to have access to the GRP data, it means
+that all steering scripts must load `GRP.C`, and hence we can at no
+point use any of previously used scripts.
+
+## The files
+
+* `run.sh`: main steering executable (same as
+ `/alice/bin/aliroot_new`)
+* `AOD.C`: AOD Filter train set-up. Derived from `AODtrainsim.C` but
+ modified to automatically get GRP parameters from OCDB using the
+ script `GRP.C` and set-up the train accordingly. Also, selection of
+ which tasks to include is done through the script `AODConfig.C`.
+ That means this script should never be modified by the user.
+* `AODConfig.C`: Read by `AOD.C` to configure which tasks to include
+ in the train.
+* `Check.C`: Perform ESD check. Derived from `CheckESD.C`.
+* `Config.C`: Simulation configuration script. Uses `GRP.C` to
+ automatically load the proper parameters for the Anchor run.
+* `Final.jdl.in`: Skeleton for final merging JDL. This is used for
+ both QA and AOD filtering.
+* `GRP.C`: Script that defines the global variable `grp` which is
+ filled with values from the appropriate OCDB GRP entry for the
+ selected run. This is used in `AOD.C`, `Config.C`, `QA.C`,
+ `Reconstruct.C`, and `Simulate.C`.
+* `LHC10hPS.C`: Special Physics Selection set-up for LHC10h due to
+ missing ZDC information to the trigger. Not needed as far as I can
+ tell.
+* `Merge.jdl.in`: Skeleton for intermediate merging JDL. This is used for
+ both QA and AOD filtering.
+* `QA.C`: QA train set-up. Derived from `QAtrainsim.C` but
+ modified to automatically get GRP parameters from OCDB using the
+ script `GRP.C` and set-up the train accordingly. Also, selection of
+ which tasks to include is done through the script `QAConfig.C`.
+ That means this script should never be modified by the user.
+* `QAConfig.C`: Read by `QA.C` to configure which tasks to include
+ in the train.
+* `Reconstruct.C`: Reconstruction steering script. Derived from
+ `rec.C` but modified to automatically get GRP parameters from OCDB
+ using the script `GRP.C` and set-up the job accordingly.
+* `Run.jdl.in`: Skeleton for initial stage running.
+* `simrun.sh`: Simulation shell script. Derived from basic `simrun.sh`
+ but adapted to the files here, allows passing the number of events
+ per job, pass the run number to relevant scripts, ignores
+ meaningless options.
+* `Simulate.C`: Simulation steering script. Derived from `sim.C` but
+ modified to automatically get GRP parameters from OCDB using the
+ script `GRP.C` and set-up the job accordingly.
+* `Tag.C`: Tag ESD files.
+* `merge.sh`: Shell script to steer merging jobs. Used by both
+ QA and AOD filtering. This is based on `/alice/bin/train_merge.sh`
+ but modified to call either the QA or AOD train merging.
+
+The shell script `doit.sh` is the omnipotent script that steers all
+parts of the simulation.
+
+## Usage of `doit.sh`
+
+ Usage: ./doit.sh [OPTIONS]
+
+ Options:
+ -h,--help This help
+ -t|--tag TAG Job tag (pp)
+ -i|--id NAME Name of production
+ -R|--run RUN_NO Run number
+ -c|--copy Copy files to AliEn
+ -n|--jobs JOBS Set number of jobs[**] (2)
+ -m|--events EVENTS Set events/job[**] (1)
+ -s|--stage STAGE Set the stage[***] (0)
+ -o|--output DIR Set base output directory[*] ($ALIEN_HOME/test)
+ -d|--data DIR Set data directory ($ALIEN_HOME/mc)
+ -b|--bin DIR Set base bin directory[*] ($ALIEN_HOME/bin)
+ -a|--aliroot RELEASE Set AliROOT release [*] (v5-04-Rev-20)
+ -r|--root RELEASE Set ROOT release [*] ()
+ -g|--geant RELEASE Set GEANT3 release [*] ()
+
+ [*] Only make sense with option -c
+ [**] Only make sense for stage 0
+ [***] If stage is set to 6, try to deduce the stage
+ automatically. If less than zero, do not do anything but copy
+
+Note, if the ROOT and GEANT release is not specified, it will be
+deduced from the AliROOT version.
+
+* Make JDLs and copy files to `/alice/cern.ch/user/a/aliprod/PWGLFforwardMC`,
+ specifying that output should be based in `/alice/sim/2014`, and we
+ should use AliROOT v5-05-Rev-11, but not submitting any jobs
+
+ ./doit.sh -a v5-05-Rev-11 \
+ -d /alice/cern.ch/user/a/aliprod/PWGLFforwardMC \
+ -o /alice/sim/2014 \
+ -c \
+ -s -1
+
+* Submit 100 jobs each with 10 events for run 118506 with the same
+ parameters as above, using PhoJet
+
+ ./doit.sh -d /alice/cern.ch/user/a/aliprod/PWGLFforwardMC \
+ -i LHC14z9a -r 118506 -s 0 -n 100 -m 10 -g PhoJet
+
+ Output will end up in `/alice/sim/2014/LHC14z9a/118506`
+
+* Submit merging jobs for the above production
+
+ ./doit.sh -d /alice/cern.ch/user/a/aliprod/PWGLFforwardMC \
+ -i LHC14z9a -r 118506 -s 6
+
+ Output will end up in `/alice/sim/2014/LHC14z9a/118506/`. Repeat
+ this until we hit the final merging.
+
+## `Config.C`
+
+The `Config.C` configuration script has been trimmed down
+considerably. The script is now very generic since most settings are
+derived from the GRP data. The only thing that remains to be selected
+in this script is the event generator.
+
+When selecting the event generator, a more versatile and configurable
+approach has been taken. `Config.C` defines the class `Setup` with
+the constructor `Setup::Setup(const char* genName)`. Here `genName`
+is passed verbatim from the `Run.jdl` JDL file. The method
+`Setup::MakeGenerator()` then internally has a switch on this string
+to find the chosen event generator. If no suitable generator can be
+found, the script will fail with a `Fatal` signal.
+
+Generators are specified as
+
+> _name_[_sub-type_[_sub-sub-type_]]
+
+where _sub-type_ (and _sub-sub-type_) are optional. Currently defined
+event generators are (case insensitive)
+
+* `pythia` Pythia6 Min.Bias. Optional sub-types
+ * `perugia0` Perugia0 tune. Optional sub-sub-types
+ * `chadr` Heavy flavour charm w/hadronic decay signals added
+ * `bchadr` Heavy flavour beauty/charm w/hadronic decay signals added
+ * `cele` Heavy flavour charm signals added
+ * `bele` Heavy flavour beauty/charm signals added
+ * `jspi2e` J/Psi to electrons signals added
+ * `btojspi2e` Beauty to J/Psi to electrons signals added
+ * `D6T` Rick Field's CDF Tune D6T
+ * `atlas` Arthur Moraes' (new) ATLAS tune, possibly with
+ sub-sub-type
+ * `_flat` for flat multiplicity probability from 0 to 200
+ * `jets` Jets in central barrel
+* `hijing` Hijing Min.Bias. Optional sub-types. For pPb and Pbp a
+ cocktail with slow neutrons is made
+ * `2000` No quenching and hard pT cut at 2.3GeV. Possible
+ sub-sub-types are
+ * `hf` Random heavy flavour signal added (see for pythia
+ above).
+* `ampt` AMPT min bias. Possible sub types are
+ * `hf` Random heavy flavour signal added (see for pythia
+ above).
+* `dpmjet`
+* `phojet` Same as `dpmjet`
+* `hydjet`
+
+More generators can easily be added.
+
+
+## JDL Parameters
+
+### `Run.jdl`
+
+* _run number_: The run number
+* _n jobs_: Number of sub-jobs to commit
+* _n events_: Number of events per sub-job
+* _tag_: The tag to put in produced files under (e.g., `LHC14z9a`)
+
+### `Merge.jdl`
+
+* _run number_: The run number
+* _stage_: Stage number (1-4)
+* _tag_: The tag to put in produced files under (e.g., `LHC14z9a`)
+* _what_: What to merge: either `AOD` or `QA`
+
+### `Final.jdl`
+
+* _run number_: The run number
+* _stage_: Stage number (1-4)
+* _tag_: The tag to put in produced files under (e.g., `LHC14z9a`)
+* _what_: What to merge: either `AOD` or `QA`
+
+## JDL Skeleton Substitutions
+
+* _@out@_: The base of the output directory e.g., `/alice/sim/2014/`
+* _@data@_: The directory where scripts, etc. are stored e.g.,
+ `/alice/cern.sh/user/a/aliprod/PWGLFforwardMC`
+* _@aliroot@_: AliROOT version to use e.g., `v5-04-Rev-20`
+* _@root@_: ROOT version to use e.g., `v5-34-08-6`
+* _@geant@_: GEANT3 version to use e.g., `v1-15a-1`
+
+## ROOT Script Prototypes
+
+### `AOD.C(UInt_t run, const char* xmlfile, Int_t stage)`
+
+* _run_: The run number
+* _xmlfile_: Not used, compatibility with `QA.C`
+* _stage_: Running stage (0: production, otherwise merge)
+
+### `QA.C(UInt_t run, const char* xmlfile, Int_t stage)`
+
+* _run_: The run number
+* _xmlfile_: Current list of input files. Must not contain `Stage`
+ for final merging.
+* _stage_: Running stage (0: production, otherwise merge)
+
+### `GRP.C(UInt_t run)`
+
+* _run_: The run number
+
+### `Reconstruct.C(UInt_t run)`
+
+* _run_: The run number
+
+### `Simulate.C(UInt_t run, Int_t nev)`
+
+* _run_: The run number
+* _nev_: Number of events per sub-job
+
+## Shell Script Arguments
+
+### `run.sh`
+
+All arguments are passed on to other script e.g., `simrun.sh`
+
+### `simrun.sh`
+
+* _--run_ *RUN*: The Run number
+* _--event_ *INTEGER*: Number of events per sub-job
+* _--process_ *LABEL*: The Event Generator to use. If not specified
+ or equal to `default` then select default EG based on collision
+ system.
+* _--field_ *VALUE*: Ignored - obtained from OCDB
+* _--energy_ *VALUE*: Ignored - obtained from OCDB
+* _--physicslist_ *VALUE*: Ignored
+* _--bmin_ FERMI: Least imapact parameter
+* _--bmax_ FERMI: Largest imapact parameter
+* _--pthardbin_ *VALUE*: Ignored
+* _--quench_ *VALUE*: Quenching type to use
+* _--sdd_: Ignored
+* _--number-- *INTEGER*: Sub-job number
+* _--qa__: Also run QA train
+* _--aod_: Also run AOD train
+
+### `merge.sh`
+
+* _which_: What to do merging of (either `QA` or `AOD`)
+* _run_: The run number
+* _dir_: Directory where intermediate data can be found
+* _stage_: Stage to execute
+
+
+Local Variables:
+ mode: markdown
+End:
+
+
--- /dev/null
+Int_t getIntEnv(const char* name)
+{
+ TString env = gSystem->Getenv(name);
+ if (env.IsNull()) return 0;
+ return env.Atoi();
+}
+void SetSpecStore(AliCDBManager& s,
+ const char* key,
+ const char* sub)
+{
+ s.SetSpecificStorage(key, Form("alien://Folder=/alice/simulation/%s",sub));
+}
+
+
+void Reconstruct(UInt_t run)
+{
+ // -----------------------------------------------------------------
+ //
+ // Get GRP parameters. Defines global "grp" as a pointer to GRPData
+ //
+ gROOT->Macro(Form("GRP.C(%d)", run));
+
+ // -----------------------------------------------------------------
+ //
+ // Basic setup
+ //
+ AliReconstruction reco;
+ reco.SetRunReconstruction("ITS TPC TRD TOF PHOS HMPID "
+ "EMCAL MUON FMD ZDC PMD T0 VZERO");
+
+
+ // -----------------------------------------------------------------
+ //
+ // switch off cleanESD, write ESDfriends and Alignment data
+ //
+ reco.SetCleanESD(kFALSE);
+ reco.SetWriteESDfriend();
+ reco.SetFractionFriends(.1);
+ reco.SetWriteAlignmentData();
+
+ // -----------------------------------------------------------------
+ //
+ // ITS Efficiency and tracking errors
+ //
+ reco.SetRunPlaneEff(kTRUE);
+ reco.SetUseTrackingErrorsForAlignment("ITS");
+
+
+ // -----------------------------------------------------------------
+ //
+ // Raw OCDB
+ //
+ AliCDBManager* man = AliCDBManager::Instance();
+ man->SetDefaultStorageFromRun(grp->run);
+
+ // --- Get GRP to deduce collision system --------------------------
+ Bool_t isAA = grp->IsAA();
+ Bool_t is10h = grp->period.EqualTo("LHC10h");
+
+ // --- ITS (2 objects) ---------------------------------------------
+ SetSpecStore(*man,"ITS/Align/Data", "2008/v4-15-Release/Residual");
+ SetSpecStore(*man,"ITS/Calib/SPDSparseDead", "2008/v4-15-Release/Residual");
+
+
+ // --- MUON objects (1 object) -------------------------------------
+ SetSpecStore(*man,"MUON/Align/Data", "2008/v4-15-Release/Residual");
+
+ // --- TPC (7 objects) ---------------------------------------------
+ SetSpecStore(*man,"TPC/Align/Data", "2008/v4-15-Release/Residual");
+ SetSpecStore(*man,"TPC/Calib/ClusterParam", "2008/v4-15-Release/Residual");
+ SetSpecStore(*man,"TPC/Calib/RecoParam", "2008/v4-15-Release/Residual");
+ SetSpecStore(*man,"TPC/Calib/TimeGain", "2008/v4-15-Release/Residual");
+ SetSpecStore(*man,"TPC/Calib/AltroConfig", "2008/v4-15-Release/Residual");
+ SetSpecStore(*man,"TPC/Calib/TimeDrift", "2008/v4-15-Release/Residual");
+ SetSpecStore(*man,"TPC/Calib/Correction", "2008/v4-15-Release/Residual");
+
+
+ // --- ZDC ---------------------------------------------------------
+ // ZDC for 2010 the following is needed
+ // (https://savannah.cern.ch/task/?func=detailitem&item_id=33180#comment46)
+ if (is10h) {
+ reco.SetRecoParam("ZDC",AliZDCRecoParamPbPb::GetHighFluxParam(2760));
+ SetSpecStore(*man,"ZDC/Align/Data", "2008/v4-15-Release/Ideal/");
+ }
+
+ // --- GRP from local OCDB -----------------------------------------
+ // man->SetSpecificStorage("GRP/GRP/Data",
+ // Form("local://%s",gSystem->pwd()));
+
+
+ // --- Override some settings in the ITS reco ----------------------
+ if (is10h) {
+ printf("Overriding ITS/Calib/RecoParam for run %d to do "
+ "reco even in absence of trigger\n", grp->run);
+ man->SetRun(grp->run);
+ AliCDBEntry* entry = man->Get("ITS/Calib/RecoParam");
+ TObjArray* array = static_cast<TObjArray*>(entry->GetObject());
+ AliITSRecoParam* par = static_cast<AliITSRecoParam*>(array->RemoveAt(1));
+ par->SetSkipSubdetsNotInTriggerCluster(kFALSE);
+ reco.SetRecoParam("ITS",par);
+ }
+
+ // -----------------------------------------------------------------
+ //
+ // Do not run QA in PbPb
+ if (isAA) reco.SetRunQA(":");
+
+ // -------------------------------------------------------
+ //
+ // Now run
+ //
+ TStopwatch timer;
+ timer.Start();
+ reco.Run();
+ timer.Stop();
+ timer.Print();
+}
+//
+// EOF
+//
--- /dev/null
+#
+# To submit this JDL:
+#
+# alien_submit alien:@data@/JDL \
+# <run number> <N_jobs> <N_events> <tag> <generator>
+#
+# where
+#
+# <run number> is the run number
+# <N_jobs> is the number of sub-jobs
+# <N_events> is the number of events per sub-job
+# <tag> is a single-word tag
+# <generator> is the name of the generator
+#
+# The output is written to alien:@out@/test/<tag>
+#
+Executable="@bin@/run.sh";
+
+Jobtag={
+ "comment:$4 ($1) $5 MC"
+};
+
+Packages = {
+ "VO_ALICE@AliRoot::@aliroot@",
+ "VO_ALICE@GEANT3::@geant@",
+ "VO_ALICE@ROOT::@root@",
+ "VO_ALICE@APISCONFIG::V1.1x",
+ "VO_ALICE@boost::v1_43_0",
+ "VO_ALICE@cgal::v3.6",
+ "VO_ALICE@fastjet::v2.4.2",
+ "VO_ALICE@jemalloc::v3.0.0"
+};
+
+
+TTL="72000";
+Price="10";
+
+Requirements=member(other.GridPartitions,"PDC08_2");
+
+Validationcommand="/alice/validation/validation.sh";
+
+InputFile={
+ "LF:@data@/Check.C",
+ "LF:@data@/Config.C",
+ "LF:@data@/Reconstruct.C",
+ "LF:@data@/Simulate.C",
+ "LF:@data@/simrun.sh",
+ "LF:@data@/Tag.C",
+ "LF:@data@/QA.C",
+ "LF:@data@/QAConfig.C",
+ "LF:@data@/AOD.C",
+ "LF:@data@/AODConfig.C",
+ "LF:@data@/GRP.C",
+ "LF:@data@/fmd_corrections.root"
+};
+
+Output = {
+ "log_archive:stderr.log,stdout.log,tag.log,sim.log,rec.log,check.log,qa.log,aod.log@disk=1",
+ "QA_archive.zip:QAresults*.root,event_stat*.root,trending*.root,fileinfo*.log,*.stat.qa*@disk=2",
+ "root_archive.zip:galice.root,Kinematics.root,TrackRefs.root,Trigger.root,AliESDs.root,AliESDfriends.root,Run*.root,ITS.RecPoints.root,@disk=2",
+ "aod_archive.zip:pyxsec*.root,AODQA.root,AliAOD*.root,FilterEvents_Trees*.root,*.stat.aod@disk=3",
+ "EventStat_temp*.root@disk=2"
+};
+
+OutputDir="@out@/$4/$1/#alien_counter_03i#";
+
+JDLVariables={
+ "Packages",
+ "OutputDir"
+};
+
+#
+splitarguments="--run $1 --event $3 --process $5 --qa --aod --number #alien_counter#";
+split="production:1-$2";
+
+Workdirectorysize={"5000MB"};
--- /dev/null
+Int_t getIntEnv(const char* name)
+{
+ TString env = gSystem->Getenv(name);
+ if (env.IsNull()) return 0;
+ return env.Atoi();
+}
+void SetSpecStore(AliSimulation& s,
+ const char* key,
+ const char* sub)
+{
+ s.SetSpecificStorage(key, Form("alien://Folder=/alice/simulation/%s",sub));
+}
+
+
+void Simulate(Int_t nev=1, UInt_t run=0)
+{
+ // -----------------------------------------------------------------
+ //
+ // Get GRP parameters. Defines global "grp" as a pointer to GRPData
+ //
+ gROOT->Macro(Form("GRP.C(%d)", run));
+
+ // -----------------------------------------------------------------
+ //
+ // Basic setup
+ //
+ AliSimulation steer;
+ steer.SetMakeSDigits("TRD TOF PHOS HMPID EMCAL MUON FMD ZDC PMD T0 VZERO");
+ steer.SetMakeDigitsFromHits("ITS TPC");
+ steer.UseMagFieldFromGRP();
+ steer.UseVertexFromCDB();
+
+ // -----------------------------------------------------------------
+ //
+ // Raw OCDB
+ //
+ AliCDBManager* cdb = AliCDBManager::Instance();
+ cdb->SetDefaultStorageFromRun(grp->run);
+ // cdb->SetRun(grp.run);
+ steer.SetDefaultStorage(cdb->GetDefaultStorage()->GetURI());
+
+ // --- Get GRP to deduce collision system --------------------------
+ Bool_t isAA = grp->IsAA();
+ Bool_t isPP = grp->IsPP();
+ Bool_t is10h = grp->period.EqualTo("LHC10h");
+
+ // --- ITS (1 Total) ----------------------------------------------
+ SetSpecStore(steer,"ITS/Align/Data", "2008/v4-15-Release/Ideal");
+
+ // --- MUON (1 object) ---------------------------------------------
+ SetSpecStore(steer,"MUON/Align/Data", "2008/v4-15-Release/Ideal");
+
+ // ---- TPC (6 total) ----------------------------------------------
+ SetSpecStore(steer,"TPC/Calib/TimeGain", "2008/v4-15-Release/Ideal/");
+ SetSpecStore(steer,"TPC/Calib/ClusterParam", "2008/v4-15-Release/Ideal/");
+ SetSpecStore(steer,"TPC/Calib/AltroConfig", "2008/v4-15-Release/Ideal/");
+ SetSpecStore(steer,"TPC/Calib/Correction", "2008/v4-15-Release/Ideal/");
+ SetSpecStore(steer,"TPC/Align/Data", "2008/v4-15-Release/Ideal/");
+ SetSpecStore(steer,"TPC/Calib/RecoParam", "2008/v4-15-Release/Residual");
+ if (is10h)
+ SetSpecStore(steer,"TPC/Calib/TimeDrift", "2008/v4-15-Release/Residual/");
+ else
+ SetSpecStore(steer,"TPC/Calib/TimeDrift", "2008/v4-15-Release/Ideal/");
+
+ // --- ZDC for 2010 the following is needed ------------------------
+ // (https://savannah.cern.ch/task/?func=detailitem&item_id=33180#comment46)
+ if (is10h)
+ SetSpecStore(steer,"ZDC/Align/Data", "2008/v4-15-Release/Ideal/");
+
+ // -----------------------------------------------------------------
+ //
+ // Vertex, Mag.field, and trigger from OCDB
+ //
+ steer.UseVertexFromCDB();
+ steer.UseMagFieldFromGRP();
+ // steer.SetTriggerConfig("OCDB");
+ steer.SetTriggerConfig(!isAA ? "p-p" : "Pb-Pb");
+
+ // -----------------------------------------------------------------
+ //
+ // The rest - disable QA for PbPb
+ //
+ if (isAA) steer.SetRunQA(":");
+ // gInterpreter->UnloadFile("GetGRP.C");
+
+ TStopwatch timer;
+ timer.Start();
+ steer.Run(nev);
+ timer.Stop();
+ timer.Print();
+}
--- /dev/null
+void Tag() {
+ const char* turl = gSystem->Getenv("ALIEN_JDL_OUTPUTDIR");
+
+ gSystem->Load("libNet.so");
+ // gSystem->Load("libMonaLisa.so");
+ // new TMonaLisaWriter(0, "GridAliRoot-tag.C", 0, 0, "global");
+
+ TString fESDFileName = "alien://";
+ fESDFileName += turl;
+ fESDFileName += "/AliESDs.root";
+
+ TString fGUID = 0;
+ GetGUID(fGUID);
+
+ gEnv->Print();
+
+ TString fAliroot, fRoot, fGeant;
+ GetVersions(fAliroot,fRoot,fGeant);
+
+ TString fPeriod, fPass, fName;
+ GetProductionInfo(fPeriod, fPass, fName);
+
+ UpdateTag(fAliroot,fRoot,fGeant,fESDFileName,fGUID,fPeriod,fPass,fName);
+}
+
+//_____________________________________//
+GetProductionInfo(TString &fPeriod, TString &fPass, TString &fName) {
+ const char* turl = gSystem->Getenv("ALIEN_JDL_OUTPUTDIR");
+
+ TString fS = turl;
+ TObjArray *fDirs = fS.Tokenize("/");
+
+ for (int iter=0; iter<fDirs->GetEntries(); iter++) {
+ TString fDir = ((TObjString *) fDirs->At(iter))->String();
+
+ if (fDir.Contains("LHC")) fPeriod = fDir;
+ if (fDir.Contains("pass")) fPass = fDir;
+ }
+ fName = fPeriod+"."+fPass;
+}
+
+//_____________________________________//
+GetVersions(TString &fAliroot, TString &froot, TString &fgeant) {
+ const char* fver = gSystem->Getenv("ALIEN_JDL_PACKAGES");
+ TString fS = fver;
+ Int_t fFirst = fS.First("#");
+
+ while(fFirst != -1) {
+ Int_t fTotalLength = fS.Length();
+ TString tmp = fS;
+ TString fS1 = fS(0,fFirst);
+ tmp = fS(fFirst+2,fTotalLength);
+ fS = tmp;
+
+ if(fS1.Contains("Root")) fAliroot = fS1;
+ if(fS1.Contains("ROOT")) froot = fS1;
+ if(fS1.Contains("GEANT")) fgeant = fS1;
+
+ if(tmp.Contains("Root")) fAliroot = tmp;
+ if(tmp.Contains("ROOT")) froot = tmp;
+ if(tmp.Contains("GEANT")) fgeant = tmp;
+
+ fFirst = tmp.First("#");
+ }
+}
+
+//_____________________________________//
+GetGUID(TString &guid) {
+ ofstream myfile ("guid.txt");
+ if (myfile.is_open()) {
+ TFile *f = TFile::Open("AliESDs.root","read");
+ if(f && !f->IsZombie() && f->IsOpen()) {
+ guid = f->GetUUID().AsString();
+ myfile << "AliESDs.root \t"<<f->GetUUID().AsString();
+ cout<<guid.Data()<<endl;
+ myfile.close();
+ }
+ else cout<<"Input file not found"<<endl;
+ }
+ else cout<<"Output file can't be created..."<<endl;
+}
+
+
+//_____________________________________//
+Bool_t UpdateTag(TString faliroot, TString froot, TString fgeant,
+ TString turl, TString guid,
+ TString fperiod, TString fpass, TString fname) {
+ cout<<"> Updating tags...."<<endl;
+
+ const TString tagPattern = "tag.root";
+ // Open the working directory
+ TSystemDirectory dir(".", gSystem->pwd());
+ TIter next(dir.GetListOfFiles());
+ TSystemFile* file = 0;
+ // Add all files matching *pattern* to the chain
+ while ((file = static_cast<TSystemFile*>(next()))) {
+ TString name(file->GetName());
+ if (!name.Contains(tagPattern)) continue;
+
+ TFile* f = TFile::Open(name,"read") ;
+ AliRunTag* tag = 0x0;
+ AliFileTag* flTag = 0x0;
+ TTree* fTree = (TTree *)f->Get("T");
+ if (!fTree) {
+ f->Close();
+ continue;
+ }
+ fTree->SetBranchAddress("AliTAG",&tag);
+
+ //Defining new tag objects
+ AliRunTag* newTag = 0x0;
+ TTree ttag("T","A Tree with event tags");
+ TBranch* btag = ttag.Branch("AliTAG", &newTag);
+ btag->SetCompressionLevel(9);
+
+ Printf(">>>>> Found %d entries....",fTree->GetEntries());
+
+ for (Int_t iTagFiles = 0; iTagFiles < fTree->GetEntries(); iTagFiles++) {
+ fTree->GetEntry(0);
+ newTag = new AliRunTag(*tag);
+ newTag->SetAlirootVersion(faliroot);
+ newTag->SetRootVersion(froot);
+ newTag->SetGeant3Version(fgeant);
+ newTag->SetLHCPeriod(fperiod);
+ newTag->SetReconstructionPass(fpass);
+ newTag->SetProductionName(fname);
+ Printf("Found %d file tags",newTag->GetNFiles());
+ for(Int_t j = 0; j < newTag->GetNFiles(); j++) {
+ flTag = (AliFileTag *) newTag->GetFileTag(j);
+ flTag->SetTURL(turl);
+ flTag->SetGUID(guid);
+ }
+ ttag.Fill();
+
+ delete tag;
+ delete newTag;
+ }//tag file loop
+
+ TFile* ftag = TFile::Open(name, "recreate");
+ ftag->cd();
+ ttag.Write();
+ ftag->Close();
+ }//directory loop
+ return kTRUE;
+}
+
+//
+// EOF
+//
--- /dev/null
+#!/bin/bash
+version=5
+tag=
+id=
+run=
+stage=0
+upload=0
+jobs=2
+events=1
+gen=default
+aliroot="v5-04-Rev-20"
+root=""
+geant=""
+minmerge=30
+noact=0
+
+# --- Display help message -------------------------------------------
+usage()
+{
+ cat <<EOF
+Usage: $0 [OPTIONS]
+
+Options:
+ -h,--help This help
+ -t|--tag TAG Job tag [****] ($tag)
+ -i|--id NAME Name of production ($id)
+ -R|--run RUN_NO Run number ($run)
+ -e|--generator NAME Event generator ($gen)
+ -c|--copy Copy files to AliEn
+ -n|--jobs JOBS Set number of jobs[**] ($jobs)
+ -m|--events EVENTS Set events/job[**] ($events)
+ -s|--stage STAGE Set the stage[***] ($stage)
+ -o|--output DIR Set base output directory ($aout)
+ -d|--data DIR Set data directory ($adir)
+ -b|--bin DIR Set base bin directory ($abin)
+ -a|--aliroot RELEASE Set AliROOT release [*] ($aliroot)
+ -r|--root RELEASE Set ROOT release [*] ($root)
+ -g|--geant RELEASE Set GEANT3 release [*] ($geant)
+ -f|--final NUMBER Run final merging when down to this ($minmerge)
+
+[*] Only make sense with option -c
+[**] Only make sense for stage 0
+[***] If stage is set to 6, try to deduce the stage automatically
+[****] TAG is a short hand for specific id and run
+EOF
+}
+
+# --- Process a return value -----------------------------------------
+log_msg()
+{
+ local log=$1 ; shift
+ echo -en "$@\e[0m ... "
+ if test "x$log" != "x" ; then
+ echo "=== $@" >> $log
+ fi
+}
+# --- Make error -----------------------------------------------------
+log_err()
+{
+ local pre=$1
+ local post=$2
+ echo -e "\e[31;1mError\e[0m: ${pre} \e[35m${post}\e[0m" > /dev/stderr
+}
+
+# --- Process a return value -----------------------------------------
+log_end()
+{
+ local log=$1
+ local ret=$2
+ local ext=$3
+ local msg=""
+ local fmt=""
+ if test $ret -eq 0 ; then
+ msg="success"
+ fmt="32"
+ else
+ msg="failure"
+ fmt="31"
+ fi
+ echo -e "\e[${fmt}m${msg}${ext}\e[0m"
+ if test "x$log" != "x" ; then
+ echo "=== $msg$ext" >> $log
+ fi
+}
+
+# --- Copy a file to AliEn -------------------------------------------
+copy()
+{
+ local file=$1
+ local dest=$2
+ local del=$3
+ local base=`basename $file`
+
+ if test "x$del" != "x" ; then
+ log_msg cp.log "Removing \e[33malien:${dest}/${base}"
+ if test $noact -lt 1 ; then
+ alien_rm ${dest}/${base} >> cp.log 2>&1
+ fi
+ log_end cp.log $? " (ignore errors)"
+ fi
+
+ log_msg cp.log "Uploading \e[33m${file}\e[0m to \e[33m${dest}"
+ if test $noact -lt 1 ; then
+ alien_cp -n file:${file} alien:${dest}/${base} >> cp.log 2>&1
+ fi
+ log_end cp.log $?
+}
+
+# --- Run merging jpb ------------------------------------------------
+merge()
+{
+ local what=$1
+ local stage=$2
+ local dir=$3
+ local out=$4
+ local tag=$5
+ local run=$6
+ local tmpdir=`mktemp -d`
+
+ local top=${out}/${tag}/${run}
+ local bse=${what}_Stage_${stage}.xml
+ local xml=${tmpdir}/${bse}
+ local arc=${what}_archive.zip
+ local jdl=Merge.jdl
+ local ret=0
+
+ rm -f cp.log
+
+ log_msg cp.log "Creating XML file \e[33m${xml}"
+ if test $stage -eq 1 ; then
+ rm -f ${xml}
+ alien_find -x ${top}/${bse} ${top} */${arc} > ${xml} 2>>cp.log
+ ret=$?
+ else
+ let prev=$stage-1
+ rm -f ${xml}
+ alien_find -x ${top}/${bse} ${top}/${what}_Stage_${prev} */${arc} \
+ > ${xml} 2>>cp.log
+ ret=$?
+ fi
+ log_end cp.log $ret
+ if test $ret -ne 0 ; then
+ log_err "Make XML", "Failed to make XML collection $bse"
+ exit 1
+ fi
+ local n=`grep "<event name" ${xml} | wc -l 2>/dev/null`
+ if test $n -lt $minmerge ; then
+ old=$bse
+ stage=5
+ jdl=Final.jdl
+ bse=${what}_Stage_${stage}.xml
+ tmp=${tmpdir}/${bse}
+ sed "s,$old,$bse," < $xml > $tmp
+ xml=$tmp
+ fi
+ echo -e "\e[33m$n\e[0m input files for \e[32m${what} stage ${stage}\e[0m"
+
+ copy ${xml} ${top} del
+
+ log_msg "" "Submitting merging job \e[33m${jdl}"
+ if test $noact -lt 1 ; then
+ alien_submit alien:${dir}/${jdl} ${run} ${stage} ${tag} ${what}
+ fi
+ log_end "" $?
+}
+
+# --- Determine the next stage ---------------------------------------
+progress()
+{
+ local out=$1
+
+ log_msg "" "Deduce next stage for \e[33m$out"
+ # First, check for final merge result
+ # echo -e "\nCheck of ${out}/QA_merge_archive.zip"
+ alien_ls ${out}/QA_merge_archive.zip > /dev/null 2>&1
+ if test $? -eq 0 ; then
+ stage=6
+ else
+ # Then check for production data
+ # echo -e "\nCheck of ${out}/001"
+ alien_ls ${out}/001 > /dev/null 2>&1
+ ret=$?
+ # echo "ret=$ret"
+ if test $ret -ne 0 ; then
+ # echo "No output, stage 0 to be done"
+ stage=0
+ else
+ # Finally, check each merge stage
+ tmp=0
+ stage=0
+ for i in 4 3 2 1; do
+ # echo -e "\nCheck of ${out}/QA_Stage_${i}"
+ alien_ls ${out}/QA_Stage_${i} > /dev/null 2>&1
+ if test $? -ne 0 ; then
+ tmp=$i
+ else
+ break
+ fi
+ done
+ stage=$tmp
+ fi
+ fi
+ log_msg "" "\e[34;m$stage"
+ log_end "" 0
+}
+# --- Upload files ---------------------------------------------------
+push()
+{
+ local bin=$1
+ local data=$2
+ local out=$3
+ local tmpdir=`mktemp -d`
+
+ rm cp.log
+
+ jdls="Run.jdl Merge.jdl Final.jdl"
+ for i in $jdls ; do
+ log_msg "" "Creating \e[33m${i}"
+ sed -e "s|@out@|${out}|" \
+ -e "s|@data@|${data}|" \
+ -e "s|@bin@|${bin}|" \
+ -e "s|@aliroot@|${aliroot}|" \
+ -e "s|@root@|${root}|" \
+ -e "s|@geant@|${geant}|" \
+ < ${i}.in > ${tmpdir}/${i}
+ log_end "" $?
+ done
+
+ log_msg cp.log "Removing and re-creating \e[33m${data}"
+ if test $noact -lt 1 ; then
+ alien_rmdir ${data} >> cp.log 2>&1
+ alien_mkdir -p $data >> cp.log 2>&1
+ fi
+ log_end cp.log $?
+
+ local del=1
+ if test "X$bin" = "X$data" ; then del=0 ; fi
+ copy run.sh $bin $del
+ copy merge.sh $bin $del
+
+
+ files="simrun.sh \
+ GRP.C \
+ Simulate.C \
+ Config.C \
+ Reconstruct.C \
+ Check.C \
+ Tag.C \
+ QA.C \
+ QAConfig.C \
+ AOD.C \
+ AODConfig.C \
+ ${tmpdir}/Run.jdl \
+ ${tmpdir}/Merge.jdl \
+ ${tmpdir}/Final.jdl \
+ fmd_corrections.root"
+
+ for i in $files ; do
+ copy $i ${data}
+ done
+}
+
+# --- Get package versions -------------------------------------------
+getVersions()
+{
+ local ali=$1
+ local roo=$2
+ local gean=$3
+
+ log_msg "" "Checking software packages"
+ if test "x$ali" = "x" ; then
+ log_end "" 1
+ log_err "Check versions" "No AliROOT Release specified"
+ exit 1
+ fi
+ if test "x$roo" != "x" && test "x$gean" = "x" ; then
+ log_msg "" "\e[33mAliROOT=$ali ROOT=$roo GEANT=$gean"
+ log_end "" 0
+ return
+ fi
+
+ l=`wget -q http://alimonitor.cern.ch/packages/ -O - | \
+ sed -n -e '/<tr/,/<\/tr>/ p' | \
+ sed -n "/<a.*VO_ALICE@AliRoot::${aliroot}/,/VO_ALICE@ROOT::/ p" | \
+ sed -n -e 's/.*VO_ALICE@\(GEAN\|ROO\)T3*::\(v[-0-9a-zA-Z]*\).*/\L\1=\2/gp'|\
+ tr '\n' ' '`
+ eval $l
+ if test "X$roo" = "X" || test "X$gean" = "X" ; then
+ log_end "" 1
+ log_err "Check versions", "Failed to extract ROOT/GEANT3 versions"
+ exit 1
+ fi
+ root=$roo
+ geant=$gean
+ log_msg "" "\e[33mAliROOT=$ali ROOT=$root GEANT=$geant"
+ log_end "" 0
+}
+
+# --- Create an arcive for upload ------------------------------------
+archive()
+{
+ log_msg "" "Creating archive of files"
+ local name=sim_files${version}
+ mkdir -p ${name}
+ files="\
+ run.sh \
+ AOD.C \
+ Check.C \
+ Config.C \
+ doit.sh \
+ Final.jdl.in \
+ GRP.C \
+ Merge.jdl.in \
+ QA.C \
+ README.md \
+ Reconstruct.C \
+ Run.jdl.in \
+ simrun.sh \
+ Simulate.C \
+ Tag.C \
+ merge.sh \
+ fmd_corrections.root"
+
+ for i in $files ; do
+ cp $i ${name}/$i
+ done
+ tar -czf ${name}.tar.gz ${name}
+ ret=$?
+ rm -rf ${name}
+ log_end "" $ret
+}
+
+# --- Set some variables ---------------------------------------------
+auid=`alien_whoami | sed 's/^ *//'`
+ahome=/alice/cern.ch/user/`echo $auid | sed 's/^\(.\).*/\1/'`/$auid
+adir=${ahome}/mc
+abin=${ahome}/mc
+aout=${ahome}/test
+
+# --- Proces command line options ------------------------------------
+while test $# -gt 0 ; do
+ case $1 in
+ -h|--help) usage; exit 0;;
+ -t|--tag) tag=$2 ; shift ;;
+ -i|--id) id=$2 ; shift ;;
+ -R|--run) run=$2 ; shift ;;
+ -e|--generator) gen=$2 ; shift ;;
+ -c|--copy) upload=1 ;;
+ -n|--jobs) jobs=$2 ; shift ;;
+ -m|--events) events=$2 ; shift ;;
+ -s|--stage) stage=$2 ; shift ;;
+ -b|--bin) abin=$2 ; shift ;;
+ -o|--output) aout=$2 ; shift ;;
+ -d|--data) adir=$2 ; shift ;;
+ -a|--aliroot) aliroot=$2 ; shift ;;
+ -r|--root) root=$2 ; shift ;;
+ -g|--geant) geant=$2 ; shift ;;
+ -f|--final) minmerge=$2 ; shift ;;
+ -A|--archive) archive ; exit 0 ;;
+ -x|--dry-run) noact=1 ;;
+ *) log_err "Unknown option" "$1" ; exit 1 ;;
+ esac
+ shift
+done
+abin=$adir
+
+
+
+# --- May upload only ------------------------------------------------
+if test $upload -gt 0 ; then
+ getVersions "$aliroot" "$root" "$geant"
+ push ${abin} ${adir} ${aout}
+ if test $stage -lt 0 ; then
+ exit 0
+ fi
+fi
+
+# --- Inspect options ------------------------------------------------
+case $tag in
+ pp) id=$tag ; run=118506 ;;
+ PbPb) id=$tag ; run=138190 ;;
+ pPb) id=$tag ; run=195483 ;;
+ Pbp) id=$tag ; run=196433 ;;
+esac
+if test "x$id" = "x" ; then
+ log_err "" "No job identifier given"
+ log_end "" 1
+ exit 1
+fi
+if test "x$run" = "x" ; then
+ log_err "" "No run number given"
+ log_end "" 1
+ exit 1
+fi
+case $stage in
+ 0|1|2|3|4|5) : ;;
+ 6) progress $aout/$id/$run ;;
+ *) log_err "Invalid stage" "$stage" ; exit 1 ;;
+esac
+if test $stage -ge 6 ; then
+ log_msg "" "All done"
+ log_end "" 0
+ exit 0
+fi
+
+# --- Either run the job or merge ------------------------------------
+if test $stage -le 0 ; then
+ log_msg "" "Removing old ${aout}/${id}/${run}"
+ ret=0
+ if test $noact -lt 1 ; then
+ alien_rmdir ${aout}/${id}/${run} > /dev/null 2>&1
+ ret=$?
+ fi
+ log_end "" $ret
+
+ log_msg "" "Submitting \e[33mRun.jdl\e[0m for \e[34m$id run\e[0m (\e[34m$jobs\e[0m jobs w/\e[34m$events)"
+ if test $noact -lt 1 ; then
+ alien_submit alien:${adir}/Run.jdl ${run} ${jobs} ${events} ${id} ${gen}
+ ret=$?
+ fi
+ log_end "" $ret
+ exit $ret
+fi
+
+merge QA ${stage} ${adir} ${aout} ${id} ${run}
+
+#
+# EOF
+#
+
+
+
--- /dev/null
+#!/bin/bash
+
+export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH
+cat <<EOF
+=========================================
+PATH=$PATH
+LD_LIBRARY_PATH=$LD_LIBRARY_PATH
+ROOTSYS=$ROOTSYS
+`which root`
+ALICE_ROOT=$ALICE_ROOT
+`which aliroot`
+`ulimit -a`
+`free -m`
+=========================================
+EOF
+
+which=$1
+run=$2
+dir=$3
+stage=$4
+counter=$5
+
+cat <<EOF
+Merge $which Stage $stage sub-job $counter
+ Directory: $dir
+ Run: $run
+EOF
+
+if test ! -f ${which}.C ; then
+ echo "No ${which}.C found in current directory" \
+ > validation_error.message
+ exit 1
+fi
+ARG="${which}.C($run,\"$dir\",$stage)"
+time aliroot -b -q -x $ARG
+exitcode=$?
+
+echo "======== $ARG finished with exit code: $exitcode ========"
+echo "############## memory after: ##############"
+free -m
+if [ $exitcode -ne 0 ]; then
+ echo "$ARG exited with code $exitcode" > validation_error.message
+fi
+
+exit $exitcode
+#
+# EOF
+#
--- /dev/null
+#!/bin/bash
+free
+echo _____________________________________________
+echo "HOME IS $HOME"
+ls $HOME
+length=`echo $HOME |wc -c`
+if (( $length >= 100 )) ;
+then
+ echo "WARNING: The home directory $HOME is longer than 100 char"
+ OLDHOME=$HOME
+ NEWHOME="/tmp/alien_home_dir.${ALIEN_PROC_ID}"
+ echo "CHANGING HOME TO $NEWHOME"
+ ln -s "$HOME" "$NEWHOME"
+ export HOME=$NEWHOME
+fi
+echo _____________________________________________
+
+export PRODUCTION_METADATA="$ALIEN_JDL_LPMMETADATA"
+
+if test -f simrun.sh ; then
+ chmod 755 simrun.sh
+ ./simrun.sh $@
+ ret=$?
+elif test -f Run.sh ; then
+ chmod 755 Run.sh
+ ./Run.sh $@
+ ret=$?
+elif test -f run.sh ; then
+ chmod 755 Run.sh
+ ./Run.sh $@
+ ret=$?
+else
+ echo "Nothing to run in this directory!"
+ exit 1
+fi
+if test $ret -ne 0 ; then
+ echo "Job failed with exit status $ret"
+ exit $ret
+fi
+
+exit 0
+#
+# EOF
+#
+
+
--- /dev/null
+#!/bin/bash
+
+# set job and simulation variables as :
+# ./Run.sh --run <x>
+
+#
+# Function to run a command and check return code
+function runcommand()
+{
+ echo -e "\n"
+ echo -e "\n" >&2
+
+ local type=$1
+ local scr=$2
+ local log=$3
+
+ echo "* $type : $scr"
+ echo "* $type : $scr" >&2
+
+ time aliroot -b -q -x $scr 2> /dev/stdout | tee -a $log
+ local ext=$?
+ local exp=${5-0}
+
+ if test -f syswatch.log ; then
+ mv syswatch.log `basename $log .log`watch.log
+ fi
+
+ if [ "$ext" -ne "$exp" ]; then
+ echo "*! $scr failed with exitcode $ext, expecting $exp"
+ echo "*! $scr failed with exitcode $ext, expecting $exp" >&2
+ echo "$scr failed with exitcode $ext, expecting $exp" \
+ > validation_error.message
+ exit ${4-$ext}
+ else
+ echo "* $scr finished with the expected exit code ($exp), moving on"
+ echo "* $scr finished with the expected exit code ($exp), moving on" >&2
+ fi
+}
+
+#
+# Function to clean up rec-points
+function cleanRecPoints()
+{
+ local alsoITS=${1-1}
+ if test $alsoITS -gt 0 ; then
+ rm -f *.RecPoints.root
+ return;
+ fi
+ for i in *.RecPoints.root ; do
+ if test ! -f $i ; then continue ; fi
+ case $i in
+ ITS*) ;;
+ *) rm -f $i ;;
+ esac
+ done
+}
+
+# Define the pt hard bin arrays
+pthardbin_loweredges=( 0 5 11 21 36 57 84 117 152 191 234 )
+pthardbin_higheredges=( 5 11 21 36 57 84 117 152 191 234 -1)
+
+CONFIG_SEED=""
+CONFIG_RUN_TYPE=""
+CONFIG_BMIN=""
+CONFIG_BMAX=""
+CONFIG_QUENCHING=""
+DC_RUN=""
+DC_EVENT="1"
+number=0
+runAODTrain=0
+runQATrain=0
+
+while test "x$1" != "x"; do
+ option="$1"
+ shift
+
+ case $option in
+ --run) DC_RUN="$1"; shift ;;
+ --event) DC_EVENT="$1"; shift ;;
+ --process) CONFIG_RUN_TYPE="$1"; shift ;;
+ --field) : ; shift ;; # No-op
+ --energy) : ; shift ;; # No-op
+ --physicslist) : ; shift ;; # No-op
+ --bmin) CONFIG_BMIN="$1"; shift ;;
+ --bmax) CONFIG_BMAX="$1"; shift ;;
+ --pthardbin) : ; shift ;; # No-op
+ --quench) CONFIG_QUENCHING="$1"; shift ;;
+ --sdd) : ;; # No-op
+ --number) number="$1"; shift ;;
+ --qa) runQATrain=1 ;;
+ --aod) runAODTrain=1 ;;
+ *) echo "Unkown option: $option" >&2
+ esac
+done
+
+CONFIG_SEED=$((ALIEN_PROC_ID%1000000000))
+
+if [ "$CONFIG_SEED" -eq 0 ]; then
+ CONFIG_SEED=$(((DC_RUN*100000+DC_EVENT)%1000000000))
+ echo "* MC Seed is $CONFIG_SEED (based on run / counter : $DC_RUN / $DC_EVENT)"
+else
+ echo "* MC Seed is $CONFIG_SEED (based on AliEn job ID)"
+fi
+
+if [ "$CONFIG_SEED" -eq 0 ]; then
+ echo "*! WARNING! Seeding variable for MC is 0 !" >&2
+fi
+
+mkdir -p input
+test -f galice.root && mv galice.root ./input/galice.root
+test -f Kinematics && mv Kinematics.root ./input/Kinematics.root
+ls input
+
+export CONFIG_SEED \
+ CONFIG_RUN_TYPE \
+ CONFIG_BMIN \
+ CONFIG_BMAX \
+ CONFIG_QUENCHING \
+ DC_RUN \
+ DC_EVENT
+
+export ALIMDC_RAWDB1="./mdc1"
+export ALIMDC_RAWDB2="./mdc2"
+export ALIMDC_TAGDB="./mdc1/tag"
+export ALIMDC_RUNDB="./mdc1/meta"
+
+if [ -f "$G4INSTALL/bin/geant4.sh" ]; then
+ echo "* Sourcing G4 environment from $G4INSTALL/bin/geant4.sh"
+ source $G4INSTALL/bin/geant4.sh
+fi
+
+cat <<EOF
+
+SIMRUN: Setup
+ Seed: $CONFIG_SEED
+ Run: $DC_RUN
+ Events: $DC_EVENT
+ Event generator: $CONFIG_RUN_TYPE
+ Serial #: $number
+ Impact parameter: ${CONFIG_BMIN}-${CONFIG_BMAX}
+ Quenching: $CONFIG_QUENCHING
+ Run QA: $runQATrain
+ Run AOD $runAODTrain
+
+Content of current directory:
+EOF
+ls -l
+
+echo "SIMRUN: Now read to process"
+
+runcommand "SIMULATION" "Simulate.C($DC_EVENT,$DC_RUN)" sim.log 5
+runcommand "RECONSTRUCTION" "Reconstruct.C($DC_RUN)" rec.log 10
+runcommand "TAG" "Tag.C" tag.log 50
+runcommand "CHECK" "Check.C" check.log 60
+if test $runQATrain -gt 0 ; then
+ runcommand "QA" "QA.C($DC_RUN)" qa.log 100
+fi
+if test $runAODTrain -gt 0 ; then
+ runcommand "AOD" "AOD.C($DC_RUN)" aod.log 100
+fi
+
+rm -f *.Hits.root *.Digits.root *.SDigits.root
+cleanRecPoints 0
+
+exit 0
+#
+# EOF
+#
+
--- /dev/null
+#!/bin/bash
+# --- Check AliEn token ----------------------------------------------
+uid=`id -u`
+genv_file=/tmp/gclient_env_${uid}
+
+if test ! -f ${genv_file} ; then
+ echo "No such file: ${genv_file}, please do alien-token-init" \
+ >/dev/stderr
+ exit 1
+fi
+. ${genv_file}
+alien-token-info | grep -q "Token is still valid"
+if test $? -ne 0 ; then
+ echo "Token not valid, please re-new" > /dev/stderr
+ exit 1
+fi
+
+run=118506
+nev=1
+if test x$1 != x ; then run=$1 ; fi
+files="AOD.C \
+ AODConfig.C \
+ Check.C \
+ Config.C \
+ GRP.C \
+ QA.C \
+ QAConfig.C \
+ Reconstruct.C \
+ Simulate.C \
+ Tag.C \
+ simrun.sh \
+ $ALICE_ROOT/OADB/PWGLF/FORWARD/CORRECTIONS/data/fmd_corrections.root"
+
+rm -rf test
+mkdir -p test
+for i in $files ; do
+ cp -v $i test/`basename $i`
+done
+
+(cd test && ../run.sh --run $run --event $nev --qa --aod $@)