From 98c73a16cc3cf99da012efa450af5feca7377976 Mon Sep 17 00:00:00 2001 From: Frederic Julian Linz <f.linz@gsi.de> Date: Tue, 7 Feb 2023 11:04:10 +0000 Subject: [PATCH] Introduction of full config.json sim chain including shell scripts New folder created: macro/PWG/common/production. All files related to config.json chain moved there. run_reco_config_json.C and run_analysis_tree_maker_json_config.C added. run_json.sh and run_sim_json.sh added. Full chain currently runs during CI. --- macro/CMakeLists.txt | 14 + macro/PWG/CMakeLists.txt | 1 + macro/PWG/common/CMakeLists.txt | 1 + macro/PWG/common/production/CMakeLists.txt | 22 + macro/PWG/common/production/config.json | 168 +++++ macro/PWG/common/production/config_ci.json.in | 168 +++++ .../run_analysis_tree_maker_json_config.C | 214 +++++++ .../common/production}/run_digi_json_config.C | 0 macro/PWG/common/production/run_json.sh | 88 +++ .../common/production/run_reco_json_config.C | 573 ++++++++++++++++++ .../common/production/run_sim_reco_json.sh | 80 +++ .../production}/run_transport_json_config.C | 0 macro/run/CMakeLists.txt | 32 +- macro/run/config.json | 117 ---- macro/run/config_ci.json | 117 ---- macro/run/run_tests.sh | 16 - 16 files changed, 1330 insertions(+), 281 deletions(-) create mode 100644 macro/PWG/CMakeLists.txt create mode 100644 macro/PWG/common/CMakeLists.txt create mode 100644 macro/PWG/common/production/CMakeLists.txt create mode 100644 macro/PWG/common/production/config.json create mode 100644 macro/PWG/common/production/config_ci.json.in create mode 100644 macro/PWG/common/production/run_analysis_tree_maker_json_config.C rename macro/{run => PWG/common/production}/run_digi_json_config.C (100%) create mode 100755 macro/PWG/common/production/run_json.sh create mode 100644 macro/PWG/common/production/run_reco_json_config.C create mode 100755 macro/PWG/common/production/run_sim_reco_json.sh rename macro/{run => PWG/common/production}/run_transport_json_config.C (100%) delete mode 100644 macro/run/config.json delete mode 100644 macro/run/config_ci.json diff --git a/macro/CMakeLists.txt b/macro/CMakeLists.txt index 393fc63212..7dc5a22d58 100644 --- a/macro/CMakeLists.txt +++ b/macro/CMakeLists.txt @@ -14,9 +14,12 @@ If(NOT ${CBM_TEST_MODEL} MATCHES Experimental) Message("Additional Nightly tests") EndIf() + add_subdirectory(PWG) + #--- Additional tests for weekly builds If(${CBM_TEST_MODEL} MATCHES Weekly) add_subdirectory(KF) + add_subdirectory(PWG) Message("Additional long running Weekly tests") EndIf() @@ -35,6 +38,17 @@ Install(FILES ${CBMROOT_SOURCE_DIR}/scripts/loadlib.C DESTINATION share/cbmroot/macro/ ) +Install(FILES ${CBMROOT_SOURCE_DIR}/macro/PWG/common/production/run_json.sh + ${CBMROOT_SOURCE_DIR}/macro/PWG/common/production/run_sim_reco_json.sh + ${CBMROOT_SOURCE_DIR}/macro/PWG/common/production/run_transport_json_config.C + ${CBMROOT_SOURCE_DIR}/macro/PWG/common/production/run_digi_json_config.C + ${CBMROOT_SOURCE_DIR}/macro/PWG/common/production/run_reco_json_config.C + ${CBMROOT_SOURCE_DIR}/macro/PWG/common/production/run_analysis_tree_maker_json_config.C + ${CBMROOT_SOURCE_DIR}/macro/PWG/common/production/config.json + DESTINATION share/cbmroot/macro/PWG/common/production + ) +Install(CODE "FILE(MAKE_DIRECTORY ${CMAKE_INSTALL_PREFIX}/share/cbmroot/macro/PWG/common/production)") + Install(FILES KF/DecayConfig.C KF/registerGeantDecays.C KF/registerLightIons.C KF/registerPythiaDecays.C KF/kf_kfparticle.C KF/kf_thermal_signal_generator.C KF/kf_transport.C DESTINATION share/cbmroot/macro/KF diff --git a/macro/PWG/CMakeLists.txt b/macro/PWG/CMakeLists.txt new file mode 100644 index 0000000000..e4717b2d67 --- /dev/null +++ b/macro/PWG/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory(common) diff --git a/macro/PWG/common/CMakeLists.txt b/macro/PWG/common/CMakeLists.txt new file mode 100644 index 0000000000..c29593f4a2 --- /dev/null +++ b/macro/PWG/common/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory(production) diff --git a/macro/PWG/common/production/CMakeLists.txt b/macro/PWG/common/production/CMakeLists.txt new file mode 100644 index 0000000000..8fd67b7d7c --- /dev/null +++ b/macro/PWG/common/production/CMakeLists.txt @@ -0,0 +1,22 @@ +# Check if Python is installed and excute test only if python is available + +find_package(Python) + +if (Python_FOUND) + set(production_macro_events 2) + + GENERATE_TEST_SCRIPT(${CBMROOT_SOURCE_DIR}/macro/PWG/common/production/run_json.sh) + + # copy the configuration to the build directory and replace variables + configure_file(${CBMROOT_SOURCE_DIR}/macro/PWG/common/production/config_ci.json.in + ${CBMROOT_BINARY_DIR}/macro/PWG/common/production/config_ci.json + @ONLY + ) + + File(COPY ${CBMROOT_SOURCE_DIR}/macro/include/.rootrc DESTINATION ${CBMROOT_BINARY_DIR}/macro/PWG/common/production) + + Set(testname PWG_common_production_run_json) + + Add_Test(${testname} ${CMAKE_CURRENT_BINARY_DIR}/run_json.sh ${CMAKE_CURRENT_BINARY_DIR}/config_ci.json) + Set_Tests_Properties(${testname} PROPERTIES TIMEOUT 600) +endif() diff --git a/macro/PWG/common/production/config.json b/macro/PWG/common/production/config.json new file mode 100644 index 0000000000..ef68c3b44b --- /dev/null +++ b/macro/PWG/common/production/config.json @@ -0,0 +1,168 @@ +{ + "accessory": { + "batch": true, + "nEvents": 10, + "jobName": "cbmsim", + "jobRange": "1-10", + "account": "cbm", + "ram": "4G", + "partition": "main", + "time": "3:00:00", + "excludeNodes": "", + "logDir": "/lustre/cbm/users/${USER}/mc/out/log", + "cbmRoot": "/lustre/cbm/users/fkornas/soft/cbmroot/MR_master22_fr_v18.6.7_fs_apr21p2/bin/CbmRootConfig.sh", + "jobScript": "${PWD}/run_sim_reco.sh", + "transport": { + "run": true, + "plutoShift": 0, + "macro": "${VMCWORKDIR}/macro/PWG/common/production/run_transport_json_config.C"}, + "digitization": { + "run": true, + "macro": "${VMCWORKDIR}/macro/PWG/common/production/run_digi_json_config.C"}, + "reconstruction": { + "run": true, + "macro": "${VMCWORKDIR}/macro/PWG/common/production/run_reco_json_config.C"}, + "AT": { + "run": true, + "macro": "${VMCWORKDIR}/macro/PWG/common/production/run_analysis_tree_maker_json_config.C"} + }, + "logScreenLevel": "INFO", + "logVerbosityLevel": "LOW", + "transport": { + "input": [ + {"generator": "unigen", + "file": "/lustre/cbm/users/ogolosov/mc/generators/dcmqgsm_smm/auau/pbeam12agev/mbias/root/dcmqgsm_${taskId}.root"}, + {"generator": "pluto", + "file": "/lustre/cbm/users/ogolosov/mc/generators/pluto/auau/pbeam12agev/w/w.zip#w_${plutoFileId}.root", + "plutoPdg": 0}, + {"#generator": "beam", + "beamA": 197, + "beamZ": 79, + "beamQ": 79, + "beamP": 12.0, + "beamStartZ": -45.0} + ], + "output": { + "path": "/lustre/cbm/users/${USER}/mc/out/tra/${taskId}/${taskId}", + "overwrite": false + }, + "target": { + "material": "Gold", + "thickness": 0.025, + "diameter": 2.5, + "position": { + "x": 0.0, + "y": 0.0, + "z": -44.0 + }, + "rotation.y": 0.0 + }, + "beam": { + "position": { + "x": 0.0, + "y": 0.0, + "zFocus": -44.0, + "sigmaX": 0.1, + "sigmaY": 0.1 + }, + "angle": { + "x": 0.0, + "y": 0.0, + "sigmaX": 0.001, + "sigmaY": 0.001 + } + }, + "randomRP": true, + "geantVersion": 4, + "geant4vmcSettings": { + "physicsLists": "QGSP_BERT_EMV+optical", + "specialProcesses": "stepLimiter", + "maxNsteps": 10000000, + "geant4commands": [""] + }, + "geometry": { + "baseSetup": "sis100_electron", + "#magneticField": { + "tag": "v18a", + "scale": 1.0, + "position": { + "x": 0.0, + "y": 0.0, + "z": 40.0 + } + }, + "subsystems": { + "magnet": "v21a", + "pipe": "v21d", + "mvd": "v20d_tr", + "sts": "v21e", + "rich": "v21a", + "trd": "v20b_1e", + "tof": "v21a_1e", + "psd": "v22a", + "platform": "v22b" + } + }, + "stackFilter": { + "storeAllPrimaries": true, + "storeAllMothers": true, + "storeAllDecays": true + } + }, + + "digitization": { + "generateRunInfo": false, + "eventMode": false, + "timeSliceLength": 1e5, + "storeAllTimeSlices": false, + "startTime": 1000, + "produceNoise": false, + "input": [ + {"id": 0, + "path": "/lustre/cbm/users/${USER}/mc/out/tra/${taskId}/${taskId}", + "rate": "1.e3", + "treeAccessMode": "regular", + "parameterSource": false}, + {"id": -1, + "path": "test_emb", + "embedToId": 0, + "treeAccessMode": "regular"}, + {"id": -1, + "path": "test_beam", + "rate": "1.e9", + "treeAccessMode": "random"} + ], + "output": { + "path": "/lustre/cbm/users/${USER}/mc/out/raw/${taskId}/${taskId}", + "overwrite": false + }, + "geometry": { + "deactivate": ["", ""], + "#deactivateAllBut": "" + } + }, + + "reconstruction": { + "rawFile": "/lustre/cbm/users/${USER}/mc/out/raw/${taskId}/${taskId}", + "nTimeSlices": -1, + "firstTimeSlice": 0, + "output": { + "path": "/lustre/cbm/users/${USER}/mc/out/reco/${taskId}/${taskId}", + "overwrite": false + }, + "sEvBuildRaw": "Ideal", + "traFile": "/lustre/cbm/users/${USER}/mc/out/tra/${taskId}/${taskId}", + "isL1Matching": true, + "isL1EffQA": false + }, + + "AT": { + "traFile": "/lustre/cbm/users/${USER}/mc/out/tra/${taskId}/${taskId}", + "rawFile": "/lustre/cbm/users/${USER}/mc/out/raw/${taskId}/${taskId}", + "recFile": "/lustre/cbm/users/${USER}/mc/out/reco/${taskId}/${taskId}", + "unigenFile": "/lustre/cbm/users/ogolosov/mc/generators/dcmqgsm_smm/auau/pbeam12agev/mbias/root/dcmqgsm_${taskId}.root", + "output": { + "path": "/lustre/cbm/users/${USER}/mc/out/AT/${taskId}/${taskId}", + "overwrite": false} + } +} diff --git a/macro/PWG/common/production/config_ci.json.in b/macro/PWG/common/production/config_ci.json.in new file mode 100644 index 0000000000..4dcb3faaac --- /dev/null +++ b/macro/PWG/common/production/config_ci.json.in @@ -0,0 +1,168 @@ +{ + "accessory": { + "batch": false, + "nEvents": "@production_macro_events@", + "jobName": "cbmsim", + "jobRange": "1", + "account": "cbm", + "ram": "4G", + "partition": "debug", + "time": "0:20:00", + "excludeNodes": "", + "logDir": "@CMAKE_BINARY_DIR@/macro/PWG/common/production/data/log", + "cbmRoot": "@CMAKE_BINARY_DIR@/config.sh", + "jobScript": "@VMCWORKDIR@/macro/PWG/common/production/run_sim_reco_json.sh", + "transport": { + "run": true, + "plutoShift": 0, + "macro": "@VMCWORKDIR@/macro/PWG/common/production/run_transport_json_config.C"}, + "digitization": { + "run": true, + "macro": "@VMCWORKDIR@/macro/PWG/common/production/run_digi_json_config.C"}, + "reconstruction": { + "run": true, + "macro": "@VMCWORKDIR@/macro/PWG/common/production/run_reco_json_config.C"}, + "AT": { + "run": true, + "macro": "@VMCWORKDIR@/macro/PWG/common/production/run_analysis_tree_maker_json_config.C"} + }, + "logScreenLevel": "INFO", + "logVerbosityLevel": "LOW", + "transport": { + "input": [ + {"generator": "unigen", + "file": "@VMCWORKDIR@/input/urqmd.auau.10gev.centr.root"}, + {"generator": "pluto", + "file": "@VMCWORKDIR@/input/pluto.auau.8gev.omega.mpmm.0001.root", + "plutoPdg": 0}, + {"#generator": "beam", + "beamA": 197, + "beamZ": 79, + "beamQ": 79, + "beamP": 12.0, + "beamStartZ": -45.0} + ], + "output": { + "path": "@CMAKE_BINARY_DIR@/macro/PWG/common/production/data/tra/${taskId}/${taskId}", + "overwrite": true + }, + "target": { + "material": "Gold", + "thickness": 0.025, + "diameter": 2.5, + "position": { + "x": 0.0, + "y": 0.0, + "z": -44.0 + }, + "rotation.y": 0.0 + }, + "beam": { + "position": { + "x": 0.0, + "y": 0.0, + "zFocus": -44.0, + "sigmaX": 0.1, + "sigmaY": 0.1 + }, + "angle": { + "x": 0.0, + "y": 0.0, + "sigmaX": 0.001, + "sigmaY": 0.001 + } + }, + "randomRP": true, + "geantVersion": 4, + "geant4vmcSettings": { + "physicsLists": "QGSP_BERT_EMV+optical", + "specialProcesses": "stepLimiter", + "maxNsteps": 10000000, + "geant4commands": [""] + }, + "geometry": { + "baseSetup": "sis100_electron", + "#magneticField": { + "tag": "v18a", + "scale": 1.0, + "position": { + "x": 0.0, + "y": 0.0, + "z": 40.0 + } + }, + "subsystems": { + "magnet": "v21a", + "pipe": "v21d", + "mvd": "v20d_tr", + "sts": "v21e", + "rich": "v21a", + "trd": "v20b_1e", + "tof": "v21a_1e", + "psd": "v22a", + "platform": "v22b" + } + }, + "stackFilter": { + "storeAllPrimaries": true, + "storeAllMothers": true, + "storeAllDecays": true + } + }, + + "digitization": { + "generateRunInfo": false, + "eventMode": false, + "timeSliceLength": 1e5, + "storeAllTimeSlices": false, + "startTime": 1000, + "produceNoise": false, + "input": [ + {"id": 0, + "path": "@CMAKE_BINARY_DIR@/macro/PWG/common/production/data/tra/${taskId}/${taskId}", + "rate": "1.e7", + "treeAccessMode": "regular", + "parameterSource": false}, + {"id": -1, + "path": "test_emb", + "embedToId": 0, + "treeAccessMode": "regular"}, + {"id": -1, + "path": "test_beam", + "rate": "1.e9", + "treeAccessMode": "random"} + ], + "output": { + "path": "@CMAKE_BINARY_DIR@/macro/PWG/common/production/data/raw/${taskId}/${taskId}", + "overwrite": true + }, + "geometry": { + "deactivate": ["", ""], + "#deactivateAllBut": "" + } + }, + + "reconstruction": { + "rawFile": "@CMAKE_BINARY_DIR@/macro/PWG/common/production/data/raw/${taskId}/${taskId}", + "nTimeSlices": -1, + "firstTimeSlice": 0, + "output": { + "path": "@CMAKE_BINARY_DIR@/macro/PWG/common/production/data/reco/${taskId}/${taskId}", + "overwrite": true + }, + "sEvBuildRaw": "Ideal", + "traFile": "@CMAKE_BINARY_DIR@/macro/PWG/common/production/data/tra/${taskId}/${taskId}", + "isL1Matching": true, + "isL1EffQA": true + }, + + "AT": { + "traFile": "@CMAKE_BINARY_DIR@/macro/PWG/common/production/data/tra/${taskId}/${taskId}", + "rawFile": "@CMAKE_BINARY_DIR@/macro/PWG/common/production/data/raw/${taskId}/${taskId}", + "recFile": "@CMAKE_BINARY_DIR@/macro/PWG/common/production/data/reco/${taskId}/${taskId}", + "unigenFile": "@VMCWORKDIR@/input/urqmd.auau.10gev.centr.root", + "output": { + "path": "@CMAKE_BINARY_DIR@/macro/PWG/common/production/data/AT/${taskId}/${taskId}", + "overwrite": true} + } +} diff --git a/macro/PWG/common/production/run_analysis_tree_maker_json_config.C b/macro/PWG/common/production/run_analysis_tree_maker_json_config.C new file mode 100644 index 0000000000..6a5261c05c --- /dev/null +++ b/macro/PWG/common/production/run_analysis_tree_maker_json_config.C @@ -0,0 +1,214 @@ +/* Copyright (C) 2023 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt + SPDX-License-Identifier: GPL-3.0-only + Authors: Viktor Klochkov, Frederic Linz [committer] */ + +// ----- Check output file name ------------------------------------------- +bool CheckOutFileName(TString fileName, Bool_t overwrite) +{ + string fName = "run_reco_json_config"; + // --- Protect against overwriting an existing file + if ((!gSystem->AccessPathName(fileName.Data())) && (!overwrite)) { + cout << fName << ": output file " << fileName << " already exists!"; + return false; + } + + // --- If the directory does not yet exist, create it + const char* directory = gSystem->DirName(fileName.Data()); + if (gSystem->AccessPathName(directory)) { + Int_t success = gSystem->mkdir(directory, kTRUE); + if (success == -1) { + cout << fName << ": output directory " << directory << " does not exist and cannot be created!"; + return false; + } + else + cout << fName << ": created directory " << directory; + } + return true; +} + +void run_analysis_tree_maker_json_config(TString traPath = "test", TString rawPath = "", TString recPath = "", + TString unigenFile = "", TString outPath = "", bool overwrite = true, + std::string config = "", int nEvents = 0) +{ + const std::string system = "Au+Au"; // TODO can we read it automatically? + const float beam_mom = 12.; + const bool is_event_base = false; + + // --- Logger settings ---------------------------------------------------- + const TString logLevel = "INFO"; + const TString logVerbosity = "LOW"; + // ------------------------------------------------------------------------ + + // ----- Environment -------------------------------------------------- + const TString myName = "run_analysis_tree_maker"; + const TString srcDir = gSystem->Getenv("VMCWORKDIR"); // top source directory + // ------------------------------------------------------------------------ + + // ----- In- and output file names ------------------------------------ + if (rawPath == "") rawPath = traPath; + if (recPath == "") recPath = traPath; + if (outPath == "") outPath = traPath; + TString traFile = traPath + ".tra.root"; + TString geoFile = traPath + ".geo.root"; + TString rawFile = rawPath + ".raw.root"; + TString recFile = recPath + ".reco.root"; + TString parFile = rawPath + ".par.root"; + TString outFile = outPath + ".analysistree.root"; + // ------------------------------------------------------------------------ + + // ----- Remove old CTest runtime dependency file ---------------------- + const TString dataDir = gSystem->DirName(outPath); + const TString dataName = gSystem->BaseName(outPath); + const TString testName = ("run_treemaker"); + // ------------------------------------------------------------------------ + + // ----- Load the geometry setup ------------------------------------- + CbmSetup* setup = CbmSetup::Instance(); + if (config == "") config = Form("%s/macro/run/config.json", gSystem->Getenv("VMCWORKDIR")); + boost::property_tree::ptree pt; + CbmTransportConfig::LoadFromFile(config, pt); + CbmTransportConfig::SetGeometry(setup, pt.get_child(CbmTransportConfig::GetModuleTag())); + // ------------------------------------------------------------------------ + + // ----- Timer -------------------------------------------------------- + TStopwatch timer; + timer.Start(); + // ------------------------------------------------------------------------ + + TString geoTag; + auto* parFileList = new TList(); + + if (!CheckOutFileName(outFile, overwrite)) return; + std::cout << "-I- " << myName << ": Using raw file " << rawFile << std::endl; + std::cout << "-I- " << myName << ": Using parameter file " << parFile << std::endl; + std::cout << "-I- " << myName << ": Using reco file " << recFile << std::endl; + if (unigenFile.Length() > 0) std::cout << "-I- " << myName << ": Using unigen file " << unigenFile << std::endl; + + // ----- Reconstruction run ------------------------------------------- + auto* run = new FairRunAna(); + auto* inputSource = new FairFileSource(recFile); + inputSource->AddFriend(traFile); + inputSource->AddFriend(rawFile); + run->SetSource(inputSource); + run->SetOutputFile(outFile); + run->SetGenerateRunInfo(kTRUE); + // ------------------------------------------------------------------------ + + // ----- Mc Data Manager ------------------------------------------------ + auto* mcManager = new CbmMCDataManager("MCManager", is_event_base); + mcManager->AddFile(traFile); + run->AddTask(mcManager); + // ------------------------------------------------------------------------ + + // --- STS track matching ---------------------------------------------- + // auto* matchTask = new CbmMatchRecoToMC(); + // run->AddTask(matchTask); + // ------------------------------------------------------------------------ + + run->AddTask(new CbmTrackingDetectorInterfaceInit()); + + auto* KF = new CbmKF(); + run->AddTask(KF); + // needed for tracks extrapolation + auto* l1 = new CbmL1("CbmL1", 1, 3); + if (setup->IsActive(ECbmModuleId::kMvd)) { + setup->GetGeoTag(ECbmModuleId::kMvd, geoTag); + const TString mvdMatBudgetFileName = srcDir + "/parameters/mvd/mvd_matbudget_" + geoTag + ".root"; + l1->SetMvdMaterialBudgetFileName(mvdMatBudgetFileName.Data()); + } + if (setup->IsActive(ECbmModuleId::kSts)) { + setup->GetGeoTag(ECbmModuleId::kSts, geoTag); + const TString stsMatBudgetFileName = srcDir + "/parameters/sts/sts_matbudget_" + geoTag + ".root"; + l1->SetStsMaterialBudgetFileName(stsMatBudgetFileName.Data()); + } + run->AddTask(l1); + + // --- TRD pid tasks + if (setup->IsActive(ECbmModuleId::kTrd)) { + CbmTrdSetTracksPidLike* trdLI = new CbmTrdSetTracksPidLike("TRDLikelihood", "TRDLikelihood"); + trdLI->SetUseMCInfo(kTRUE); + trdLI->SetUseMomDependence(kTRUE); + run->AddTask(trdLI); + std::cout << "-I- : Added task " << trdLI->GetName() << std::endl; + // ------------------------------------------------------------------------ + } + + // AnalysisTree converter + auto* man = new CbmConverterManager(); + man->SetSystem(system); + man->SetBeamMomentum(beam_mom); + + man->SetOutputName(outFile.Data(), "rTree"); + + if (!is_event_base) { man->AddTask(new CbmMatchEvents()); } + + man->AddTask(new CbmSimEventHeaderConverter("SimEventHeader")); + man->AddTask(new CbmRecEventHeaderConverter("RecEventHeader")); + man->AddTask(new CbmSimTracksConverter("SimParticles")); + + CbmStsTracksConverter* taskCbmStsTracksConverter = new CbmStsTracksConverter("VtxTracks", "SimParticles"); + taskCbmStsTracksConverter->SetIsWriteKFInfo(); + taskCbmStsTracksConverter->SetIsReproduceCbmKFPF(); + man->AddTask(taskCbmStsTracksConverter); + + man->AddTask(new CbmRichRingsConverter("RichRings", "VtxTracks")); + man->AddTask(new CbmTofHitsConverter("TofHits", "VtxTracks")); + man->AddTask(new CbmTrdTracksConverter("TrdTracks", "VtxTracks")); + man->AddTask(new CbmPsdModulesConverter("PsdModules")); + + run->AddTask(man); + + // ----- Parameter database -------------------------------------------- + FairRuntimeDb* rtdb = run->GetRuntimeDb(); + auto* parIo1 = new FairParRootFileIo(); + auto* parIo2 = new FairParAsciiFileIo(); + parIo1->open(parFile.Data()); + parIo2->open(parFileList, "in"); + rtdb->setFirstInput(parIo1); + rtdb->setSecondInput(parIo2); + rtdb->setOutput(parIo1); + rtdb->saveOutput(); + // ------------------------------------------------------------------------ + + // ----- Intialise and run -------------------------------------------- + run->Init(); + + std::cout << "Starting run" << std::endl; + run->Run(nEvents); + // ------------------------------------------------------------------------ + + timer.Stop(); + const Double_t rtime = timer.RealTime(); + const Double_t ctime = timer.CpuTime(); + std::cout << "Macro finished succesfully." << std::endl; + std::cout << "Output file is " << outFile << std::endl; + std::cout << "Parameter file is " << parFile << std::endl; + + printf("RealTime=%f seconds, CpuTime=%f seconds\n", rtime, ctime); + + // ----- CTest resource monitoring ------------------------------------ + FairSystemInfo sysInfo; + const Float_t maxMemory = sysInfo.GetMaxMemory(); + std::cout << R"(<DartMeasurement name="MaxMemory" type="numeric/double">)"; + std::cout << maxMemory; + std::cout << "</DartMeasurement>" << std::endl; + std::cout << R"(<DartMeasurement name="WallTime" type="numeric/double">)"; + std::cout << rtime; + std::cout << "</DartMeasurement>" << std::endl; + const Float_t cpuUsage = ctime / rtime; + std::cout << R"(<DartMeasurement name="CpuLoad" type="numeric/double">)"; + std::cout << cpuUsage; + std::cout << "</DartMeasurement>" << std::endl; + // ------------------------------------------------------------------------ + + // ----- Finish ------------------------------------------------------- + std::cout << " Test passed" << std::endl; + std::cout << " All ok " << std::endl; + // Generate_CTest_Dependency_File(depFile); + // ------------------------------------------------------------------------ + + // ----- This is to prevent a malloc error when exiting ROOT ---------- + // The source of the error is unknown. Related to TGeoManager. + RemoveGeoManager(); + // ------------------------------------------------------------------------ +} diff --git a/macro/run/run_digi_json_config.C b/macro/PWG/common/production/run_digi_json_config.C similarity index 100% rename from macro/run/run_digi_json_config.C rename to macro/PWG/common/production/run_digi_json_config.C diff --git a/macro/PWG/common/production/run_json.sh b/macro/PWG/common/production/run_json.sh new file mode 100755 index 0000000000..168a827b61 --- /dev/null +++ b/macro/PWG/common/production/run_json.sh @@ -0,0 +1,88 @@ +#!/bin/bash + +function getJsonVal () { + val=$(${_python} -c "import json;print(json.dumps(json.load(open('${config}'))$1))";) + eval echo ${val} +} # e.x. 'outPath=$(getJsonVal "['transport']['output']['path']")' + +#function checkJsonKey () { +# python -c "import json,sys;print ('$1' in json.load(open('${config}')))"; +#} # returns True if key exists, False if not, e.x. 'run_transport=$(checkJsonKey "transport")' + +function readStepInfo () { + run=$(getJsonVal "['accessory']['${step}']['run']") + if [ ${run} == true ]; then + overwrite=$(getJsonVal "['${step}']['output']['overwrite']") + outDir=$(getJsonVal "['${step}']['output']['path']") + [[ ${outDir} != */ ]] && outDir=$(dirname ${outFile}) + srcDir=${outDir}/macro + macro=$(getJsonVal "['accessory']['${step}']['macro']") + macroName=$(basename ${macro}) + fi +} + +# find the proper python executable and exit if not found +if [[ ! -z $PYHON_EXEC ]]; then + _python=$PYHON_EXEC +else + _python=$(which python) + if [[ -z $_python ]]; then + _python=$(which python2) + if [[ -z $_python ]]; then + _python=$(which python3) + if [[ -z $_python ]]; then + echo "No python interpreter found" + exit 1 + fi + fi + fi +fi +export _python=${_python} + +submitScript=${0} +echo "Submit script : ${submitScript}" +config=${1} +batch=$(getJsonVal "['accessory']['batch']") +jobScript=$(getJsonVal "['accessory']['jobScript']") +export cbmRoot=$(getJsonVal "['accessory']['cbmRoot']") +cbmRoot="${cbmRoot} -a" +echo "CbmRoot : ${cbmRoot}" +source ${cbmRoot} + +steps="transport digitization reconstruction AT" +for step in ${steps}; do + readStepInfo + if [ ${run} == true ]; then + mkdir -pv ${srcDir} + cp -v ${macro} ${srcDir} + cp -v ${config} ${srcDir} + cp -v ${submitScript} ${srcDir} + cp -v ${jobScript} ${srcDir} + fi +done + +export -f getJsonVal +export -f readStepInfo + +export configName=$(basename ${config}) +export config=${srcDir}/${configName} +export nEvents=$(getJsonVal "['accessory']['nEvents']") +jobRange=$(getJsonVal "['accessory']['jobRange']") +logDir=$(getJsonVal "['accessory']['logDir']") +mkdir -pv ${logDir} + +if [ ${batch} == true ];then + account=$(getJsonVal "['accessory']['account']") + ram=$(getJsonVal "['accessory']['ram']") + partition=$(getJsonVal "['accessory']['partition']") + time=$(getJsonVal "['accessory']['time']") + jobName=$(getJsonVal "['accessory']['jobName']") + excludeNodes=$(getJsonVal "['accessory']['excludeNodes']") + sbatch -A ${account} --mem=${ram} -p ${partition} -t ${time} -J ${jobName}\ + -a ${jobRange} -o ${logDir}/%a_%A.log --export=ALL \ + --exclude=${excludeNodes} -- ${jobScript} +else + echo "Jobscript: ${jobScript}" + export SLURM_ARRAY_TASK_ID=${jobRange} + ${jobScript} &> ${logDir}/${jobRange}.log +fi diff --git a/macro/PWG/common/production/run_reco_json_config.C b/macro/PWG/common/production/run_reco_json_config.C new file mode 100644 index 0000000000..f04de8c780 --- /dev/null +++ b/macro/PWG/common/production/run_reco_json_config.C @@ -0,0 +1,573 @@ +/* Copyright (C) 2023 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt + SPDX-License-Identifier: GPL-3.0-only + Authors: Frederic Linz [committer], Volker Friese, Dominik Smith */ + +/** @file run_reco.C + ** @author Volker Friese <v.friese@gsi.de> + ** @since 14 November 2020 + **/ + + +// --- Includes needed for IDE +#include <RtypesCore.h> +#if !defined(__CLING__) +#include "CbmBuildEventsFromTracksReal.h" +#include "CbmBuildEventsIdeal.h" +#include "CbmBuildEventsQa.h" +#include "CbmDefs.h" +#include "CbmFindPrimaryVertex.h" +#include "CbmKF.h" +#include "CbmL1.h" +#include "CbmL1StsTrackFinder.h" +#include "CbmLitFindGlobalTracks.h" +#include "CbmMCDataManager.h" +#include "CbmMatchRecoToMC.h" +#include "CbmMuchFindHitsGem.h" +#include "CbmMvdClusterfinder.h" +#include "CbmMvdHitfinder.h" +#include "CbmPVFinderKF.h" +#include "CbmPrimaryVertexFinder.h" +#include "CbmPsdHitProducer.h" +#include "CbmRecoSts.h" +#include "CbmRecoTzero.h" +#include "CbmRichHitProducer.h" +#include "CbmRichReconstruction.h" +#include "CbmSetup.h" +#include "CbmStsFindTracks.h" +#include "CbmStsFindTracksEvents.h" +#include "CbmStsTrackFinder.h" +#include "CbmTaskBuildRawEvents.h" +#include "CbmTofSimpClusterizer.h" +#include "CbmTrdClusterFinder.h" +#include "CbmTrdHitProducer.h" + +#include <FairFileSource.h> +#include <FairMonitor.h> +#include <FairParAsciiFileIo.h> +#include <FairParRootFileIo.h> +#include <FairRunAna.h> +#include <FairRuntimeDb.h> +#include <FairSystemInfo.h> + +#include <TStopwatch.h> +#endif + + +/** @brief Macro for CBM reconstruction + ** @author Volker Friese <v.friese@gsi.de> + ** @since 14 November 2020 + ** @param input Name of input file (w/o extension .raw.root) + ** @param nTimeSlices Number of time-slices to process + ** @param firstTimeSlice First time-slice (entry) to be processed + ** @param output Name of output file (w/o extension .rec.root) + ** @param sEvBuildRaw Option for raw event building + ** @param traFile Transport ROOT file (w/o extension .tra.root) + ** @param isL1Matching Enable Hit and track matching to MC tracks + ** @param isL1EffQA Option to provide L1_histo.root for QA + ** + ** This macro performs from the digis in a time-slice. It can be used + ** for simulated data (result of run_digi.C) or real data after unpacking. + ** + ** The macro covers both time-based reconstruction and event-based + ** reconstruction using raw events build from digis. This can be selected + ** by the forth argument. If left empty, no raw event builder will be + ** employed and reconstruction will be time-based. The option "Ideal" + ** selects the ideal raw event builder, which associates digis to events + ** based on the MC truth. The option "Real" selects a real raw event builder + ** (latest version, for older versions use "Real2018" or "Real2019"). + ** + ** + ** The file names must be specified without extensions. The convention is + ** that the raw (input) file is [input].raw.root. The output file + ** will be [input].rec.root if not specified by the user. The parameter file + ** has the extension .par.root. It is assumed to be [input].par.root if + ** not specified by the user. + ** + ** If no argument is specified, the input will be set to "test". This allows + ** to execute the macro chain (run_tra_file.C, run_digi.C and run_reco.C) + ** from the ROOT prompt without user intervention. + ** + **/ + +// ----- Check output file name ------------------------------------------- +bool CheckOutFileName(TString fileName, Bool_t overwrite) +{ + string fName = "run_reco_json_config"; + // --- Protect against overwriting an existing file + if ((!gSystem->AccessPathName(fileName.Data())) && (!overwrite)) { + cout << fName << ": output file " << fileName << " already exists!"; + return false; + } + + // --- If the directory does not yet exist, create it + const char* directory = gSystem->DirName(fileName.Data()); + if (gSystem->AccessPathName(directory)) { + Int_t success = gSystem->mkdir(directory, kTRUE); + if (success == -1) { + cout << fName << ": output directory " << directory << " does not exist and cannot be created!"; + return false; + } + else + cout << fName << ": created directory " << directory; + } + return true; +} + +// -------------------------------------------------------------------------- +void run_reco_json_config(TString input = "", Int_t nTimeSlices = -1, Int_t firstTimeSlice = 0, TString output = "", + bool overwrite = false, TString sEvBuildRaw = "", std::string config = "", + TString traFile = "", Bool_t isL1Matching = true, Bool_t isL1EffQA = false) +{ + // ======================================================================== + // Adjust this part according to your requirements + + // --- Logger settings ---------------------------------------------------- + TString logLevel = "INFO"; + TString logVerbosity = "LOW"; + // ------------------------------------------------------------------------ + + // ----- Environment -------------------------------------------------- + TString myName = "run_reco"; // this macro's name for screen output + TString srcDir = gSystem->Getenv("VMCWORKDIR"); // top source directory + // ------------------------------------------------------------------------ + + + // ----- In- and output file names ------------------------------------ + if (input.IsNull()) input = "test"; + TString rawFile = input + ".raw.root"; + TString parFile = input + ".par.root"; + if (output.IsNull()) output = input; + TString outFile = output + ".reco.root"; + TString monFile = output + ".moni_reco.root"; + if (traFile.IsNull()) traFile = input; + traFile += ".tra.root"; + if (!CheckOutFileName(outFile, overwrite)) return; + std::cout << "Inputfile " << rawFile << std::endl; + std::cout << "Outfile " << outFile << std::endl; + std::cout << "Parfile " << parFile << std::endl; + + // ----- Load the geometry setup ------------------------------------- + CbmSetup* geo = CbmSetup::Instance(); + if (config == "") config = Form("%s/macro/run/config.json", gSystem->Getenv("VMCWORKDIR")); + boost::property_tree::ptree pt; + CbmTransportConfig::LoadFromFile(config, pt); + CbmTransportConfig::SetGeometry(geo, pt.get_child(CbmTransportConfig::GetModuleTag())); + // ------------------------------------------------------------------------ + + + // ----- Some global switches ----------------------------------------- + Bool_t eventBased = !sEvBuildRaw.IsNull(); + Bool_t useMvd = geo->IsActive(ECbmModuleId::kMvd); + Bool_t useSts = geo->IsActive(ECbmModuleId::kSts); + Bool_t useRich = geo->IsActive(ECbmModuleId::kRich); + Bool_t useMuch = geo->IsActive(ECbmModuleId::kMuch); + Bool_t useTrd = geo->IsActive(ECbmModuleId::kTrd); + Bool_t useTof = geo->IsActive(ECbmModuleId::kTof); + Bool_t usePsd = geo->IsActive(ECbmModuleId::kPsd); + // ------------------------------------------------------------------------ + if (isL1EffQA) isL1Matching = true; + + // ----- Parameter files as input to the runtime database ------------- + std::cout << std::endl; + std::cout << "-I- " << myName << ": Defining parameter files " << std::endl; + TList* parFileList = new TList(); + TString geoTag; + + // - TRD digitisation parameters + if (CbmSetup::Instance()->GetGeoTag(ECbmModuleId::kTrd, geoTag)) { + const Char_t* npar[4] = {"asic", "digi", "gas", "gain"}; + TObjString* trdParFile(NULL); + for (Int_t i(0); i < 4; i++) { + trdParFile = new TObjString(srcDir + "/parameters/trd/trd_" + geoTag + "." + npar[i] + ".par"); + parFileList->Add(trdParFile); + std::cout << "-I- " << myName << ": Using parameter file " << trdParFile->GetString() << std::endl; + } + } + + // - TOF digitisation parameters + if (CbmSetup::Instance()->GetGeoTag(ECbmModuleId::kTof, geoTag)) { + TObjString* tofBdfFile = new TObjString(srcDir + "/parameters/tof/tof_" + geoTag + ".digibdf.par"); + parFileList->Add(tofBdfFile); + std::cout << "-I- " << myName << ": Using parameter file " << tofBdfFile->GetString() << std::endl; + } + // ------------------------------------------------------------------------ + + // In general, the following parts need not be touched + // ======================================================================== + + + // ----- Timer -------------------------------------------------------- + TStopwatch timer; + timer.Start(); + // ------------------------------------------------------------------------ + + + // ----- FairRunAna --------------------------------------------------- + FairRunAna* run = new FairRunAna(); + FairFileSource* inputSource = new FairFileSource(rawFile); + if (isL1Matching) { inputSource->AddFriend(traFile); } + run->SetSource(inputSource); + run->SetOutputFile(outFile); + run->SetGenerateRunInfo(kTRUE); + FairMonitor::GetMonitor()->EnableMonitor(kTRUE, monFile); + // ------------------------------------------------------------------------ + + // ----- MCDataManager ----------------------------------- + if (isL1Matching) { + CbmMCDataManager* mcManager = new CbmMCDataManager("MCDataManager", 0); + mcManager->AddFile(traFile); + run->AddTask(mcManager); + } + // ------------------------------------------------------------------------ + + // ----- Logger settings ---------------------------------------------- + FairLogger::GetLogger()->SetLogScreenLevel(logLevel.Data()); + FairLogger::GetLogger()->SetLogVerbosityLevel(logVerbosity.Data()); + // ------------------------------------------------------------------------ + + + // ----- Raw event building from digis -------------------------------- + if (eventBased) { + if (sEvBuildRaw.EqualTo("Ideal", TString::ECaseCompare::kIgnoreCase)) { + FairTask* evBuildRaw = new CbmBuildEventsIdeal(); + run->AddTask(evBuildRaw); + std::cout << "-I- " << myName << ": Added task " << evBuildRaw->GetName() << std::endl; + eventBased = kTRUE; + } //? Ideal raw event building + else if (sEvBuildRaw.EqualTo("Real", TString::ECaseCompare::kIgnoreCase)) { + CbmTaskBuildRawEvents* evBuildRaw = new CbmTaskBuildRawEvents(); + + //Choose between NoOverlap, MergeOverlap, AllowOverlap + evBuildRaw->SetEventOverlapMode(EOverlapModeRaw::NoOverlap); + + // Remove detectors where digis not found + if (!useRich) evBuildRaw->RemoveDetector(kRawEventBuilderDetRich); + if (!useMuch) evBuildRaw->RemoveDetector(kRawEventBuilderDetMuch); + if (!usePsd) evBuildRaw->RemoveDetector(kRawEventBuilderDetPsd); + if (!useTof) evBuildRaw->RemoveDetector(kRawEventBuilderDetTof); + if (!useTrd) evBuildRaw->RemoveDetector(kRawEventBuilderDetTrd); + if (!useSts) { + std::cerr << "-E- " << myName << ": Sts must be present for raw event " + << "building using ``Real2019'' option. Terminating macro." << std::endl; + return; + } + // Set STS as reference detector + evBuildRaw->SetReferenceDetector(kRawEventBuilderDetSts); + + // Use sliding window seed builder with STS + //evBuildRaw->SetReferenceDetector(kRawEventBuilderDetUndef); + //evBuildRaw->AddSeedTimeFillerToList(kRawEventBuilderDetSts); + //evBuildRaw->SetSlidingWindowSeedFinder(1000, 500, 500); + //evBuildRaw->SetSeedFinderQa(true); // optional QA information for seed finder + + evBuildRaw->SetTsParameters(0.0, 1.e7, 0.0); //Double_t dTsStartTime, Double_t dTsLength, Double_t dTsOverLength + + // Use CbmMuchDigi instead of CbmMuchBeamtimeDigi + evBuildRaw->ChangeMuchBeamtimeDigiFlag(kFALSE); + + evBuildRaw->SetTriggerMinNumber(ECbmModuleId::kSts, 1); + evBuildRaw->SetTriggerMaxNumber(ECbmModuleId::kSts, -1); + evBuildRaw->SetTriggerWindow(ECbmModuleId::kSts, -1000., 1.e5); + + run->AddTask(evBuildRaw); + std::cout << "-I- " << myName << ": Added task " << evBuildRaw->GetName() << std::endl; + eventBased = kTRUE; + } //? Real raw event building + else { + std::cerr << "-E- " << myName << ": Unknown option " << sEvBuildRaw + << " for raw event building! Terminating macro execution." << std::endl; + return; + } + } //? event-based reco + // ------------------------------------------------------------------------ + + + // ----------- QA for raw event builder ----------------------------------- + if (eventBased && isL1Matching) { + CbmBuildEventsQa* evBuildQA = new CbmBuildEventsQa(); + run->AddTask(evBuildQA); + } + // ------------------------------------------------------------------------ + + + // ----- Local reconstruction in MVD ---------------------------------- + if (useMvd) { + + CbmMvdClusterfinder* mvdCluster = new CbmMvdClusterfinder("MVD Cluster Finder", 0, 0); + run->AddTask(mvdCluster); + std::cout << "-I- : Added task " << mvdCluster->GetName() << std::endl; + + CbmMvdHitfinder* mvdHit = new CbmMvdHitfinder("MVD Hit Finder", 0, 0); + mvdHit->UseClusterfinder(kTRUE); + run->AddTask(mvdHit); + std::cout << "-I- " << myName << ": Added task " << mvdHit->GetName() << std::endl; + } + // ------------------------------------------------------------------------ + + + // ----- Local reconstruction in STS ---------------------------------- + if (useSts) { + CbmRecoSts* stsReco = new CbmRecoSts(ECbmRecoMode::kCbmRecoTimeslice); + if (eventBased) stsReco->SetMode(ECbmRecoMode::kCbmRecoEvent); + run->AddTask(stsReco); + std::cout << "-I- " << myName << ": Added task " << stsReco->GetName() << std::endl; + } + // ------------------------------------------------------------------------ + + + // ----- Local reconstruction in RICH --------------------------------- + if (useRich) { + CbmRichHitProducer* richHitProd = new CbmRichHitProducer(); + run->AddTask(richHitProd); + std::cout << "-I- " << myName << ": Added task " << richHitProd->GetName() << std::endl; + } + // ------------------------------------------------------------------------ + + + // ----- Local reconstruction in MUCH --------------------------------- + if (useMuch) { + + // --- Parameter file name + TString geoTag; + geo->GetGeoTag(ECbmModuleId::kMuch, geoTag); + Int_t muchFlag = (geoTag.Contains("mcbm") ? 1 : 0); + TString parFile = gSystem->Getenv("VMCWORKDIR"); + parFile += "/parameters/much/much_" + geoTag(0, 4) + "_digi_sector.root"; + std::cout << "Using parameter file " << parFile << std::endl; + + // --- Hit finder for GEMs + FairTask* muchReco = new CbmMuchFindHitsGem(parFile.Data(), muchFlag); + run->AddTask(muchReco); + std::cout << "-I- " << myName << ": Added task " << muchReco->GetName() << " with parameter file " << parFile + << std::endl; + } + // ------------------------------------------------------------------------ + + + // ----- Local reconstruction in TRD ---------------------------------- + if (useTrd) { + + Double_t triggerThreshold = 0.5e-6; // SIS100 + CbmTrdClusterFinder* trdCluster = new CbmTrdClusterFinder(); + if (eventBased) trdCluster->SetTimeBased(kFALSE); + else + trdCluster->SetTimeBased(kTRUE); + trdCluster->SetNeighbourEnable(true, false); + trdCluster->SetMinimumChargeTH(triggerThreshold); + trdCluster->SetRowMerger(true); + + // Uncomment if you want to use all available digis. + // In that case clusters hits will not be added to the CbmEvent + // trdCluster->SetUseOnlyEventDigis(kFALSE); + + run->AddTask(trdCluster); + std::cout << "-I- " << myName << ": Added task " << trdCluster->GetName() << std::endl; + + CbmTrdHitProducer* trdHit = new CbmTrdHitProducer(); + run->AddTask(trdHit); + std::cout << "-I- " << myName << ": Added task " << trdHit->GetName() << std::endl; + } + // ------------------------------------------------------------------------ + + + // ----- Local reconstruction in TOF ---------------------------------- + if (useTof) { + CbmTofSimpClusterizer* tofCluster = new CbmTofSimpClusterizer("TofSimpClusterizer", 0); + tofCluster->SetOutputBranchPersistent("TofHit", kTRUE); + tofCluster->SetOutputBranchPersistent("TofDigiMatch", kTRUE); + run->AddTask(tofCluster); + std::cout << "-I- " << myName << ": Added task " << tofCluster->GetName() << std::endl; + } + // ------------------------------------------------------------------------ + + + // ----- Local reconstruction in PSD ---------------------------------- + if (usePsd) { + CbmPsdHitProducer* psdHit = new CbmPsdHitProducer(); + run->AddTask(psdHit); + std::cout << "-I- " << myName << ": Added task " << psdHit->GetName() << std::endl; + } + // -------------- Match MC Hits to Reco Hits-------------------------------- + if (isL1Matching) { + CbmMatchRecoToMC* match1 = new CbmMatchRecoToMC(); + run->AddTask(match1); + } + + // ----- Track finding in STS (+ MVD) -------------------------------- + if (useMvd || useSts) { + run->AddTask(new CbmTrackingDetectorInterfaceInit()); + CbmKF* kalman = new CbmKF(); + run->AddTask(kalman); + + // L1 tracking: + int verbosemodeL1 = (isL1EffQA) ? 2 : 0; + int performanceL1 = (isL1EffQA) ? 3 : 0; + auto l1 = new CbmL1("L1", verbosemodeL1, performanceL1); + + // --- Material budget file names + TString mvdGeoTag; + if (geo->GetGeoTag(ECbmModuleId::kMvd, mvdGeoTag)) { + TString parFile = gSystem->Getenv("VMCWORKDIR"); + parFile += "/parameters/mvd/mvd_matbudget_" + mvdGeoTag + ".root"; + std::cout << "Using material budget file " << parFile << std::endl; + l1->SetMvdMaterialBudgetFileName(parFile.Data()); + } + TString stsGeoTag; + if (geo->GetGeoTag(ECbmModuleId::kSts, stsGeoTag)) { + TString parFile = gSystem->Getenv("VMCWORKDIR"); + parFile += "/parameters/sts/sts_matbudget_" + stsGeoTag + ".root"; + std::cout << "Using material budget file " << parFile << std::endl; + l1->SetStsMaterialBudgetFileName(parFile.Data()); + } + run->AddTask(l1); + std::cout << "-I- " << myName << ": Added task " << l1->GetName() << std::endl; + + CbmStsTrackFinder* stsTrackFinder = new CbmL1StsTrackFinder(); + if (eventBased) { + FairTask* stsFindTracks = new CbmStsFindTracksEvents(stsTrackFinder, useMvd); + run->AddTask(stsFindTracks); + std::cout << "-I- " << myName << ": Added task " << stsFindTracks->GetName() << std::endl; + } + else { + FairTask* stsFindTracks = new CbmStsFindTracks(0, stsTrackFinder, useMvd); + run->AddTask(stsFindTracks); + std::cout << "-I- " << myName << ": Added task " << stsFindTracks->GetName() << std::endl; + } + } + // ------------------------------------------------------------------------ + + + // ==== From here on, the time-based and the event-based reconstruction + // ==== chains differ, since time-based version of primary vertex finding + // ==== and global tracking are not yet available. For time-based + // ==== reconstruction, a track-based event finder is used; no global + // ==== tracks are produced. + + if (eventBased) { + + // ----- Primary vertex finding ------------------------------------- + CbmPrimaryVertexFinder* pvFinder = new CbmPVFinderKF(); + CbmFindPrimaryVertex* findVertex = new CbmFindPrimaryVertex(pvFinder); + run->AddTask(findVertex); + std::cout << "-I- " << myName << ": Added task " << findVertex->GetName() << std::endl; + // ---------------------------------------------------------------------- + + + // --- Global track finding ----------------------------------------- + CbmLitFindGlobalTracks* finder = new CbmLitFindGlobalTracks(); + finder->SetTrackingType("branch"); + finder->SetMergerType("nearest_hit"); + run->AddTask(finder); + std::cout << "-I- : Added task " << finder->GetName() << std::endl; + // ---------------------------------------------------------------------- + + // --- Particle Id in TRD ----------------------------------------- + if (useTrd) { + CbmTrdSetTracksPidLike* trdLI = new CbmTrdSetTracksPidLike("TRDLikelihood", "TRDLikelihood"); + trdLI->SetUseMCInfo(kTRUE); + trdLI->SetUseMomDependence(kTRUE); + run->AddTask(trdLI); + std::cout << "-I- : Added task " << trdLI->GetName() << std::endl; + } + // ------------------------------------------------------------------------ + + + // ----- RICH reconstruction ---------------------------------------- + if (useRich) { + CbmRichReconstruction* richReco = new CbmRichReconstruction(); + run->AddTask(richReco); + std::cout << "-I- : Added task " << richReco->GetName() << std::endl; + } + // ---------------------------------------------------------------------- + + // ----- T0 reconstruction ---------------------------------------------- + CbmRecoTzero* recoT0 = new CbmRecoTzero(); + run->AddTask(recoT0); + std::cout << "-I-: Added task " << recoT0->GetName() << std::endl; + // ----------------------------------------------------------------------- + + // ----- Track matching ----------------------------------------------- + if (isL1Matching) { + CbmMatchRecoToMC* match2 = new CbmMatchRecoToMC(); + run->AddTask(match2); + } + // ------------------------------------------------------------------------- + } //? event-based reco + + else { + + // -----Â Event building from STS tracks ----------------------------- + run->AddTask(new CbmBuildEventsFromTracksReal()); + // ---------------------------------------------------------------------- + + } //? time-based reco + + + // ----- Parameter database -------------------------------------------- + std::cout << std::endl << std::endl; + std::cout << "-I- " << myName << ": Set runtime DB" << std::endl; + FairRuntimeDb* rtdb = run->GetRuntimeDb(); + FairParRootFileIo* parIo1 = new FairParRootFileIo(); + FairParAsciiFileIo* parIo2 = new FairParAsciiFileIo(); + parIo1->open(parFile.Data(), "UPDATE"); + rtdb->setFirstInput(parIo1); + if (!parFileList->IsEmpty()) { + parIo2->open(parFileList, "in"); + rtdb->setSecondInput(parIo2); + } + // ------------------------------------------------------------------------ + + + // ----- Run initialisation ------------------------------------------- + std::cout << std::endl; + std::cout << "-I- " << myName << ": Initialise run" << std::endl; + run->Init(); + rtdb->setOutput(parIo1); + rtdb->saveOutput(); + rtdb->print(); + // ------------------------------------------------------------------------ + + + // ----- Register light ions (d, t, He3, He4) ------------------------- + std::cout << std::endl; + TString registerLightIonsMacro = gSystem->Getenv("VMCWORKDIR"); + registerLightIonsMacro += "/macro/KF/registerLightIons.C"; + std::cout << "Loading macro " << registerLightIonsMacro << std::endl; + gROOT->LoadMacro(registerLightIonsMacro); + gROOT->ProcessLine("registerLightIons()"); + // ------------------------------------------------------------------------ + + // ----- Start run ---------------------------------------------------- + std::cout << std::endl << std::endl; + std::cout << "-I- " << myName << ": Starting run" << std::endl; + run->Run(firstTimeSlice, nTimeSlices); + // ------------------------------------------------------------------------ + + + // ----- Finish ------------------------------------------------------- + timer.Stop(); + FairMonitor::GetMonitor()->Print(); + Double_t rtime = timer.RealTime(); + Double_t ctime = timer.CpuTime(); + std::cout << std::endl << std::endl; + std::cout << "Macro finished successfully." << std::endl; + std::cout << "Output file is " << outFile << std::endl; + std::cout << "Parameter file is " << parFile << std::endl; + std::cout << "Real time " << rtime << " s, CPU time " << ctime << " s" << std::endl; + FairSystemInfo sysInfo; + Float_t maxMemory = sysInfo.GetMaxMemory(); + std::cout << "<DartMeasurement name=\"MaxMemory\" type=\"numeric/double\">"; + std::cout << maxMemory; + std::cout << "</DartMeasurement>" << std::endl; + Float_t cpuUsage = ctime / rtime; + std::cout << "<DartMeasurement name=\"CpuLoad\" type=\"numeric/double\">"; + std::cout << cpuUsage; + std::cout << "</DartMeasurement>" << std::endl; + // ------------------------------------------------------------------------ + + // ----- This is to prevent a malloc error when exiting ROOT ---------- + // The source of the error is unknown. Related to TGeoManager. + RemoveGeoManager(); + // ------------------------------------------------------------------------ + +} // End of main macro function diff --git a/macro/PWG/common/production/run_sim_reco_json.sh b/macro/PWG/common/production/run_sim_reco_json.sh new file mode 100755 index 0000000000..287b13445f --- /dev/null +++ b/macro/PWG/common/production/run_sim_reco_json.sh @@ -0,0 +1,80 @@ +#!/bin/bash + +steps="transport digitization reconstruction AT" +source ${cbmRoot} +for step in ${steps}; do + readStepInfo + if [ ${run} == true ]; then + export taskId=${SLURM_ARRAY_TASK_ID} + plutoShift=$(getJsonVal "['accessory']['transport']['plutoShift']") + export plutoFileId=$(printf %05d $((${taskId}-${plutoShift}))) + config=${srcDir}/${configName} + macro=${srcDir}/${macroName} + outFile=$(getJsonVal "['${step}']['output']['path']") + outDir=$(dirname ${outFile}) + log=${outDir}/${step}.log + + mkdir -pv ${outDir} + cd ${outDir} + ln -sfv ${VMCWORKDIR}/macro/run/.rootrc ${outDir} + if [ ${step} == reconstruction ]; then + rawFile=$(getJsonVal "['reconstruction']['rawFile']") + nTimeSlices=$(getJsonVal "['reconstruction']['nTimeSlices']") + firstTimeSlice=$(getJsonVal "['reconstruction']['firstTimeSlice']") + sEvBuildRaw=$(getJsonVal "['reconstruction']['sEvBuildRaw']") + traFile=$(getJsonVal "['reconstruction']['traFile']") + isL1Matching=$(getJsonVal "['reconstruction']['isL1Matching']") + isL1EffQA=$(getJsonVal "['reconstruction']['isL1EffQA']") + echo " " + echo "Run reconstruction: ${macro}(\"${rawFile}\",${nTimeSlices},${firstTimeSlice},\"${outFile}\",\ + ${overwrite},\"${sEvBuildRaw}\",\"${config}\",\"${traFile}\",${isL1Matching},${isL1EffQA})" + root -b -l -q "${macro}(\"${rawFile}\",${nTimeSlices},${firstTimeSlice},\"${outFile}\",\ + ${overwrite},\"${sEvBuildRaw}\",\"${config}\",\"${traFile}\",${isL1Matching},${isL1EffQA})" &> ${log} + elif [ ${step} == AT ]; then + traFile=$(getJsonVal "['AT']['traFile']") + rawFile=$(getJsonVal "['AT']['rawFile']") + recFile=$(getJsonVal "['AT']['recFile']") + unigenFile=$(getJsonVal "['AT']['unigenFile']") + echo " " + echo "Run AT converter: ${macro}(\"${traFile}\",\"${rawFile}\",\"${recFile}\",\ + \"${unigenFile}\",\"${outFile}\",${overwrite},\"${config}\")" + root -b -l -q "${macro}(\"${traFile}\",\"${rawFile}\",\"${recFile}\",\ + \"${unigenFile}\",\"${outFile}\",${overwrite},\"${config}\")" &> ${log} + else + if [ ${step} == digitization ]; then + input=$(getJsonVal "['transport']['output']['path']") + if [ ! -e ${outFile}.par.root ] || [ ${overwrite} == true ]; then + cp -v ${input}.par.root ${outDir} + fi + echo " " + echo "Run digitization: ${macro}(\"${config}\",${nEvents})" + fi + + if [ ${step} == transport ]; then + echo " " + echo "Run transport: ${macro}(\"${config}\",${nEvents})" + fi + + root -b -l -q "${macro}(\"${config}\",${nEvents})" &> ${log} + fi + gzip -f ${log} + + rm -v .rootrc + if [ ${step} == reconstruction ]; then + if [ "${isL1EffQA}" == true ]; then + rm -v *{moni,CA}* all_*.par + else + rm -v *{core,moni,CA,L1,Edep}* all_*.par + fi + fi + if [ ${step} == digitization ]; then + rm -v *{moni,Fair}* all_*.par + fi + if [ ${step} == AT ]; then + rm -v *{core,CA,L1}* + fi + + cd - + export taskId= + fi +done diff --git a/macro/run/run_transport_json_config.C b/macro/PWG/common/production/run_transport_json_config.C similarity index 100% rename from macro/run/run_transport_json_config.C rename to macro/PWG/common/production/run_transport_json_config.C diff --git a/macro/run/CMakeLists.txt b/macro/run/CMakeLists.txt index f1f85c5dfd..adba40b906 100644 --- a/macro/run/CMakeLists.txt +++ b/macro/run/CMakeLists.txt @@ -1,7 +1,5 @@ # ===== Generate the needed shell scripts ================================ GENERATE_ROOT_TEST_SCRIPT(${CBMROOT_SOURCE_DIR}/macro/run/run_tra_file.C) -GENERATE_ROOT_TEST_SCRIPT(${CBMROOT_SOURCE_DIR}/macro/run/run_transport_json_config.C) -GENERATE_ROOT_TEST_SCRIPT(${CBMROOT_SOURCE_DIR}/macro/run/run_digi_json_config.C) GENERATE_ROOT_TEST_SCRIPT(${CBMROOT_SOURCE_DIR}/macro/run/run_tra_beam.C) GENERATE_ROOT_TEST_SCRIPT(${CBMROOT_SOURCE_DIR}/macro/run/run_digi.C) GENERATE_ROOT_TEST_SCRIPT(${CBMROOT_SOURCE_DIR}/macro/run/run_reco.C) @@ -79,33 +77,6 @@ foreach(setup IN LISTS cbm_setup) set(sname test) endif() - # --- Test run_transport_json_config - # --- Transport run using run_transport_json_config.C - set(json_config_file ${CBMROOT_SOURCE_DIR}/macro/run/config_ci.json) - set(testname run_transport_json_config) - add_test(${testname} ${MACRO_DIR}/run_transport_json_config.sh \"${json_config_file}\" 2 ${randomSeed}) - set_tests_properties(${testname} PROPERTIES - TIMEOUT ${timeOutTime} - FAIL_REGULAR_EXPRESSION "segmentation violation" - PASS_REGULAR_EXPRESSION "Macro finished successfully" - FIXTURES_REQUIRED run_cleanup - FIXTURES_SETUP fixt_tra_json_config - RESOURCE_LOCK json_config_ParDb - ) - - # --- Test run_digi_json_config - # --- Digitization run with using run_digi_json_config.C - set(testname run_digi_json_config) - add_test(${testname} ${MACRO_DIR}/run_digi_json_config.sh \"${json_config_file}\") - set_tests_properties(${testname} PROPERTIES - TIMEOUT ${timeOutTime} - FAIL_REGULAR_EXPRESSION "segmentation violation" - PASS_REGULAR_EXPRESSION "Macro finished successfully" - FIXTURES_REQUIRED fixt_tra_json_config - FIXTURES_SETUP fixt_digi_json_config - RESOURCE_LOCK json_config_ParDb - ) - # --- Test run_tra_coll # --- Transport run with collision events, using run_tra_file.C set(testname run_${sname}_tra_coll) @@ -505,8 +476,7 @@ EndIf() # If(DEFINED ENV{RAW_DATA_PATH} ) ##################### # ============================================================================ -Install(FILES .rootrc run_tra_file.C run_tra_beam.C run_transport_json_config.C run_digi_json_config.C config.json - run_digi.C run_reco.C run_unpack_online.C run_unpack_tsa.C config_ci.json +Install(FILES .rootrc run_tra_file.C run_tra_beam.C run_digi.C run_reco.C run_unpack_online.C run_unpack_tsa.C DESTINATION share/cbmroot/macro/run ) Install(PROGRAMS run_tests.sh diff --git a/macro/run/config.json b/macro/run/config.json deleted file mode 100644 index c018b9e83b..0000000000 --- a/macro/run/config.json +++ /dev/null @@ -1,117 +0,0 @@ -{ - "logScreenLevel": "INFO", - "logVerbosityLevel": "LOW", - "transport": { - "input": [ - {"generator": "unigen", - "file": "${VMCWORKDIR}/input/urqmd.auau.10gev.centr.root"}, - {"generator": "pluto", - "file": "${VMCWORKDIR}/input/pluto.auau.8gev.omega.mpmm.0001.root", - "plutoPdg": 0}, - {"generator": "beam", - "beamA": 197, - "beamZ": 79, - "beamQ": 79, - "beamP": 12.0, - "beamStartZ": -1.0} - ], - "output": { - "path": "test", - "overwrite": false - }, - "target": { - "material": "Gold", - "thickness": 0.025, - "diameter": 2.5, - "position": { - "x": 0.0, - "y": 0.0, - "z": 0.0 - }, - "rotation.y": 0.0 - }, - "beam": { - "position": { - "x": 0.0, - "y": 0.0, - "zFocus": 0.0, - "sigmaX": 0.1, - "sigmaY": 0.1 - }, - "angle": { - "x": 0.0, - "y": 0.0, - "sigmaX": 0.001, - "sigmaY": 0.001 - } - }, - "randomRP": true, - "geantVersion": 4, - "geant4vmcSettings": { - "physicsLists": "QGSP_BERT_EMV+optical", - "specialProcesses": "stepLimiter", - "maxNsteps": 10000000, - "geant4commands": [""] - }, - "geometry": { - "baseSetup": "sis100_electron", - "magneticField": { - "tag": "v18a", - "scale": 1.0, - "position": { - "x": 0.0, - "y": 0.0, - "z": 0.0 - } - }, - "subsystems": { - "magnet": "v21a", - "pipe": "v16e_1e", - "mvd": "v20c_tr", - "sts": "v20a", - "rich": "v21a", - "trd": "v20c_1e", - "tof": "v20c_1e", - "psd": "v20c", - "platform": "v13a" - } - }, - "stackFilter": { - "storeAllPrimaries": true, - "storeAllMothers": true, - "storeAllDecays": true - } - }, - - "digitization": { - "generateRunInfo": false, - "eventMode": false, - "timeSliceLength": -1.0, - "storeAllTimeSlices": false, - "startTime": 1000, - "produceNoise": true, - "input": [ - {"id": 0, - "path": "test", - "rate": "1.e7", - "treeAccessMode": "regular", - "parameterSource": true}, - {"id": -1, - "path": "test_emb", - "embedToId": 0, - "treeAccessMode": "regular"}, - {"id": -1, - "path": "test_beam", - "rate": "1.e9", - "treeAccessMode": "regular"} - ], - "output": { - "path": "data/test_json", - "overwrite": false - }, - "geometry": { - "deactivate": ["", ""], - "#deactivateAllBut": "" - } - } -} diff --git a/macro/run/config_ci.json b/macro/run/config_ci.json deleted file mode 100644 index 0c75e9bc98..0000000000 --- a/macro/run/config_ci.json +++ /dev/null @@ -1,117 +0,0 @@ -{ - "logScreenLevel": "INFO", - "logVerbosityLevel": "LOW", - "transport": { - "input": [ - {"generator": "unigen", - "file": "${VMCWORKDIR}/input/urqmd.auau.10gev.centr.root"}, - {"generator": "pluto", - "file": "${VMCWORKDIR}/input/pluto.auau.8gev.omega.mpmm.0001.root", - "plutoPdg": 0}, - {"generator": "beam", - "beamA": 197, - "beamZ": 79, - "beamQ": 79, - "beamP": 12.0, - "beamStartZ": -1.0} - ], - "output": { - "path": "data/test", - "overwrite": true - }, - "target": { - "material": "Gold", - "thickness": 0.025, - "diameter": 2.5, - "position": { - "x": 0.0, - "y": 0.0, - "z": 0.0 - }, - "rotation.y": 0.0 - }, - "beam": { - "position": { - "x": 0.0, - "y": 0.0, - "zFocus": 0.0, - "sigmaX": 0.1, - "sigmaY": 0.1 - }, - "angle": { - "x": 0.0, - "y": 0.0, - "sigmaX": 0.001, - "sigmaY": 0.001 - } - }, - "randomRP": true, - "geantVersion": 4, - "geant4vmcSettings": { - "physicsLists": "QGSP_BERT_EMV+optical", - "specialProcesses": "stepLimiter", - "maxNsteps": 10000000, - "geant4commands": [""] - }, - "geometry": { - "baseSetup": "sis100_electron", - "magneticField": { - "tag": "v18a", - "scale": 1.0, - "position": { - "x": 0.0, - "y": 0.0, - "z": 0.0 - } - }, - "subsystems": { - "magnet": "v21a", - "pipe": "v16e_1e", - "mvd": "v20c_tr", - "sts": "v20a", - "rich": "v21a", - "trd": "v20c_1e", - "tof": "v20c_1e", - "psd": "v20c", - "platform": "v13a" - } - }, - "stackFilter": { - "storeAllPrimaries": true, - "storeAllMothers": true, - "storeAllDecays": true - } - }, - - "digitization": { - "generateRunInfo": false, - "eventMode": false, - "timeSliceLength": -1.0, - "storeAllTimeSlices": false, - "startTime": 1000, - "produceNoise": true, - "input": [ - {"id": 0, - "path": "data/test", - "rate": "1.e7", - "treeAccessMode": "regular", - "parameterSource": true}, - {"id": -1, - "path": "test_emb", - "embedToId": 0, - "treeAccessMode": "regular"}, - {"id": -1, - "path": "test_beam", - "rate": "1.e9", - "treeAccessMode": "regular"} - ], - "output": { - "path": "data/test_json", - "overwrite": true - }, - "geometry": { - "deactivate": ["", ""], - "#deactivateAllBut": "" - } - } -} diff --git a/macro/run/run_tests.sh b/macro/run/run_tests.sh index cb3fb4f1bc..113a91f39b 100644 --- a/macro/run/run_tests.sh +++ b/macro/run/run_tests.sh @@ -45,22 +45,6 @@ main () { $log_file_name \ $check_string - log_file_name=data/run_tra_json.log - check_string="Macro finished successfully" - - execute_macro "run_transport_json_config.C(\"config_ci.json\")" \ - $log_file_name \ - $check_string - - # Testing the digitization macros - log_file_name=data/run_digi_json.log - check_string="Macro finished successfully" - - execute_macro "run_digi_json_config.C(\"config_ci.json\")" \ - $log_file_name \ - $check_string - - log_file_name=data/run_digi_eb.log check_string="Macro finished successfully" execute_macro "run_digi.C(\"data/${sname}_coll\", -1, \"data/${sname}_ev\", -1.)" \ -- GitLab