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