From f42f80f13ed49f729f3f7834339ca1ea837aff1e Mon Sep 17 00:00:00 2001 From: Souvik Chattopadhyay <schattop@lxbuild07.gsi.de> Date: Sun, 23 Feb 2025 01:03:08 +0100 Subject: [PATCH 01/11] Save changeext lib e switching branches --- external/InstallParameter.cmake | 9 --------- 1 file changed, 9 deletions(-) delete mode 100644 external/InstallParameter.cmake diff --git a/external/InstallParameter.cmake b/external/InstallParameter.cmake deleted file mode 100644 index 8915b4595..000000000 --- a/external/InstallParameter.cmake +++ /dev/null @@ -1,9 +0,0 @@ -set(PARAMETER_VERSION fc402a25347c5a9f8df60fea216054d414df1321) # 2025/04/07 -set(PARAMETER_SRC_URL "https://git.cbm.gsi.de/CbmSoft/cbmroot_parameter.git") - -download_project_if_needed(PROJECT Parameter_source - GIT_REPOSITORY ${PARAMETER_SRC_URL} - GIT_TAG ${PARAMETER_VERSION} - SOURCE_DIR ${CMAKE_SOURCE_DIR}/parameters - TEST_FILE sts/LandauWidthTable.txt - ) -- GitLab From 0576c3a019129db81389f2e70e99b468db98ecac Mon Sep 17 00:00:00 2001 From: Souvik Chattopadhyay <schattop@lxg0486.gsi.de> Date: Tue, 25 Mar 2025 12:14:08 +0100 Subject: [PATCH 02/11] QA checker updates (I) --- macro/qa/Run_api_for_comparing_hist.C | 261 ++++++++++++++++++++++++++ 1 file changed, 261 insertions(+) create mode 100644 macro/qa/Run_api_for_comparing_hist.C diff --git a/macro/qa/Run_api_for_comparing_hist.C b/macro/qa/Run_api_for_comparing_hist.C new file mode 100644 index 000000000..74f5a6ab5 --- /dev/null +++ b/macro/qa/Run_api_for_comparing_hist.C @@ -0,0 +1,261 @@ +#include <iostream> +#include <vector> +#include <string> +#include <fstream> +#include <unistd.h> +#include <cstddef> +#include <sstream> +void updateYamlFile(const std::string &filePath, const std::vector<std::string> &versionNames, + const std::string &srcDir, const std::string &newFilePattern, bool compareCommit1) { + std::ifstream file(filePath); + if (!file) { + std::cerr << "Error: Unable to open file " << filePath << std::endl; + return; + } + + std::ostringstream modifiedYaml; + std::string line; + bool inVersions = false, inDatasets = false, inFiles = false; + + while (std::getline(file, line)) { + // Trim leading spaces (YAML indentation) + std::string trimmedLine = line; + trimmedLine.erase(0, trimmedLine.find_first_not_of(" \t")); + + // Identify sections + if (trimmedLine.find("versions:") == 0) { + inVersions = true; + inDatasets = false; + inFiles = false; + modifiedYaml << line << "\n"; // Keep the "versions:" header + + // Add new versions dynamically + if(compareCommit1==true){ + for (const auto &version : versionNames) { + std::string label = version.substr(0, 9); + std::string path = srcDir + "/output_CA_" + label; + modifiedYaml << " - label: \"" << label << "\"\n"; + modifiedYaml << " path: \"" << path << "\"\n"; + } + } + else{ + for (const auto &version : versionNames) { + //std::string version=versionName[iv]; + std::size_t pos = version.find('_'); + + // Extract the year and week number + std::string YEAR_ISO = version.substr(0, pos); + std::string WEEK_ISO = version.substr(pos + 1); + std::string path = "/lustre/cbm/users/ploizeau/cdash/weekly_virgo3_vae23_dev_" + YEAR_ISO +"_" + WEEK_ISO + "/macro/run/data/s100h_qa_ts_eb_ideal.\ +qa"; + std::string label = version; + + + modifiedYaml << " - label: \"" << label << "\"\n"; + modifiedYaml << " path: \"" << path << "\"\n"; + } + + + + } + continue; // Skip original version entries + } + + if (trimmedLine.find("datasets:") == 0) { + inDatasets = true; + inVersions = false; + inFiles = false; + } else if (trimmedLine.find("files:") == 0) { + inFiles = true; + inVersions = false; + inDatasets = false; + } + + // Skip old "versions:" content + if (inVersions && (trimmedLine.find("- label:") == 0 || trimmedLine.find("path:") == 0)) { + continue; + } + + // Replace file pattern inside "files:" + if (inFiles && trimmedLine.find("- name:") == 0) { + + modifiedYaml << " - name: \"" << newFilePattern << "\"\n"; // Replace with new pattern + std::cout<< "SOUVIK - name: \"" << newFilePattern << "\"\n"; + continue; + } + + // Preserve other sections as-is + modifiedYaml << line << "\n"; + } + + file.close(); + + // Write the updated content back to the file + std::ofstream outFile(filePath); + if (!outFile) { + std::cerr << "Error: Unable to write to file " << filePath << std::endl; + return; + } + outFile << modifiedYaml.str(); + outFile.close(); + + std::cout << "YAML file updated successfully!" << std::endl; +} + + + + + + +int main(int argc, char* argv[]) { + std::vector<std::string> args(argv, argv + argc); + /*for(int i=0;i<args.size();i++){ + + std::cout<<args[i]<<std::endl; + + }*/ + char buffer[1024]; + if (getcwd(buffer, sizeof(buffer)) == nullptr) { + //std::cerr << "Error: " << strerror(errno) << std::endl; + return 1; + } + + std::string srcDir(buffer); + std::cout<<"Current Directory:\t"<<srcDir<<std::endl; + // std::string srcDir = std::filesystem::current_path().string(); + std::vector<std::string> versionName; + + const char* configName = "objects2.yaml"; + const char* outputName = "QACheckerOutput.root"; + std::string scriptInput= "./run_commit_out.sh"; + std::string dataset = "default"; + bool defaultConfig= true; + bool compareCommit= false; + // std::ofstream yamlFile(configName); + + + + if(argc<2){ + std::cerr<< "Please provide type of input(-chash or -wtest) and atleast two versions(commit hash or week number(yyyy_ww)"<<std::endl; + return 0; + } + + + if (args[1] == "-chash") {//for comparision of differnt commit + compareCommit = true; + + } + else if(args[1] == "-wtest"){//for comparision of weekly test + + + compareCommit = false; + } + + else{ + + std::cerr<< "No valid input available"<<std::endl; + return 0; + + } + + + + +for (size_t i = 2; i < args.size(); ++i) { + if(args[i]=="-config"){ + defaultConfig=0; + configName=args[i + 1].c_str(); + break; + } + else if(args[i]=="-output"){ + break; + } + versionName.push_back(args[i]); + scriptInput += " " + args[i]; + + } + + for (size_t i = 2; i < args.size(); ++i) { + if(args[i]=="-output"){ + + outputName=args[i + 1].c_str(); + break; + } + } + for (size_t i = 2; i < args.size(); ++i) { + if(args[i]=="-dataset"){ + + dataset=args[i + 1]; + break; + } + } + // std::string yamlName =srcDir+"/configs/"+std::string(configName); + // if(defaultConfig==1){ + std::string yamlName =srcDir+"/configs/"+std::string(configName); + if(compareCommit==true){ + std::string newFilePattern = "%v_%d.root"; // New pattern for files + + updateYamlFile(yamlName, versionName, srcDir, newFilePattern,compareCommit); + } + else{ + std::string newFilePattern = "%v.root"; // New pattern for files + + updateYamlFile(yamlName, versionName, srcDir, newFilePattern,compareCommit); + } + /* yamlFile << " datasets:\n"; + yamlFile << " - \"" <<dataset<< "\"\n"; + yamlFile << " files:\n"; + yamlFile << " - name: \"%v_%d.root\"\n"; + yamlFile << " label: qa\n"; + yamlFile << " objects:\n"; + yamlFile << " - CbmCaInputQaSts/efficiencies/casts_reco_eff_vs_r_st0\n"; + yamlFile << " - CbmCaInputQaSts/efficiencies/casts_reco_eff_vs_xy_st0\n"; + yamlFile << " - CbmCaInputQaSts/histograms/casts_pull_t_st2\n"; + yamlFile << " - CbmCaInputQaSts/histograms/casts_res_x_vs_x_st2\n"; + */ + // yamlFile.close(); + // std::cout << "YAML file created successfully!" << std::endl; + // return 0; + //} + + + + + if(compareCommit==true){ + + // Execute the script using system() + std::cout << "Executing script to install commit hash: " << scriptInput << std::endl; + std::string scriptwithData=scriptInput+" --dataset "+dataset; + int returnCode = std::system(scriptwithData.c_str()); + if (returnCode != 0) { + std::cerr << "Failed to execute:" <<scriptInput<< std::endl; + return 1; + } + std::string yamlName =srcDir+"/configs/"+std::string(configName); + std::string qacommand = std::string("root -l -q 'qa_compare_ca.C(\"") + yamlName + "\", \"" + outputName + "\")'"; + std::cout<<"Executing macro\t"<<qacommand<<std::endl; + int returnMacro = std::system(qacommand.c_str()); + if (returnMacro = 0) { + std::cerr << "Failed to execute: qa_compare_ca.C"<< std::endl; + return 1; + } + + + + } + else{ +std::string yamlName =srcDir+"/configs/"+std::string(configName); + std::string qacommand = std::string("root -l -q 'qa_compare_ca.C(\"") + yamlName + "\", \"" + outputName + "\")'"; + std::cout<<"Executing macro\t"<<qacommand<<std::endl; + int returnMacro = std::system(qacommand.c_str()); + if (returnMacro != 0) { + std::cerr << "Failed to execute: qa_compare_ca.C"<< std::endl; + return 1; + + } + + } + + + +} -- GitLab From a08a5b790f21c9941edc7b1eae0f1f66a7de8530 Mon Sep 17 00:00:00 2001 From: Souvik Chattopadhyay <schattop@lxg0486.gsi.de> Date: Wed, 26 Mar 2025 11:41:23 +0100 Subject: [PATCH 03/11] updated runapi --- macro/qa/Run_api_for_comparing_hist.C | 21 ++------------------- 1 file changed, 2 insertions(+), 19 deletions(-) diff --git a/macro/qa/Run_api_for_comparing_hist.C b/macro/qa/Run_api_for_comparing_hist.C index 74f5a6ab5..3800f00c5 100644 --- a/macro/qa/Run_api_for_comparing_hist.C +++ b/macro/qa/Run_api_for_comparing_hist.C @@ -80,7 +80,7 @@ qa"; if (inFiles && trimmedLine.find("- name:") == 0) { modifiedYaml << " - name: \"" << newFilePattern << "\"\n"; // Replace with new pattern - std::cout<< "SOUVIK - name: \"" << newFilePattern << "\"\n"; + continue; } @@ -99,7 +99,7 @@ qa"; outFile << modifiedYaml.str(); outFile.close(); - std::cout << "YAML file updated successfully!" << std::endl; + // std::cout << "YAML file updated successfully!" << std::endl; } @@ -202,23 +202,6 @@ for (size_t i = 2; i < args.size(); ++i) { updateYamlFile(yamlName, versionName, srcDir, newFilePattern,compareCommit); } - /* yamlFile << " datasets:\n"; - yamlFile << " - \"" <<dataset<< "\"\n"; - yamlFile << " files:\n"; - yamlFile << " - name: \"%v_%d.root\"\n"; - yamlFile << " label: qa\n"; - yamlFile << " objects:\n"; - yamlFile << " - CbmCaInputQaSts/efficiencies/casts_reco_eff_vs_r_st0\n"; - yamlFile << " - CbmCaInputQaSts/efficiencies/casts_reco_eff_vs_xy_st0\n"; - yamlFile << " - CbmCaInputQaSts/histograms/casts_pull_t_st2\n"; - yamlFile << " - CbmCaInputQaSts/histograms/casts_res_x_vs_x_st2\n"; - */ - // yamlFile.close(); - // std::cout << "YAML file created successfully!" << std::endl; - // return 0; - //} - - if(compareCommit==true){ -- GitLab From a6b0152822f9b75c7f662f009a835ceb59299e9c Mon Sep 17 00:00:00 2001 From: Souvik Chattopadhyay <schattop@lxbuild07.gsi.de> Date: Wed, 26 Mar 2025 16:22:15 +0100 Subject: [PATCH 04/11] binary file to compare different commit hash or weekly Ctest --- macro/qa/hist_compare_api | Bin 0 -> 54856 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100755 macro/qa/hist_compare_api diff --git a/macro/qa/hist_compare_api b/macro/qa/hist_compare_api new file mode 100755 index 0000000000000000000000000000000000000000..477c9bc9d974bc9c5476d4c5923feb80e21dc3f9 GIT binary patch literal 54856 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 YL$|AO!*G(Qe%&7>$8m8L;)>$`0<<zvVgLXD literal 0 HcmV?d00001 -- GitLab From 5510d46cc9bc7c85015f0ae04ca710f5065124de Mon Sep 17 00:00:00 2001 From: Souvik Chattopadhyay <souvik.c@vecc.gov.in> Date: Wed, 26 Mar 2025 16:33:35 +0100 Subject: [PATCH 05/11] shell script which can automatically change from one commit to another commit and create the output Ctest root file --- macro/qa/run_commit_out.sh | 63 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100755 macro/qa/run_commit_out.sh diff --git a/macro/qa/run_commit_out.sh b/macro/qa/run_commit_out.sh new file mode 100755 index 000000000..54a271126 --- /dev/null +++ b/macro/qa/run_commit_out.sh @@ -0,0 +1,63 @@ +#!/bin/bash +if [ "$#" -lt 2 ]; then + echo "Please Provide atleast two commit version" + exit 1 +fi + +run_comparison() { + work_dir=$(pwd) + local commit=$1 + local short_com1=$(echo "$1"| cut -c1-9) + local build_dir=$2 + + output_file="s100m3_qa_ts_eb_real_${short_com1}.qa.root" + if [ -f "$output_file" ]; then + echo "File $output_file exist" + return 0 + fi + echo "Checking out commit: $commit" + git checkout $commit || { echo "Failed to checkout $commit"; exit 1; } + + echo "Installing CBMRoot..." + ./install_cbmroot.sh || { echo "Installation failed"; exit 1; } + + echo "Running Ctest" + cd $build_dir + ctest -R run_s100m3_qa_ts_eb_real + cd macro/run/data + #old_name="s100m3_qa_ts_eb_real.qa.root" + #new_name="s100m3_qa_ts_eb_real_${short_com1}.qa.root" + cp s100m3_qa_ts_eb_real.qa.root ${work_dir}/s100m3_qa_ts_eb_real_${short_com1}.qa.root + echo "working dir : ${work_dir}" + cd $work_dir +} + +# Initialize variables +build_dir="/u/schattop/cbmroot_build/" +commits=() + +# Parse command-line arguments +while [[ $# -gt 0 ]]; do + case ${1} in + --build_dir) + build_dir=${2} + shift 2 + ;; + *) + commits+=("${1}") + shift + ;; + esac +done + +# Check if dataset is provided +if [[ -z "$build_dir" ]]; then + echo " running with default build dir" + #exit 1 +fi + +# Loop through all commits and run the comparison +for commit in "${commits[@]}"; do + echo "Processing commit: $commit" + run_comparison "$commit" "$build_dir" +done -- GitLab From c5737376f0353a83522331336fdf1515e6a2bab9 Mon Sep 17 00:00:00 2001 From: Souvik Chattopadhyay <souvik.c@vecc.gov.in> Date: Wed, 26 Mar 2025 17:19:15 +0100 Subject: [PATCH 06/11] updated binary with -config as input --- macro/qa/hist_compare_api | Bin 54856 -> 54856 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/macro/qa/hist_compare_api b/macro/qa/hist_compare_api index 477c9bc9d974bc9c5476d4c5923feb80e21dc3f9..3be66e84e291ac3c01a85ecd93d3794e8041c20f 100755 GIT binary patch delta 8604 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 TYUKH7XZwMOC+4*Cw;lcqd75Z( delta 8300 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 -- GitLab From 9d48be1198aced9a4d584949409b0e79255a519b Mon Sep 17 00:00:00 2001 From: Souvik Chattopadhyay <souvik.c@vecc.gov.in> Date: Thu, 27 Mar 2025 10:52:22 +0100 Subject: [PATCH 07/11] updated c++ macro --- macro/qa/Run_api_for_comparing_hist.C | 62 ++++++++++++++++++--------- 1 file changed, 42 insertions(+), 20 deletions(-) diff --git a/macro/qa/Run_api_for_comparing_hist.C b/macro/qa/Run_api_for_comparing_hist.C index 3800f00c5..5c8bad5ba 100644 --- a/macro/qa/Run_api_for_comparing_hist.C +++ b/macro/qa/Run_api_for_comparing_hist.C @@ -33,7 +33,7 @@ void updateYamlFile(const std::string &filePath, const std::vector<std::string> if(compareCommit1==true){ for (const auto &version : versionNames) { std::string label = version.substr(0, 9); - std::string path = srcDir + "/output_CA_" + label; + std::string path = srcDir + "/s100m3_qa_ts_eb_real_" + label+".qa"; modifiedYaml << " - label: \"" << label << "\"\n"; modifiedYaml << " path: \"" << path << "\"\n"; } @@ -128,15 +128,15 @@ int main(int argc, char* argv[]) { const char* configName = "objects2.yaml"; const char* outputName = "QACheckerOutput.root"; std::string scriptInput= "./run_commit_out.sh"; - std::string dataset = "default"; + std::string build_dir = "~/cbmroot_build"; bool defaultConfig= true; bool compareCommit= false; // std::ofstream yamlFile(configName); - if(argc<2){ - std::cerr<< "Please provide type of input(-chash or -wtest) and atleast two versions(commit hash or week number(yyyy_ww)"<<std::endl; + if(argc<1){ + std::cerr<< "Please provide type of input(-chash or -wtest) and atleast two versions(commit hash or week number(yyyy_ww). You may also provide config file(using -config), outputfile's name (using -output) and build directory (-build_dir) "<<std::endl; return 0; } @@ -150,8 +150,17 @@ int main(int argc, char* argv[]) { compareCommit = false; } +else if(args[1] == "-config"){ + + defaultConfig=0; + configName=args[1 + 1].c_str(); + for (size_t i = 0; i < args.size(); ++i) { + if(args[i]=="-output"){ + outputName=args[i + 1].c_str(); } + } +} - else{ +else{ std::cerr<< "No valid input available"<<std::endl; return 0; @@ -159,15 +168,15 @@ int main(int argc, char* argv[]) { } - +if(defaultConfig==1){ for (size_t i = 2; i < args.size(); ++i) { if(args[i]=="-config"){ - defaultConfig=0; + // defaultConfig=0; configName=args[i + 1].c_str(); break; } - else if(args[i]=="-output"){ + else if((args[i]=="-output") ||(args[i]=="-build_dir")){ break; } versionName.push_back(args[i]); @@ -183,32 +192,32 @@ for (size_t i = 2; i < args.size(); ++i) { } } for (size_t i = 2; i < args.size(); ++i) { - if(args[i]=="-dataset"){ + if(args[i]=="-build_dir"){ - dataset=args[i + 1]; + build_dir=args[i + 1]; break; } } // std::string yamlName =srcDir+"/configs/"+std::string(configName); // if(defaultConfig==1){ - std::string yamlName =srcDir+"/configs/"+std::string(configName); - if(compareCommit==true){ - std::string newFilePattern = "%v_%d.root"; // New pattern for files + std::string yamlName =srcDir+"/configs/"+std::string(configName); + if(compareCommit==true){ + std::string newFilePattern = "%v.root"; // New pattern for files - updateYamlFile(yamlName, versionName, srcDir, newFilePattern,compareCommit); - } - else{ - std::string newFilePattern = "%v.root"; // New pattern for files + updateYamlFile(yamlName, versionName, srcDir, newFilePattern,compareCommit); + } + else{ + std::string newFilePattern = "%v.root"; // New pattern for files - updateYamlFile(yamlName, versionName, srcDir, newFilePattern,compareCommit); - } + updateYamlFile(yamlName, versionName, srcDir, newFilePattern,compareCommit); + } if(compareCommit==true){ // Execute the script using system() std::cout << "Executing script to install commit hash: " << scriptInput << std::endl; - std::string scriptwithData=scriptInput+" --dataset "+dataset; + std::string scriptwithData=scriptInput+" --build_dir "+build_dir; int returnCode = std::system(scriptwithData.c_str()); if (returnCode != 0) { std::cerr << "Failed to execute:" <<scriptInput<< std::endl; @@ -238,6 +247,19 @@ std::string yamlName =srcDir+"/configs/"+std::string(configName); } } + } + else{ + std::string yamlName =srcDir+"/configs/"+std::string(configName); + std::string qacommand = std::string("root -l -q 'qa_compare_ca.C(\"") + yamlName + "\", \"" + outputName + "\")'"; + std::cout<<"Executing macro\t"<<qacommand<<std::endl; + int returnMacro = std::system(qacommand.c_str()); + if (returnMacro != 0) { + std::cerr << "Failed to execute: qa_compare_ca.C"<< std::endl; + return 1; + + + } + } -- GitLab From eb91e270f21e83ef9e395755d0005673722b506d Mon Sep 17 00:00:00 2001 From: Souvik Chattopadhyay <souvik.c@vecc.gov.in> Date: Mon, 7 Apr 2025 15:23:43 +0200 Subject: [PATCH 08/11] application added with a shell script for ctest --- macro/qa/run_ctest_commit.sh | 90 +++++++++++++++++++ services/CMakeLists.txt | 1 + services/qa/Application.cxx | 125 +++++++++++++++++++++++++++ services/qa/Application.h | 44 ++++++++++ services/qa/ApplicationParameter.cxx | 71 +++++++++++++++ services/qa/ApplicationParameter.h | 41 +++++++++ services/qa/CMakeLists.txt | 38 ++++++++ services/qa/ConfigEditor.cxx | 85 ++++++++++++++++++ services/qa/ConfigEditor.h | 37 ++++++++ services/qa/main.cxx | 23 +++++ 10 files changed, 555 insertions(+) create mode 100755 macro/qa/run_ctest_commit.sh create mode 100644 services/qa/Application.cxx create mode 100644 services/qa/Application.h create mode 100644 services/qa/ApplicationParameter.cxx create mode 100644 services/qa/ApplicationParameter.h create mode 100644 services/qa/CMakeLists.txt create mode 100644 services/qa/ConfigEditor.cxx create mode 100644 services/qa/ConfigEditor.h create mode 100644 services/qa/main.cxx diff --git a/macro/qa/run_ctest_commit.sh b/macro/qa/run_ctest_commit.sh new file mode 100755 index 000000000..f6187b1d9 --- /dev/null +++ b/macro/qa/run_ctest_commit.sh @@ -0,0 +1,90 @@ +#!/bin/bash + +run_comparison() { + local commit=$1 + local short_com1=$(echo "$1"| cut -c1-9) + local BUILD_DIR=$2 + local CURRENT_DIR=$3 + output_file1="${CURRENT_DIR}/s100m3_qa_ts_eb_real_${short_com1}.qa.root" + output_file2="${BUILD_DIR}/macro/run/data/s100m3_qa_ts_eb_real_${short_com1}.qa.root" + if [ -f "$output_file1" ]; then + echo "File ${output_file1} exist" + return 0 + elif [ -f "$output_file2" ]; then + echo "File ${output_file2} exist" + cp ${output_file2} ${output_file1} + return 0 + fi + cd ${VMCWORKDIR} + echo "Checking out commit: $commit" + git checkout $commit || { echo "Failed to checkout $commit"; exit 1; } + echo "Installing CBMRoot..." + ./install_cbmroot.sh || { echo "Installation failed"; exit 1; } + + echo "Running Ctest" + cd ${BUILD_DIR} + ctest -R run_s100m3_qa_ts_eb_real + cd ${BUILD_DIR}/macro/run/data + cp s100m3_qa_ts_eb_real.qa.root ${CURRENT_DIR}/s100m3_qa_ts_eb_real_${short_com1}.qa.root + cd ${VMCWORKDIR} +} + +# Initialize variables + +# Save the current branch +current_branch=$(git rev-parse --abbrev-ref HEAD) + + +WORK_DIR=${VMCWORKDIR} + +BUILD_DIR=${VMCWORKDIR}/../cbmroot_build/ + +commits=() + +CURRENT_DIR="" + +# Parse command-line arguments +while [[ $# -gt 0 ]]; do + case ${1} in + --build_dir) + BUILD_DIR=${2} + shift 2 + ;; + --current_dir) + CURRENT_DIR=${2} + shift 2 + ;; + *) + commits+=("${1}") + shift + ;; + esac +done +if [[ ! -d "${BUILD_DIR}" ]]; then + BUILD_DIR="${VMCWORKDIR}/build" + if [[ ! -d "${BUILD_DIR}" ]]; then + printf "E- cbmroot_build directory was not found. Please:\n" + printf " - provide the build directory in the command line" + exit 2 + + fi +fi + + +# Loop through all commits and run the comparison +for commit in "${commits[@]}"; do + echo "Processing commit: $commit" + run_comparison "${commit}" "${BUILD_DIR}" "${CURRENT_DIR}" +done + +# Get the final branch you want to checkout +desired_branch=$(git rev-parse --abbrev-ref HEAD) + +# Check if the current branch is the same as the desired branch +if [ "$current_branch" != "$desired_branch" ]; then + echo "Checking out the original branch: $desired_branch" + git checkout $desired_branch || { echo "Failed to checkout $desired_branch"; exit 1; } + ./install_cbmroot.sh || { echo "Installation failed"; exit 1; } +else + echo "Already on the initial branch: $current_branch. Skipping checkout and installation." +fi diff --git a/services/CMakeLists.txt b/services/CMakeLists.txt index db898cd63..23b962b62 100644 --- a/services/CMakeLists.txt +++ b/services/CMakeLists.txt @@ -3,3 +3,4 @@ add_subdirectory(histserv) add_subdirectory(online_par_dump) add_subdirectory(tsa_dump) add_subdirectory(run_info) +add_subdirectory(qa) diff --git a/services/qa/Application.cxx b/services/qa/Application.cxx new file mode 100644 index 000000000..a8ca45968 --- /dev/null +++ b/services/qa/Application.cxx @@ -0,0 +1,125 @@ +#include "Application.h" +#include <iostream> +#include <map> +#include <memory> +#include <sstream> +#include <unistd.h> // for getcwd() +#include <limits.h> // for PATH_MAX + +/** @brief Helper: get current working directory without filesystem **/ +std::string getCurrentDir() { + char buffer[PATH_MAX]; + if (getcwd(buffer, sizeof(buffer)) != nullptr) { + return std::string(buffer); + } else { + perror("getcwd() error"); + return ""; + } +} + +/** @brief Constructor: Initializes the application with program options **/ +Application::Application(ApplicationParameter const& opt) { + std::string compareType = opt.getCompare(); + std::vector<std::string> names = opt.getNames(); + + configFileName = opt.getConfig(); + outputFileName = opt.getOutput(); + + ConfigEditor config(configFileName); + + if (compareType == "commit") { + citest(names, opt.getbuilddir()); + addVersionCommit(config, names); + config.setDatasets({"default"}); + std::string currentDir = getCurrentDir(); + addFile(config, currentDir +"/%v.root", "qa_commit", {}); + } + + + else if (compareType == "weeklyTest") { + addVersionWeeklyTest(config, names); + config.setDatasets({"default"}); + addFile(config, "%v.root", "qa_weekly", {}); + } + + else { + std::cerr << "Unknown compare type: " << compareType << std::endl; + } + + config.saveConfig(opt.getConfig()); + exec("E"); +} + +/** @brief Adds commit versions to the configuration **/ +void Application::addVersionCommit(ConfigEditor& config, const std::vector<std::string>& names) { + std::map<std::string, std::string> versions; + for (const std::string& name : names) { + std::string label = name.substr(0, 9); + std::string path = "s100m3_qa_ts_eb_real_" + label + ".qa"; + versions[label] = path; + } + config.setVersions(versions); +} + +/** @brief Adds weekly test versions to the configuration **/ +void Application::addVersionWeeklyTest(ConfigEditor& config, const std::vector<std::string>& names) { + std::map<std::string, std::string> versions; + for (const std::string& name : names) { + std::string path = "/lustre/cbm/users/ploizeau/cdash/weekly_virgo3_vae23_dev_" + name + "/macro/run/data/s100h_qa_ts_eb_ideal.qa"; + versions[name] = path; + } + config.setVersions(versions); +} + +/** @brief Adds a file with specified format and label **/ +void Application::addFile(ConfigEditor& config, std::string fileformat, std::string labelformat, const std::vector<std::string>& objects) { + std::vector<std::tuple<std::string, std::string, std::vector<std::string>>> files; + files.emplace_back(fileformat, labelformat, objects); + config.setFiles(files); +} + +/** @brief Run shell script for CI test with different commit **/ +void Application::citest(const std::vector<std::string>& names, std::string builddir) { + std::ostringstream cmd; + const char* vmworkdir = getenv("VMWORKDIR"); + if (vmworkdir != nullptr) { + + cmd << vmworkdir << "/macro/qa/run_ctest_commit.sh"; + //int ret = system(cmd.str().c_str()); + + + //cmd << "${VMWORKDIR}/macro/qa/run_ctest_commit.sh"; + + for (const auto& name : names) { + cmd << " " << name; + } + + if (!builddir.empty()) { + cmd << " --build_dir " << builddir; + } + + // Add current directory + std::string currentDir = getCurrentDir(); + cmd << " --current_dir " << currentDir; + + std::string finalCmd = cmd.str(); + std::cout << "Executing: " << finalCmd << std::endl; + + int ret = system(finalCmd.c_str()); + + if (ret != 0) { + std::cerr << "Script failed with return code: " << ret << std::endl; + } + } + else{ + std::cerr << "VMWORKDIR not set in environment!" << std::endl; + } +} + +/** @brief Executes the comparison routine with an optional parameter **/ +void Application::exec(Option_t* option) { + auto pChecker = std::make_unique<cbm::qa::checker::Core>(); + pChecker->RegisterOutFile(outputFileName.c_str()); + pChecker->SetFromYAML(configFileName.c_str()); + pChecker->Process(option); +} diff --git a/services/qa/Application.h b/services/qa/Application.h new file mode 100644 index 000000000..d1abf4926 --- /dev/null +++ b/services/qa/Application.h @@ -0,0 +1,44 @@ +#ifndef APPLICATION_H +#define APPLICATION_H + +#include "ConfigEditor.h" +#include "ApplicationParameter.h" +#include <vector> +#include <string> +#include <map> +#include <memory> // For std::unique_ptr +#include "CbmQaCheckerCore.h" + +class Application { +public: + /** @brief Constructor: Initializes the application with program options **/ + explicit Application(ApplicationParameter const& opt); + + /** @brief Executes the comparison routine with an optional parameter **/ + void exec(Option_t* option = "E"); + +private: + /** @brief Adds commit versions to the configuration **/ + void addVersionCommit(ConfigEditor& config, const std::vector<std::string>& names); + + /** @brief Adds weekly test versions to the configuration **/ + void addVersionWeeklyTest(ConfigEditor& config, const std::vector<std::string>& names); + + /** @brief Adds a file with specified format and label to the configaration **/ + void addFile(ConfigEditor& config, std::string fileformat, std::string labelformat, const std::vector<std::string>& objects); + + + + void citest(const std::vector<std::string>& names, std::string builddir = ""); + + + + /** @brief Unique pointer to Checker **/ + // std::unique_ptr<cbm::qa::checker::Core> pChecker; + + + std::string configFileName; + std::string outputFileName; +}; + +#endif // APPLICATION_H diff --git a/services/qa/ApplicationParameter.cxx b/services/qa/ApplicationParameter.cxx new file mode 100644 index 000000000..82ad18404 --- /dev/null +++ b/services/qa/ApplicationParameter.cxx @@ -0,0 +1,71 @@ +#include "ApplicationParameter.h" +#include <iostream> + +namespace po = boost::program_options; + +/** @brief Constructor: Parses command-line arguments **/ +ApplicationParameter::ApplicationParameter(int argc, char* argv[]) { + parseCommandLine(argc, argv); +} + +/** @brief Parses command-line arguments **/ +void ApplicationParameter::parseCommandLine(int argc, char* argv[]) { + try { + // Define command-line options + po::options_description desc("Allowed options"); + desc.add_options() + ("help,h", "Display help message") + ("compare,t", po::value<std::string>(&fcompare)->required()->value_name("commit"), + "Specify comparison type (only 'commit' or 'weeklyTest' are allowed)") + ("names,n", po::value<std::vector<std::string>>(&fnames)->multitoken()->value_name("<name1 name2 ...>"), + "List of commit hash or week numbers(yyyy_ww)") + ("output,o", po::value<std::string>(&foutput)->default_value("./output_compare_qa.root"), + "Specify output file name") + ("config,c", po::value<std::string>(&fconfig)->default_value("./objects.yaml"), + "Specify config file") + ("builddir,b", po::value<std::string>(&fbuilddir)->default_value(""), + "Specify cbmroot build directory"); + + // Parse command-line arguments + po::variables_map vars; + po::store(po::parse_command_line(argc, argv, desc), vars); + + // Handle help request + if (vars.count("help")) { + std::cout << desc << std::endl; + exit(EXIT_SUCCESS); + } + + // Apply required options + po::notify(vars); + + // Validate "--compare" option (only "commit" or "weeklyTest" allowed) + if ((fcompare != "commit") && (fcompare != "weeklyTest")) { + throw po::validation_error(po::validation_error::invalid_option_value, "compare", fcompare); + } + + } catch (const po::error& e) { + std::cerr << "Error: " << e.what() << std::endl; + exit(EXIT_FAILURE); + } +} + +/** @brief Getters for parsed options **/ +std::string ApplicationParameter::getCompare() const { + return fcompare; +} + +std::vector<std::string> ApplicationParameter::getNames() const { + return fnames; +} + +std::string ApplicationParameter::getOutput() const { + return foutput; +} + +std::string ApplicationParameter::getConfig() const { + return fconfig; +} +std::string ApplicationParameter::getbuilddir() const { + return fbuilddir; +} diff --git a/services/qa/ApplicationParameter.h b/services/qa/ApplicationParameter.h new file mode 100644 index 000000000..4b28fbef0 --- /dev/null +++ b/services/qa/ApplicationParameter.h @@ -0,0 +1,41 @@ +#ifndef APPLICATION_PARAMETER_H +#define APPLICATION_PARAMETER_H + +#include <boost/program_options.hpp> +#include <string> +#include <vector> + +class ApplicationParameter { +public: + /** @brief Constructor: Parses command-line arguments **/ + ApplicationParameter(int argc, char* argv[]); + + + + /** @brief Default copy constructor **/ + ApplicationParameter(const ApplicationParameter&) = default; + + /** @brief Default assignment operator **/ + ApplicationParameter& operator=(const ApplicationParameter&) = default; + + /** @brief Getters for parsed options **/ + std::string getCompare() const; + std::vector<std::string> getNames() const; + std::string getOutput() const; + std::string getConfig() const; + std::string getbuilddir() const; + +private: + /** @brief Parses command-line arguments **/ + void parseCommandLine(int argc, char* argv[]); + + // Variables to store parsed command-line arguments + std::string fcompare; + std::vector<std::string> fnames; + std::string foutput; + std::string fconfig; + std::string fbuilddir; + +}; + +#endif // APPLICATION_PARAMETER_H diff --git a/services/qa/CMakeLists.txt b/services/qa/CMakeLists.txt new file mode 100644 index 000000000..3fd0fd991 --- /dev/null +++ b/services/qa/CMakeLists.txt @@ -0,0 +1,38 @@ +set(INCLUDE_DIRECTORIES + ${INCLUDE_DIRECTORIES} + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_SOURCE_DIR}/core/qa + ) +# Source files +set(SRCS + main.cxx + Application.cxx + ConfigEditor.cxx + ApplicationParameter.cxx +) + +# Header files +set(HEADERS + Application.h + ConfigEditor.h + ApplicationParameter.h +) + +set(INCLUDE_DIRECTORIES + ${INCLUDE_DIRECTORIES} + ${CBMROOT_SOURCE_DIR} + ) + + + +add_executable(qachecker ${SRCS} ${HEADERS}) + +target_link_libraries(qachecker + PUBLIC + CbmQaBase + PRIVATE + Boost::program_options + FairLogger::FairLogger + external::yaml-cpp +) +install(TARGETS qachecker DESTINATION bin) diff --git a/services/qa/ConfigEditor.cxx b/services/qa/ConfigEditor.cxx new file mode 100644 index 000000000..229e8f2e0 --- /dev/null +++ b/services/qa/ConfigEditor.cxx @@ -0,0 +1,85 @@ +#include "ConfigEditor.h" +#include <iostream> +#include <fstream> +/** @brief Constructor: Loads the YAML file **/ +ConfigEditor::ConfigEditor(const std::string& configFile) { + if (std::ifstream(configFile)) { + LoadConfig(configFile); + } + else{ + setDefault(); + } +} + +/** @brief Load YAML configuration **/ +void ConfigEditor::LoadConfig(const std::string& configFile) { + try { + yamlData = YAML::LoadFile(configFile); + } catch (const std::exception& e) { + std::cerr << "Error loading YAML file: " << e.what() << std::endl; + } +} +/** @brief default YAML configuration **/ + +void ConfigEditor::setDefault() { + + yamlData["checker"]["settings"]["ratio_min"] = 0.90; + yamlData["checker"]["settings"]["ratio_max"] = 1.10; + yamlData["checker"]["settings"]["pval_threshold"] = 0.01; +} + + +/** @brief Set new versions **/ +void ConfigEditor::setVersions(const std::map<std::string, std::string>& newVersions) { + yamlData["checker"]["versions"] = YAML::Node(YAML::NodeType::Sequence); + for (const auto& [label, path] : newVersions) { + YAML::Node versionNode; + versionNode["label"] = label; + versionNode["path"] = path; + yamlData["checker"]["versions"].push_back(versionNode); + } +} + +/** @brief Set new dataset names **/ +void ConfigEditor::setDatasets(const std::vector<std::string>& newDatasets) { + yamlData["checker"]["datasets"] = YAML::Node(YAML::NodeType::Sequence); + for (const auto& dataset : newDatasets) { + yamlData["checker"]["datasets"].push_back(dataset); + } +} + +/** @brief Set new files with labels **/ +void ConfigEditor::setFiles(const std::vector<std::tuple<std::string, std::string, std::vector<std::string>>>& newFiles) { + yamlData["checker"]["files"] = YAML::Node(YAML::NodeType::Sequence); + for (const auto& [name, label, objects] : newFiles) { + YAML::Node fileNode; + fileNode["name"] = name; + fileNode["label"] = label; // Always add the label + + // Only add "objects" node if the objects vector is non-empty + if (!objects.empty()) { + YAML::Node objectsNode(YAML::NodeType::Sequence); + for (const auto& obj : objects) { + objectsNode.push_back(obj); + } + fileNode["objects"] = objectsNode; + } + + yamlData["checker"]["files"].push_back(fileNode); + } +} + +/** @brief Save the modified YAML file **/ +void ConfigEditor::saveConfig(const std::string& configFile) const { + if (!configFile.empty() && yamlData.IsDefined()) { + std::ofstream outFile(configFile); + if (outFile.is_open()) { + outFile << yamlData; + outFile.close(); + } else { + std::cerr << "Error: Unable to open file for saving!" << std::endl; + } + } else { + std::cerr << "Error: No config file specified or YAML data is empty!" << std::endl; + } +} diff --git a/services/qa/ConfigEditor.h b/services/qa/ConfigEditor.h new file mode 100644 index 000000000..9bdf1dc1d --- /dev/null +++ b/services/qa/ConfigEditor.h @@ -0,0 +1,37 @@ +#ifndef CONFIG_EDITOR_H +#define CONFIG_EDITOR_H + +#include <yaml-cpp/yaml.h> +#include <string> +#include <vector> +#include <map> + +class ConfigEditor { +public: + /** @brief Constructor **/ + explicit ConfigEditor(const std::string& configFile = ""); + + /** @brief Load YAML configuration **/ + void LoadConfig(const std::string& configFile); + + /** @brief Load default configuration **/ + void setDefault(); + + /** @brief Set and update version information **/ + void setVersions(const std::map<std::string, std::string>& newVersions); + + /** @brief Set and update dataset names **/ + void setDatasets(const std::vector<std::string>& newDatasets); + + /** @brief Set and update files **/ + void setFiles(const std::vector<std::tuple<std::string, std::string, std::vector<std::string>>>& newFiles); + + /** @brief Save the modified YAML configuration **/ + void saveConfig(const std::string& configFile) const; + +private: + YAML::Node yamlData; // Stores the configuration data + +}; + +#endif // CONFIG_EDITOR_H diff --git a/services/qa/main.cxx b/services/qa/main.cxx new file mode 100644 index 000000000..829bef04b --- /dev/null +++ b/services/qa/main.cxx @@ -0,0 +1,23 @@ +#include "Application.h" +#include "ApplicationParameter.h" +#include <iostream> + +int main(int argc, char* argv[]) { + try { + // Parse command-line arguments + ApplicationParameter opt(argc, argv); + + // Create the Application instance + Application app(opt); + + // Execute the comparison process with a default option + //app.exec("E"); + + // Return the process result + //return result; + } + catch (const std::exception& e) { + std::cerr << "Error: " << e.what() << std::endl; + return EXIT_FAILURE; + } +} -- GitLab From 2e88e52f9a343bd8bc1be5b083c50aad852cf7ba Mon Sep 17 00:00:00 2001 From: Souvik Chattopadhyay <souvik.c@vecc.gov.in> Date: Mon, 7 Apr 2025 16:33:43 +0200 Subject: [PATCH 09/11] deleted the previous cpp macro --- macro/qa/Run_api_for_comparing_hist.C | 266 -------------------------- 1 file changed, 266 deletions(-) delete mode 100644 macro/qa/Run_api_for_comparing_hist.C diff --git a/macro/qa/Run_api_for_comparing_hist.C b/macro/qa/Run_api_for_comparing_hist.C deleted file mode 100644 index 5c8bad5ba..000000000 --- a/macro/qa/Run_api_for_comparing_hist.C +++ /dev/null @@ -1,266 +0,0 @@ -#include <iostream> -#include <vector> -#include <string> -#include <fstream> -#include <unistd.h> -#include <cstddef> -#include <sstream> -void updateYamlFile(const std::string &filePath, const std::vector<std::string> &versionNames, - const std::string &srcDir, const std::string &newFilePattern, bool compareCommit1) { - std::ifstream file(filePath); - if (!file) { - std::cerr << "Error: Unable to open file " << filePath << std::endl; - return; - } - - std::ostringstream modifiedYaml; - std::string line; - bool inVersions = false, inDatasets = false, inFiles = false; - - while (std::getline(file, line)) { - // Trim leading spaces (YAML indentation) - std::string trimmedLine = line; - trimmedLine.erase(0, trimmedLine.find_first_not_of(" \t")); - - // Identify sections - if (trimmedLine.find("versions:") == 0) { - inVersions = true; - inDatasets = false; - inFiles = false; - modifiedYaml << line << "\n"; // Keep the "versions:" header - - // Add new versions dynamically - if(compareCommit1==true){ - for (const auto &version : versionNames) { - std::string label = version.substr(0, 9); - std::string path = srcDir + "/s100m3_qa_ts_eb_real_" + label+".qa"; - modifiedYaml << " - label: \"" << label << "\"\n"; - modifiedYaml << " path: \"" << path << "\"\n"; - } - } - else{ - for (const auto &version : versionNames) { - //std::string version=versionName[iv]; - std::size_t pos = version.find('_'); - - // Extract the year and week number - std::string YEAR_ISO = version.substr(0, pos); - std::string WEEK_ISO = version.substr(pos + 1); - std::string path = "/lustre/cbm/users/ploizeau/cdash/weekly_virgo3_vae23_dev_" + YEAR_ISO +"_" + WEEK_ISO + "/macro/run/data/s100h_qa_ts_eb_ideal.\ -qa"; - std::string label = version; - - - modifiedYaml << " - label: \"" << label << "\"\n"; - modifiedYaml << " path: \"" << path << "\"\n"; - } - - - - } - continue; // Skip original version entries - } - - if (trimmedLine.find("datasets:") == 0) { - inDatasets = true; - inVersions = false; - inFiles = false; - } else if (trimmedLine.find("files:") == 0) { - inFiles = true; - inVersions = false; - inDatasets = false; - } - - // Skip old "versions:" content - if (inVersions && (trimmedLine.find("- label:") == 0 || trimmedLine.find("path:") == 0)) { - continue; - } - - // Replace file pattern inside "files:" - if (inFiles && trimmedLine.find("- name:") == 0) { - - modifiedYaml << " - name: \"" << newFilePattern << "\"\n"; // Replace with new pattern - - continue; - } - - // Preserve other sections as-is - modifiedYaml << line << "\n"; - } - - file.close(); - - // Write the updated content back to the file - std::ofstream outFile(filePath); - if (!outFile) { - std::cerr << "Error: Unable to write to file " << filePath << std::endl; - return; - } - outFile << modifiedYaml.str(); - outFile.close(); - - // std::cout << "YAML file updated successfully!" << std::endl; -} - - - - - - -int main(int argc, char* argv[]) { - std::vector<std::string> args(argv, argv + argc); - /*for(int i=0;i<args.size();i++){ - - std::cout<<args[i]<<std::endl; - - }*/ - char buffer[1024]; - if (getcwd(buffer, sizeof(buffer)) == nullptr) { - //std::cerr << "Error: " << strerror(errno) << std::endl; - return 1; - } - - std::string srcDir(buffer); - std::cout<<"Current Directory:\t"<<srcDir<<std::endl; - // std::string srcDir = std::filesystem::current_path().string(); - std::vector<std::string> versionName; - - const char* configName = "objects2.yaml"; - const char* outputName = "QACheckerOutput.root"; - std::string scriptInput= "./run_commit_out.sh"; - std::string build_dir = "~/cbmroot_build"; - bool defaultConfig= true; - bool compareCommit= false; - // std::ofstream yamlFile(configName); - - - - if(argc<1){ - std::cerr<< "Please provide type of input(-chash or -wtest) and atleast two versions(commit hash or week number(yyyy_ww). You may also provide config file(using -config), outputfile's name (using -output) and build directory (-build_dir) "<<std::endl; - return 0; - } - - - if (args[1] == "-chash") {//for comparision of differnt commit - compareCommit = true; - - } - else if(args[1] == "-wtest"){//for comparision of weekly test - - - compareCommit = false; - } -else if(args[1] == "-config"){ - - defaultConfig=0; - configName=args[1 + 1].c_str(); - for (size_t i = 0; i < args.size(); ++i) { - if(args[i]=="-output"){ - outputName=args[i + 1].c_str(); } - } -} - -else{ - - std::cerr<< "No valid input available"<<std::endl; - return 0; - - } - - -if(defaultConfig==1){ - -for (size_t i = 2; i < args.size(); ++i) { - if(args[i]=="-config"){ - // defaultConfig=0; - configName=args[i + 1].c_str(); - break; - } - else if((args[i]=="-output") ||(args[i]=="-build_dir")){ - break; - } - versionName.push_back(args[i]); - scriptInput += " " + args[i]; - - } - - for (size_t i = 2; i < args.size(); ++i) { - if(args[i]=="-output"){ - - outputName=args[i + 1].c_str(); - break; - } - } - for (size_t i = 2; i < args.size(); ++i) { - if(args[i]=="-build_dir"){ - - build_dir=args[i + 1]; - break; - } - } - // std::string yamlName =srcDir+"/configs/"+std::string(configName); - // if(defaultConfig==1){ - std::string yamlName =srcDir+"/configs/"+std::string(configName); - if(compareCommit==true){ - std::string newFilePattern = "%v.root"; // New pattern for files - - updateYamlFile(yamlName, versionName, srcDir, newFilePattern,compareCommit); - } - else{ - std::string newFilePattern = "%v.root"; // New pattern for files - - updateYamlFile(yamlName, versionName, srcDir, newFilePattern,compareCommit); - } - - - if(compareCommit==true){ - - // Execute the script using system() - std::cout << "Executing script to install commit hash: " << scriptInput << std::endl; - std::string scriptwithData=scriptInput+" --build_dir "+build_dir; - int returnCode = std::system(scriptwithData.c_str()); - if (returnCode != 0) { - std::cerr << "Failed to execute:" <<scriptInput<< std::endl; - return 1; - } - std::string yamlName =srcDir+"/configs/"+std::string(configName); - std::string qacommand = std::string("root -l -q 'qa_compare_ca.C(\"") + yamlName + "\", \"" + outputName + "\")'"; - std::cout<<"Executing macro\t"<<qacommand<<std::endl; - int returnMacro = std::system(qacommand.c_str()); - if (returnMacro = 0) { - std::cerr << "Failed to execute: qa_compare_ca.C"<< std::endl; - return 1; - } - - - - } - else{ -std::string yamlName =srcDir+"/configs/"+std::string(configName); - std::string qacommand = std::string("root -l -q 'qa_compare_ca.C(\"") + yamlName + "\", \"" + outputName + "\")'"; - std::cout<<"Executing macro\t"<<qacommand<<std::endl; - int returnMacro = std::system(qacommand.c_str()); - if (returnMacro != 0) { - std::cerr << "Failed to execute: qa_compare_ca.C"<< std::endl; - return 1; - - } - - } - } - else{ - std::string yamlName =srcDir+"/configs/"+std::string(configName); - std::string qacommand = std::string("root -l -q 'qa_compare_ca.C(\"") + yamlName + "\", \"" + outputName + "\")'"; - std::cout<<"Executing macro\t"<<qacommand<<std::endl; - int returnMacro = std::system(qacommand.c_str()); - if (returnMacro != 0) { - std::cerr << "Failed to execute: qa_compare_ca.C"<< std::endl; - return 1; - - - } - } - - - -} -- GitLab From 353849ae5fd2d7a74131e2964ecaa3dea4d5ac24 Mon Sep 17 00:00:00 2001 From: Souvik Chattopadhyay <souvik.c@vecc.gov.in> Date: Mon, 7 Apr 2025 17:19:31 +0200 Subject: [PATCH 10/11] Apply clang-format removed hist_compare_api binary applied clang-format applied clang-format after rebaseing removed macro/qa/run_commit_out.sh updated the function name with upper case in configEditor.h updated all .cxx and .h file with licence header removed artifacts of the rebase in analysis/PWGDIL/dielectron/conversion/CbmAnaConversion.cxx and sim/detectors/fsd/CbmFsdDigitize.cxx applied clang-format and added external lib which was deleted --- .../conversion/CbmAnaConversion.cxx | 2 +- .../papaframework/PairAnalysisPairKF.cxx | 2 + external/InstallParameter.cmake | 9 + macro/qa/hist_compare_api | Bin 54856 -> 0 bytes macro/qa/run_commit_out.sh | 63 ------- services/qa/Application.cxx | 167 ++++++++++-------- services/qa/Application.h | 56 +++--- services/qa/ApplicationParameter.cxx | 106 ++++++----- services/qa/ApplicationParameter.h | 67 +++---- services/qa/ConfigEditor.cxx | 133 +++++++------- services/qa/ConfigEditor.h | 52 +++--- services/qa/main.cxx | 36 ++-- 12 files changed, 347 insertions(+), 346 deletions(-) create mode 100644 external/InstallParameter.cmake delete mode 100755 macro/qa/hist_compare_api delete mode 100755 macro/qa/run_commit_out.sh diff --git a/analysis/PWGDIL/dielectron/conversion/CbmAnaConversion.cxx b/analysis/PWGDIL/dielectron/conversion/CbmAnaConversion.cxx index e7b6fcdd3..5495d5739 100644 --- a/analysis/PWGDIL/dielectron/conversion/CbmAnaConversion.cxx +++ b/analysis/PWGDIL/dielectron/conversion/CbmAnaConversion.cxx @@ -64,7 +64,7 @@ #define M2E 2.6112004954086e-7 -using namespace std; + using namespace std; using boost::assign::list_of; CbmAnaConversion::CbmAnaConversion() diff --git a/analysis/PWGDIL/dielectron/papaframework/PairAnalysisPairKF.cxx b/analysis/PWGDIL/dielectron/papaframework/PairAnalysisPairKF.cxx index 0579a7755..e79f053bf 100644 --- a/analysis/PWGDIL/dielectron/papaframework/PairAnalysisPairKF.cxx +++ b/analysis/PWGDIL/dielectron/papaframework/PairAnalysisPairKF.cxx @@ -21,6 +21,8 @@ #include "PairAnalysisMC.h" #include "PairAnalysisTrack.h" +#include <TDatabasePDG.h> + ClassImp(PairAnalysisPairKF) PairAnalysisPairKF::PairAnalysisPairKF() diff --git a/external/InstallParameter.cmake b/external/InstallParameter.cmake new file mode 100644 index 000000000..8915b4595 --- /dev/null +++ b/external/InstallParameter.cmake @@ -0,0 +1,9 @@ +set(PARAMETER_VERSION fc402a25347c5a9f8df60fea216054d414df1321) # 2025/04/07 +set(PARAMETER_SRC_URL "https://git.cbm.gsi.de/CbmSoft/cbmroot_parameter.git") + +download_project_if_needed(PROJECT Parameter_source + GIT_REPOSITORY ${PARAMETER_SRC_URL} + GIT_TAG ${PARAMETER_VERSION} + SOURCE_DIR ${CMAKE_SOURCE_DIR}/parameters + TEST_FILE sts/LandauWidthTable.txt + ) diff --git a/macro/qa/hist_compare_api b/macro/qa/hist_compare_api deleted file mode 100755 index 3be66e84e291ac3c01a85ecd93d3794e8041c20f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 54856 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 diff --git a/macro/qa/run_commit_out.sh b/macro/qa/run_commit_out.sh deleted file mode 100755 index 54a271126..000000000 --- a/macro/qa/run_commit_out.sh +++ /dev/null @@ -1,63 +0,0 @@ -#!/bin/bash -if [ "$#" -lt 2 ]; then - echo "Please Provide atleast two commit version" - exit 1 -fi - -run_comparison() { - work_dir=$(pwd) - local commit=$1 - local short_com1=$(echo "$1"| cut -c1-9) - local build_dir=$2 - - output_file="s100m3_qa_ts_eb_real_${short_com1}.qa.root" - if [ -f "$output_file" ]; then - echo "File $output_file exist" - return 0 - fi - echo "Checking out commit: $commit" - git checkout $commit || { echo "Failed to checkout $commit"; exit 1; } - - echo "Installing CBMRoot..." - ./install_cbmroot.sh || { echo "Installation failed"; exit 1; } - - echo "Running Ctest" - cd $build_dir - ctest -R run_s100m3_qa_ts_eb_real - cd macro/run/data - #old_name="s100m3_qa_ts_eb_real.qa.root" - #new_name="s100m3_qa_ts_eb_real_${short_com1}.qa.root" - cp s100m3_qa_ts_eb_real.qa.root ${work_dir}/s100m3_qa_ts_eb_real_${short_com1}.qa.root - echo "working dir : ${work_dir}" - cd $work_dir -} - -# Initialize variables -build_dir="/u/schattop/cbmroot_build/" -commits=() - -# Parse command-line arguments -while [[ $# -gt 0 ]]; do - case ${1} in - --build_dir) - build_dir=${2} - shift 2 - ;; - *) - commits+=("${1}") - shift - ;; - esac -done - -# Check if dataset is provided -if [[ -z "$build_dir" ]]; then - echo " running with default build dir" - #exit 1 -fi - -# Loop through all commits and run the comparison -for commit in "${commits[@]}"; do - echo "Processing commit: $commit" - run_comparison "$commit" "$build_dir" -done diff --git a/services/qa/Application.cxx b/services/qa/Application.cxx index a8ca45968..073432a26 100644 --- a/services/qa/Application.cxx +++ b/services/qa/Application.cxx @@ -1,101 +1,119 @@ +/* Copyright (C) 2025 GSI/VECC, Darmstadt/Kolkata + SPDX-License-Identifier: GPL-3.0-only + Authors: Souvik Chattopadhyay[committer], Sergei Zharko */ + + + + #include "Application.h" + #include <iostream> #include <map> #include <memory> #include <sstream> -#include <unistd.h> // for getcwd() -#include <limits.h> // for PATH_MAX + +#include <limits.h> // for PATH_MAX +#include <unistd.h> // for getcwd() /** @brief Helper: get current working directory without filesystem **/ -std::string getCurrentDir() { - char buffer[PATH_MAX]; - if (getcwd(buffer, sizeof(buffer)) != nullptr) { - return std::string(buffer); - } else { - perror("getcwd() error"); - return ""; - } +std::string getCurrentDir() +{ + char buffer[PATH_MAX]; + if (getcwd(buffer, sizeof(buffer)) != nullptr) { + return std::string(buffer); + } + else { + perror("getcwd() error"); + return ""; + } } /** @brief Constructor: Initializes the application with program options **/ -Application::Application(ApplicationParameter const& opt) { - std::string compareType = opt.getCompare(); - std::vector<std::string> names = opt.getNames(); +Application::Application(ApplicationParameter const& opt) +{ + std::string compareType = opt.getCompare(); + std::vector<std::string> names = opt.getNames(); - configFileName = opt.getConfig(); - outputFileName = opt.getOutput(); + configFileName = opt.getConfig(); + outputFileName = opt.getOutput(); - ConfigEditor config(configFileName); + ConfigEditor config(configFileName); - if (compareType == "commit") { - citest(names, opt.getbuilddir()); - addVersionCommit(config, names); - config.setDatasets({"default"}); - std::string currentDir = getCurrentDir(); - addFile(config, currentDir +"/%v.root", "qa_commit", {}); - } + if (compareType == "commit") { + citest(names, opt.getbuilddir()); + addVersionCommit(config, names); + config.setDatasets({"default"}); + std::string currentDir = getCurrentDir(); + addFile(config, currentDir + "/%v.root", "qa_commit", {}); + } - else if (compareType == "weeklyTest") { - addVersionWeeklyTest(config, names); - config.setDatasets({"default"}); - addFile(config, "%v.root", "qa_weekly", {}); - } - - else { - std::cerr << "Unknown compare type: " << compareType << std::endl; - } + else if (compareType == "weeklyTest") { + addVersionWeeklyTest(config, names); + config.setDatasets({"default"}); + addFile(config, "%v.root", "qa_weekly", {}); + } - config.saveConfig(opt.getConfig()); - exec("E"); + else { + std::cerr << "Unknown compare type: " << compareType << std::endl; + } + + config.saveConfig(opt.getConfig()); + exec("E"); } /** @brief Adds commit versions to the configuration **/ -void Application::addVersionCommit(ConfigEditor& config, const std::vector<std::string>& names) { - std::map<std::string, std::string> versions; - for (const std::string& name : names) { - std::string label = name.substr(0, 9); - std::string path = "s100m3_qa_ts_eb_real_" + label + ".qa"; - versions[label] = path; - } - config.setVersions(versions); +void Application::addVersionCommit(ConfigEditor& config, const std::vector<std::string>& names) +{ + std::map<std::string, std::string> versions; + for (const std::string& name : names) { + std::string label = name.substr(0, 9); + std::string path = "s100m3_qa_ts_eb_real_" + label + ".qa"; + versions[label] = path; + } + config.setVersions(versions); } /** @brief Adds weekly test versions to the configuration **/ -void Application::addVersionWeeklyTest(ConfigEditor& config, const std::vector<std::string>& names) { - std::map<std::string, std::string> versions; - for (const std::string& name : names) { - std::string path = "/lustre/cbm/users/ploizeau/cdash/weekly_virgo3_vae23_dev_" + name + "/macro/run/data/s100h_qa_ts_eb_ideal.qa"; - versions[name] = path; - } - config.setVersions(versions); +void Application::addVersionWeeklyTest(ConfigEditor& config, const std::vector<std::string>& names) +{ + std::map<std::string, std::string> versions; + for (const std::string& name : names) { + std::string path = + "/lustre/cbm/users/ploizeau/cdash/weekly_virgo3_vae23_dev_" + name + "/macro/run/data/s100h_qa_ts_eb_ideal.qa"; + versions[name] = path; + } + config.setVersions(versions); } /** @brief Adds a file with specified format and label **/ -void Application::addFile(ConfigEditor& config, std::string fileformat, std::string labelformat, const std::vector<std::string>& objects) { - std::vector<std::tuple<std::string, std::string, std::vector<std::string>>> files; - files.emplace_back(fileformat, labelformat, objects); - config.setFiles(files); +void Application::addFile(ConfigEditor& config, std::string fileformat, std::string labelformat, + const std::vector<std::string>& objects) +{ + std::vector<std::tuple<std::string, std::string, std::vector<std::string>>> files; + files.emplace_back(fileformat, labelformat, objects); + config.setFiles(files); } /** @brief Run shell script for CI test with different commit **/ -void Application::citest(const std::vector<std::string>& names, std::string builddir) { - std::ostringstream cmd; - const char* vmworkdir = getenv("VMWORKDIR"); - if (vmworkdir != nullptr) { +void Application::citest(const std::vector<std::string>& names, std::string builddir) +{ + std::ostringstream cmd; + const char* vmworkdir = getenv("VMWORKDIR"); + if (vmworkdir != nullptr) { + + cmd << vmworkdir << "/macro/qa/run_ctest_commit.sh"; + //int ret = system(cmd.str().c_str()); - cmd << vmworkdir << "/macro/qa/run_ctest_commit.sh"; - //int ret = system(cmd.str().c_str()); - - //cmd << "${VMWORKDIR}/macro/qa/run_ctest_commit.sh"; + //cmd << "${VMWORKDIR}/macro/qa/run_ctest_commit.sh"; for (const auto& name : names) { - cmd << " " << name; + cmd << " " << name; } if (!builddir.empty()) { - cmd << " --build_dir " << builddir; + cmd << " --build_dir " << builddir; } // Add current directory @@ -107,19 +125,20 @@ void Application::citest(const std::vector<std::string>& names, std::string buil int ret = system(finalCmd.c_str()); - if (ret != 0) { - std::cerr << "Script failed with return code: " << ret << std::endl; - } - } - else{ - std::cerr << "VMWORKDIR not set in environment!" << std::endl; + if (ret != 0) { + std::cerr << "Script failed with return code: " << ret << std::endl; } + } + else { + std::cerr << "VMWORKDIR not set in environment!" << std::endl; + } } /** @brief Executes the comparison routine with an optional parameter **/ -void Application::exec(Option_t* option) { - auto pChecker = std::make_unique<cbm::qa::checker::Core>(); - pChecker->RegisterOutFile(outputFileName.c_str()); - pChecker->SetFromYAML(configFileName.c_str()); - pChecker->Process(option); +void Application::exec(Option_t* option) +{ + auto pChecker = std::make_unique<cbm::qa::checker::Core>(); + pChecker->RegisterOutFile(outputFileName.c_str()); + pChecker->SetFromYAML(configFileName.c_str()); + pChecker->Process(option); } diff --git a/services/qa/Application.h b/services/qa/Application.h index d1abf4926..6fc34e27d 100644 --- a/services/qa/Application.h +++ b/services/qa/Application.h @@ -1,44 +1,50 @@ +/* Copyright (C) 2025 GSI/VECC, Darmstadt/Kolkata + SPDX-License-Identifier: GPL-3.0-only + Authors: Souvik Chattopadhyay[committer], Sergei Zharko */ + + + #ifndef APPLICATION_H #define APPLICATION_H -#include "ConfigEditor.h" #include "ApplicationParameter.h" -#include <vector> -#include <string> +#include "CbmQaCheckerCore.h" +#include "ConfigEditor.h" + #include <map> #include <memory> // For std::unique_ptr -#include "CbmQaCheckerCore.h" - +#include <string> +#include <vector> + class Application { -public: - /** @brief Constructor: Initializes the application with program options **/ - explicit Application(ApplicationParameter const& opt); + public: + /** @brief Constructor: Initializes the application with program options **/ + explicit Application(ApplicationParameter const& opt); - /** @brief Executes the comparison routine with an optional parameter **/ - void exec(Option_t* option = "E"); + /** @brief Executes the comparison routine with an optional parameter **/ + void exec(Option_t* option = "E"); -private: - /** @brief Adds commit versions to the configuration **/ - void addVersionCommit(ConfigEditor& config, const std::vector<std::string>& names); + private: + /** @brief Adds commit versions to the configuration **/ + void addVersionCommit(ConfigEditor& config, const std::vector<std::string>& names); - /** @brief Adds weekly test versions to the configuration **/ - void addVersionWeeklyTest(ConfigEditor& config, const std::vector<std::string>& names); + /** @brief Adds weekly test versions to the configuration **/ + void addVersionWeeklyTest(ConfigEditor& config, const std::vector<std::string>& names); - /** @brief Adds a file with specified format and label to the configaration **/ - void addFile(ConfigEditor& config, std::string fileformat, std::string labelformat, const std::vector<std::string>& objects); + /** @brief Adds a file with specified format and label to the configaration **/ + void addFile(ConfigEditor& config, std::string fileformat, std::string labelformat, + const std::vector<std::string>& objects); - - void citest(const std::vector<std::string>& names, std::string builddir = ""); + void citest(const std::vector<std::string>& names, std::string builddir = ""); - - /** @brief Unique pointer to Checker **/ + /** @brief Unique pointer to Checker **/ // std::unique_ptr<cbm::qa::checker::Core> pChecker; - - std::string configFileName; - std::string outputFileName; + + std::string configFileName; + std::string outputFileName; }; -#endif // APPLICATION_H +#endif // APPLICATION_H diff --git a/services/qa/ApplicationParameter.cxx b/services/qa/ApplicationParameter.cxx index 82ad18404..e9f44146f 100644 --- a/services/qa/ApplicationParameter.cxx +++ b/services/qa/ApplicationParameter.cxx @@ -1,71 +1,65 @@ +/* Copyright (C) 2025 GSI/VECC, Darmstadt/Kolkata + SPDX-License-Identifier: GPL-3.0-only + Authors: Souvik Chattopadhyay[committer], Sergei Zharko */ + + + + #include "ApplicationParameter.h" + #include <iostream> namespace po = boost::program_options; /** @brief Constructor: Parses command-line arguments **/ -ApplicationParameter::ApplicationParameter(int argc, char* argv[]) { - parseCommandLine(argc, argv); -} +ApplicationParameter::ApplicationParameter(int argc, char* argv[]) { parseCommandLine(argc, argv); } /** @brief Parses command-line arguments **/ -void ApplicationParameter::parseCommandLine(int argc, char* argv[]) { - try { - // Define command-line options - po::options_description desc("Allowed options"); - desc.add_options() - ("help,h", "Display help message") - ("compare,t", po::value<std::string>(&fcompare)->required()->value_name("commit"), - "Specify comparison type (only 'commit' or 'weeklyTest' are allowed)") - ("names,n", po::value<std::vector<std::string>>(&fnames)->multitoken()->value_name("<name1 name2 ...>"), - "List of commit hash or week numbers(yyyy_ww)") - ("output,o", po::value<std::string>(&foutput)->default_value("./output_compare_qa.root"), - "Specify output file name") - ("config,c", po::value<std::string>(&fconfig)->default_value("./objects.yaml"), - "Specify config file") - ("builddir,b", po::value<std::string>(&fbuilddir)->default_value(""), - "Specify cbmroot build directory"); - - // Parse command-line arguments - po::variables_map vars; - po::store(po::parse_command_line(argc, argv, desc), vars); - - // Handle help request - if (vars.count("help")) { - std::cout << desc << std::endl; - exit(EXIT_SUCCESS); - } - - // Apply required options - po::notify(vars); - - // Validate "--compare" option (only "commit" or "weeklyTest" allowed) - if ((fcompare != "commit") && (fcompare != "weeklyTest")) { - throw po::validation_error(po::validation_error::invalid_option_value, "compare", fcompare); - } - - } catch (const po::error& e) { - std::cerr << "Error: " << e.what() << std::endl; - exit(EXIT_FAILURE); +void ApplicationParameter::parseCommandLine(int argc, char* argv[]) +{ + try { + // Define command-line options + po::options_description desc("Allowed options"); + desc.add_options()("help,h", "Display help message")( + "compare,t", po::value<std::string>(&fcompare)->required()->value_name("commit"), + "Specify comparison type (only 'commit' or 'weeklyTest' are allowed)")( + "names,n", po::value<std::vector<std::string>>(&fnames)->multitoken()->value_name("<name1 name2 ...>"), + "List of commit hash or week numbers(yyyy_ww)")( + "output,o", po::value<std::string>(&foutput)->default_value("./output_compare_qa.root"), + "Specify output file name")("config,c", po::value<std::string>(&fconfig)->default_value("./objects.yaml"), + "Specify config file")( + "builddir,b", po::value<std::string>(&fbuilddir)->default_value(""), "Specify cbmroot build directory"); + + // Parse command-line arguments + po::variables_map vars; + po::store(po::parse_command_line(argc, argv, desc), vars); + + // Handle help request + if (vars.count("help")) { + std::cout << desc << std::endl; + exit(EXIT_SUCCESS); } + + // Apply required options + po::notify(vars); + + // Validate "--compare" option (only "commit" or "weeklyTest" allowed) + if ((fcompare != "commit") && (fcompare != "weeklyTest")) { + throw po::validation_error(po::validation_error::invalid_option_value, "compare", fcompare); + } + } + catch (const po::error& e) { + std::cerr << "Error: " << e.what() << std::endl; + exit(EXIT_FAILURE); + } } /** @brief Getters for parsed options **/ -std::string ApplicationParameter::getCompare() const { - return fcompare; -} +std::string ApplicationParameter::getCompare() const { return fcompare; } -std::vector<std::string> ApplicationParameter::getNames() const { - return fnames; -} +std::vector<std::string> ApplicationParameter::getNames() const { return fnames; } -std::string ApplicationParameter::getOutput() const { - return foutput; -} +std::string ApplicationParameter::getOutput() const { return foutput; } -std::string ApplicationParameter::getConfig() const { - return fconfig; -} -std::string ApplicationParameter::getbuilddir() const { - return fbuilddir; -} +std::string ApplicationParameter::getConfig() const { return fconfig; } +std::string ApplicationParameter::getbuilddir() const { return fbuilddir; } diff --git a/services/qa/ApplicationParameter.h b/services/qa/ApplicationParameter.h index 4b28fbef0..c6bdda818 100644 --- a/services/qa/ApplicationParameter.h +++ b/services/qa/ApplicationParameter.h @@ -1,41 +1,46 @@ +/* Copyright (C) 2025 GSI/VECC, Darmstadt/Kolkata + SPDX-License-Identifier: GPL-3.0-only + Authors: Souvik Chattopadhyay[committer], Sergei Zharko */ + + + #ifndef APPLICATION_PARAMETER_H #define APPLICATION_PARAMETER_H #include <boost/program_options.hpp> + #include <string> #include <vector> class ApplicationParameter { -public: - /** @brief Constructor: Parses command-line arguments **/ - ApplicationParameter(int argc, char* argv[]); - - - - /** @brief Default copy constructor **/ - ApplicationParameter(const ApplicationParameter&) = default; - - /** @brief Default assignment operator **/ - ApplicationParameter& operator=(const ApplicationParameter&) = default; - - /** @brief Getters for parsed options **/ - std::string getCompare() const; - std::vector<std::string> getNames() const; - std::string getOutput() const; - std::string getConfig() const; - std::string getbuilddir() const; - -private: - /** @brief Parses command-line arguments **/ - void parseCommandLine(int argc, char* argv[]); - - // Variables to store parsed command-line arguments - std::string fcompare; - std::vector<std::string> fnames; - std::string foutput; - std::string fconfig; - std::string fbuilddir; - + public: + /** @brief Constructor: Parses command-line arguments **/ + ApplicationParameter(int argc, char* argv[]); + + + /** @brief Default copy constructor **/ + ApplicationParameter(const ApplicationParameter&) = default; + + /** @brief Default assignment operator **/ + ApplicationParameter& operator=(const ApplicationParameter&) = default; + + /** @brief Getters for parsed options **/ + std::string getCompare() const; + std::vector<std::string> getNames() const; + std::string getOutput() const; + std::string getConfig() const; + std::string getbuilddir() const; + + private: + /** @brief Parses command-line arguments **/ + void parseCommandLine(int argc, char* argv[]); + + // Variables to store parsed command-line arguments + std::string fcompare; + std::vector<std::string> fnames; + std::string foutput; + std::string fconfig; + std::string fbuilddir; }; -#endif // APPLICATION_PARAMETER_H +#endif // APPLICATION_PARAMETER_H diff --git a/services/qa/ConfigEditor.cxx b/services/qa/ConfigEditor.cxx index 229e8f2e0..1a5ff9191 100644 --- a/services/qa/ConfigEditor.cxx +++ b/services/qa/ConfigEditor.cxx @@ -1,85 +1,100 @@ +/* Copyright (C) 2025 GSI/VECC, Darmstadt/Kolkata + SPDX-License-Identifier: GPL-3.0-only + Authors: Souvik Chattopadhyay[committer], Sergei Zharko */ + #include "ConfigEditor.h" -#include <iostream> + #include <fstream> +#include <iostream> /** @brief Constructor: Loads the YAML file **/ -ConfigEditor::ConfigEditor(const std::string& configFile) { +ConfigEditor::ConfigEditor(const std::string& configFile) +{ if (std::ifstream(configFile)) { - LoadConfig(configFile); - } - else{ - setDefault(); - } + LoadConfig(configFile); + } + else { + SetDefault(); + } } /** @brief Load YAML configuration **/ -void ConfigEditor::LoadConfig(const std::string& configFile) { - try { - yamlData = YAML::LoadFile(configFile); - } catch (const std::exception& e) { - std::cerr << "Error loading YAML file: " << e.what() << std::endl; - } +void ConfigEditor::LoadConfig(const std::string& configFile) +{ + try { + yamlData = YAML::LoadFile(configFile); + } + catch (const std::exception& e) { + std::cerr << "Error loading YAML file: " << e.what() << std::endl; + } } /** @brief default YAML configuration **/ -void ConfigEditor::setDefault() { - - yamlData["checker"]["settings"]["ratio_min"] = 0.90; - yamlData["checker"]["settings"]["ratio_max"] = 1.10; - yamlData["checker"]["settings"]["pval_threshold"] = 0.01; +void ConfigEditor::SetDefault() +{ + + yamlData["checker"]["settings"]["ratio_min"] = 0.90; + yamlData["checker"]["settings"]["ratio_max"] = 1.10; + yamlData["checker"]["settings"]["pval_threshold"] = 0.01; } /** @brief Set new versions **/ -void ConfigEditor::setVersions(const std::map<std::string, std::string>& newVersions) { - yamlData["checker"]["versions"] = YAML::Node(YAML::NodeType::Sequence); - for (const auto& [label, path] : newVersions) { - YAML::Node versionNode; - versionNode["label"] = label; - versionNode["path"] = path; - yamlData["checker"]["versions"].push_back(versionNode); - } +void ConfigEditor::SetVersions(const std::map<std::string, std::string>& newVersions) +{ + yamlData["checker"]["versions"] = YAML::Node(YAML::NodeType::Sequence); + for (const auto& [label, path] : newVersions) { + YAML::Node versionNode; + versionNode["label"] = label; + versionNode["path"] = path; + yamlData["checker"]["versions"].push_back(versionNode); + } } /** @brief Set new dataset names **/ -void ConfigEditor::setDatasets(const std::vector<std::string>& newDatasets) { - yamlData["checker"]["datasets"] = YAML::Node(YAML::NodeType::Sequence); - for (const auto& dataset : newDatasets) { - yamlData["checker"]["datasets"].push_back(dataset); - } +void ConfigEditor::SetDatasets(const std::vector<std::string>& newDatasets) +{ + yamlData["checker"]["datasets"] = YAML::Node(YAML::NodeType::Sequence); + for (const auto& dataset : newDatasets) { + yamlData["checker"]["datasets"].push_back(dataset); + } } -/** @brief Set new files with labels **/ -void ConfigEditor::setFiles(const std::vector<std::tuple<std::string, std::string, std::vector<std::string>>>& newFiles) { - yamlData["checker"]["files"] = YAML::Node(YAML::NodeType::Sequence); - for (const auto& [name, label, objects] : newFiles) { - YAML::Node fileNode; - fileNode["name"] = name; - fileNode["label"] = label; // Always add the label +/** @brief Set new files with labels **/ +void ConfigEditor::SetFiles(const std::vector<std::tuple<std::string, std::string, std::vector<std::string>>>& newFiles) +{ + yamlData["checker"]["files"] = YAML::Node(YAML::NodeType::Sequence); + for (const auto& [name, label, objects] : newFiles) { + YAML::Node fileNode; + fileNode["name"] = name; + fileNode["label"] = label; // Always add the label - // Only add "objects" node if the objects vector is non-empty - if (!objects.empty()) { - YAML::Node objectsNode(YAML::NodeType::Sequence); - for (const auto& obj : objects) { - objectsNode.push_back(obj); - } - fileNode["objects"] = objectsNode; - } - - yamlData["checker"]["files"].push_back(fileNode); + // Only add "objects" node if the objects vector is non-empty + if (!objects.empty()) { + YAML::Node objectsNode(YAML::NodeType::Sequence); + for (const auto& obj : objects) { + objectsNode.push_back(obj); + } + fileNode["objects"] = objectsNode; } + + yamlData["checker"]["files"].push_back(fileNode); + } } /** @brief Save the modified YAML file **/ -void ConfigEditor::saveConfig(const std::string& configFile) const { - if (!configFile.empty() && yamlData.IsDefined()) { - std::ofstream outFile(configFile); - if (outFile.is_open()) { - outFile << yamlData; - outFile.close(); - } else { - std::cerr << "Error: Unable to open file for saving!" << std::endl; - } - } else { - std::cerr << "Error: No config file specified or YAML data is empty!" << std::endl; +void ConfigEditor::SaveConfig(const std::string& configFile) const +{ + if (!configFile.empty() && yamlData.IsDefined()) { + std::ofstream outFile(configFile); + if (outFile.is_open()) { + outFile << yamlData; + outFile.close(); + } + else { + std::cerr << "Error: Unable to open file for saving!" << std::endl; } + } + else { + std::cerr << "Error: No config file specified or YAML data is empty!" << std::endl; + } } diff --git a/services/qa/ConfigEditor.h b/services/qa/ConfigEditor.h index 9bdf1dc1d..d1f224d73 100644 --- a/services/qa/ConfigEditor.h +++ b/services/qa/ConfigEditor.h @@ -1,37 +1,45 @@ +/* Copyright (C) 2025 GSI/VECC, Darmstadt/Kolkata + SPDX-License-Identifier: GPL-3.0-only + Authors: Souvik Chattopadhyay[committer], Sergei Zharko */ + + + + + #ifndef CONFIG_EDITOR_H #define CONFIG_EDITOR_H -#include <yaml-cpp/yaml.h> +#include <map> #include <string> #include <vector> -#include <map> + +#include <yaml-cpp/yaml.h> class ConfigEditor { -public: - /** @brief Constructor **/ - explicit ConfigEditor(const std::string& configFile = ""); + public: + /** @brief Constructor **/ + explicit ConfigEditor(const std::string& configFile = ""); + + /** @brief Load YAML configuration **/ + void LoadConfig(const std::string& configFile); - /** @brief Load YAML configuration **/ - void LoadConfig(const std::string& configFile); - /** @brief Load default configuration **/ - void setDefault(); - - /** @brief Set and update version information **/ - void setVersions(const std::map<std::string, std::string>& newVersions); + void SetDefault(); + + /** @brief Set and update version information **/ + void SetVersions(const std::map<std::string, std::string>& newVersions); - /** @brief Set and update dataset names **/ - void setDatasets(const std::vector<std::string>& newDatasets); + /** @brief Set and update dataset names **/ + void SetDatasets(const std::vector<std::string>& newDatasets); - /** @brief Set and update files **/ - void setFiles(const std::vector<std::tuple<std::string, std::string, std::vector<std::string>>>& newFiles); + /** @brief Set and update files **/ + void SetFiles(const std::vector<std::tuple<std::string, std::string, std::vector<std::string>>>& newFiles); - /** @brief Save the modified YAML configuration **/ - void saveConfig(const std::string& configFile) const; + /** @brief Save the modified YAML configuration **/ + void SaveConfig(const std::string& configFile) const; -private: - YAML::Node yamlData; // Stores the configuration data - + private: + YAML::Node yamlData; // Stores the configuration data }; -#endif // CONFIG_EDITOR_H +#endif // CONFIG_EDITOR_H diff --git a/services/qa/main.cxx b/services/qa/main.cxx index 829bef04b..c65618d5c 100644 --- a/services/qa/main.cxx +++ b/services/qa/main.cxx @@ -1,23 +1,29 @@ +/* Copyright (C) 2025 GSI/VECC, Darmstadt/Kolkata + SPDX-License-Identifier: GPL-3.0-only + Authors: Souvik Chattopadhyay[committer], Sergei Zharko */ + #include "Application.h" #include "ApplicationParameter.h" + #include <iostream> -int main(int argc, char* argv[]) { - try { - // Parse command-line arguments - ApplicationParameter opt(argc, argv); +int main(int argc, char* argv[]) +{ + try { + // Parse command-line arguments + ApplicationParameter opt(argc, argv); - // Create the Application instance - Application app(opt); + // Create the Application instance + Application app(opt); - // Execute the comparison process with a default option - //app.exec("E"); + // Execute the comparison process with a default option + //app.exec("E"); - // Return the process result - //return result; - } - catch (const std::exception& e) { - std::cerr << "Error: " << e.what() << std::endl; - return EXIT_FAILURE; - } + // Return the process result + //return result; + } + catch (const std::exception& e) { + std::cerr << "Error: " << e.what() << std::endl; + return EXIT_FAILURE; + } } -- GitLab From 41ac348d9dc9b7593599ac8ff1dfdc97612b0e04 Mon Sep 17 00:00:00 2001 From: Souvik Chattopadhyay <souvik.c@vecc.gov.in> Date: Thu, 10 Apr 2025 17:54:26 +0200 Subject: [PATCH 11/11] Apply clang-format changed the function names to capital letter changed the installation script changed the installation of cbmroot inside run_ctest_commit.sh modified Application.cxx so that if run_ctest_commit.sh fails it returns --- .../dielectron/conversion/CbmAnaConversion.cxx | 2 +- macro/qa/run_ctest_commit.sh | 8 +++++--- services/qa/Application.cxx | 16 ++++++++-------- services/qa/Application.h | 1 - services/qa/ApplicationParameter.cxx | 2 -- services/qa/ApplicationParameter.h | 1 - services/qa/ConfigEditor.h | 3 --- 7 files changed, 14 insertions(+), 19 deletions(-) diff --git a/analysis/PWGDIL/dielectron/conversion/CbmAnaConversion.cxx b/analysis/PWGDIL/dielectron/conversion/CbmAnaConversion.cxx index 5495d5739..e7b6fcdd3 100644 --- a/analysis/PWGDIL/dielectron/conversion/CbmAnaConversion.cxx +++ b/analysis/PWGDIL/dielectron/conversion/CbmAnaConversion.cxx @@ -64,7 +64,7 @@ #define M2E 2.6112004954086e-7 - using namespace std; +using namespace std; using boost::assign::list_of; CbmAnaConversion::CbmAnaConversion() diff --git a/macro/qa/run_ctest_commit.sh b/macro/qa/run_ctest_commit.sh index f6187b1d9..5cf5f3bea 100755 --- a/macro/qa/run_ctest_commit.sh +++ b/macro/qa/run_ctest_commit.sh @@ -19,8 +19,9 @@ run_comparison() { echo "Checking out commit: $commit" git checkout $commit || { echo "Failed to checkout $commit"; exit 1; } echo "Installing CBMRoot..." - ./install_cbmroot.sh || { echo "Installation failed"; exit 1; } - + ./autoinstall_framework.sh --use_fairsoft /cvmfs/fairsoft.gsi.de/debian10/fairsoft/nov22p3 --use_fairroot /cvmfs/fairsoft.gsi.de/debian10/fairroot/v18.8.0_nov22p3 -cr || { echo "Installation failed"; exit 1; } + #./install_cbmroot.sh || { echo "Installation failed"; exit 1; } + echo "Running Ctest" cd ${BUILD_DIR} ctest -R run_s100m3_qa_ts_eb_real @@ -84,7 +85,8 @@ desired_branch=$(git rev-parse --abbrev-ref HEAD) if [ "$current_branch" != "$desired_branch" ]; then echo "Checking out the original branch: $desired_branch" git checkout $desired_branch || { echo "Failed to checkout $desired_branch"; exit 1; } - ./install_cbmroot.sh || { echo "Installation failed"; exit 1; } + ./autoinstall_framework.sh --use_fairsoft /cvmfs/fairsoft.gsi.de/debian10/fairsoft/nov22p3 --use_fairroot /cvmfs/fairsoft.gsi.de/debian10/fairroot/v18.8.0_nov22p3 -cr || { echo "Installation failed"; exit 1; } + #./install_cbmroot.sh || { echo "Installation failed"; exit 1; } else echo "Already on the initial branch: $current_branch. Skipping checkout and installation." fi diff --git a/services/qa/Application.cxx b/services/qa/Application.cxx index 073432a26..98c0b94a9 100644 --- a/services/qa/Application.cxx +++ b/services/qa/Application.cxx @@ -3,8 +3,6 @@ Authors: Souvik Chattopadhyay[committer], Sergei Zharko */ - - #include "Application.h" #include <iostream> @@ -42,7 +40,7 @@ Application::Application(ApplicationParameter const& opt) if (compareType == "commit") { citest(names, opt.getbuilddir()); addVersionCommit(config, names); - config.setDatasets({"default"}); + config.SetDatasets({"default"}); std::string currentDir = getCurrentDir(); addFile(config, currentDir + "/%v.root", "qa_commit", {}); } @@ -50,7 +48,7 @@ Application::Application(ApplicationParameter const& opt) else if (compareType == "weeklyTest") { addVersionWeeklyTest(config, names); - config.setDatasets({"default"}); + config.SetDatasets({"default"}); addFile(config, "%v.root", "qa_weekly", {}); } @@ -58,7 +56,7 @@ Application::Application(ApplicationParameter const& opt) std::cerr << "Unknown compare type: " << compareType << std::endl; } - config.saveConfig(opt.getConfig()); + config.SaveConfig(opt.getConfig()); exec("E"); } @@ -71,7 +69,7 @@ void Application::addVersionCommit(ConfigEditor& config, const std::vector<std:: std::string path = "s100m3_qa_ts_eb_real_" + label + ".qa"; versions[label] = path; } - config.setVersions(versions); + config.SetVersions(versions); } /** @brief Adds weekly test versions to the configuration **/ @@ -83,7 +81,7 @@ void Application::addVersionWeeklyTest(ConfigEditor& config, const std::vector<s "/lustre/cbm/users/ploizeau/cdash/weekly_virgo3_vae23_dev_" + name + "/macro/run/data/s100h_qa_ts_eb_ideal.qa"; versions[name] = path; } - config.setVersions(versions); + config.SetVersions(versions); } /** @brief Adds a file with specified format and label **/ @@ -92,7 +90,7 @@ void Application::addFile(ConfigEditor& config, std::string fileformat, std::str { std::vector<std::tuple<std::string, std::string, std::vector<std::string>>> files; files.emplace_back(fileformat, labelformat, objects); - config.setFiles(files); + config.SetFiles(files); } /** @brief Run shell script for CI test with different commit **/ @@ -127,10 +125,12 @@ void Application::citest(const std::vector<std::string>& names, std::string buil if (ret != 0) { std::cerr << "Script failed with return code: " << ret << std::endl; + return; } } else { std::cerr << "VMWORKDIR not set in environment!" << std::endl; + return; } } diff --git a/services/qa/Application.h b/services/qa/Application.h index 6fc34e27d..82a3dd48a 100644 --- a/services/qa/Application.h +++ b/services/qa/Application.h @@ -3,7 +3,6 @@ Authors: Souvik Chattopadhyay[committer], Sergei Zharko */ - #ifndef APPLICATION_H #define APPLICATION_H diff --git a/services/qa/ApplicationParameter.cxx b/services/qa/ApplicationParameter.cxx index e9f44146f..eb5f2fc05 100644 --- a/services/qa/ApplicationParameter.cxx +++ b/services/qa/ApplicationParameter.cxx @@ -3,8 +3,6 @@ Authors: Souvik Chattopadhyay[committer], Sergei Zharko */ - - #include "ApplicationParameter.h" #include <iostream> diff --git a/services/qa/ApplicationParameter.h b/services/qa/ApplicationParameter.h index c6bdda818..44011e107 100644 --- a/services/qa/ApplicationParameter.h +++ b/services/qa/ApplicationParameter.h @@ -3,7 +3,6 @@ Authors: Souvik Chattopadhyay[committer], Sergei Zharko */ - #ifndef APPLICATION_PARAMETER_H #define APPLICATION_PARAMETER_H diff --git a/services/qa/ConfigEditor.h b/services/qa/ConfigEditor.h index d1f224d73..204a4647d 100644 --- a/services/qa/ConfigEditor.h +++ b/services/qa/ConfigEditor.h @@ -3,9 +3,6 @@ Authors: Souvik Chattopadhyay[committer], Sergei Zharko */ - - - #ifndef CONFIG_EDITOR_H #define CONFIG_EDITOR_H -- GitLab