From 62ea70fef1ed9be7fd0bbe9c3b90d2484eb5f48c Mon Sep 17 00:00:00 2001
From: Wouter Deconinck <wdconinc@gmail.com>
Date: Mon, 29 Nov 2021 04:41:15 +0000
Subject: [PATCH] TCS benchmark and FF status plot

---
 .gitlab-ci.yml                        |   1 +
 benchmarks/tcs/analysis/tcs_tests.cxx |  60 +++++++++
 benchmarks/tcs/config.yml             |  26 ++++
 benchmarks/tcs/tcs.sh                 | 173 ++++++++++++++++++++++++++
 4 files changed, 260 insertions(+)
 create mode 100644 benchmarks/tcs/analysis/tcs_tests.cxx
 create mode 100644 benchmarks/tcs/config.yml
 create mode 100644 benchmarks/tcs/tcs.sh

diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index b611efc2..1c679940 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -68,6 +68,7 @@ include:
   - local: 'benchmarks/dis/config.yml'
     #- local: 'benchmarks/dvmp/config.yml'
   - local: 'benchmarks/dvcs/config.yml'
+  - local: 'benchmarks/tcs/config.yml'
   - local: 'benchmarks/u_omega/config.yml'
   - local: 'benchmarks/single/config.yml'
   - local: 'benchmarks/synchrotron/config.yml'
diff --git a/benchmarks/tcs/analysis/tcs_tests.cxx b/benchmarks/tcs/analysis/tcs_tests.cxx
new file mode 100644
index 00000000..5fe49b7b
--- /dev/null
+++ b/benchmarks/tcs/analysis/tcs_tests.cxx
@@ -0,0 +1,60 @@
+#include <cmath>
+#include <iostream>
+#include <string>
+#include <vector>
+
+#include "ROOT/RDataFrame.hxx"
+#include "Math/Vector4D.h"
+#include "TCanvas.h"
+
+#include <nlohmann/json.hpp>
+using json = nlohmann::json;
+
+R__LOAD_LIBRARY(libfmt.so)
+#include "fmt/core.h"
+#include "fmt/color.h"
+
+R__LOAD_LIBRARY(libeicd.so)
+R__LOAD_LIBRARY(libDD4pod.so)
+
+#include "eicd/InclusiveKinematicsCollection.h"
+#include "eicd/ReconstructedParticleCollection.h"
+
+void tcs_tests(const char* fname = "rec_tcs.root"){
+
+  fmt::print(fmt::emphasis::bold | fg(fmt::color::forest_green), "Running TCS analysis...\n");
+
+  // Run this in multi-threaded mode if desired
+  ROOT::EnableImplicitMT();
+  ROOT::RDataFrame df("events", fname);
+
+  auto df0 = df.Define("n_parts", "ReconstructedParticles.size()")
+               .Define("isQ2gt1", "InclusiveKinematicsTruth.Q2 > 1.0")
+               .Define("n_Q2gt1", "isQ2gt1.size()");
+
+  auto h_n_parts = df0.Histo1D({"h_n_parts", "; h_n_parts n", 10, 0, 10}, "n_parts");
+  auto h_Q2      = df0.Histo1D({"h_Q2", "; Q^{2} [GeV^{2}/c^{2}]", 100, 0, 30}, "InclusiveKinematicsTruth.Q2");
+  auto h_ff_status = df0.Histo1D({"h_ff_status", "; FF status", 10, -0.5, 9.5}, "ReconstructedFFParticles.status");
+  auto n_Q2gt1   = df0.Mean("n_Q2gt1");
+  auto n_parts   = df0.Mean("n_parts");
+
+  // ---------------------------
+  // Do evaluation
+
+  auto c = new TCanvas();
+  h_Q2->DrawCopy();
+  c->SaveAs("results/tcs/Q2.png");
+  c->SaveAs("results/tcs/Q2.pdf");
+  fmt::print("{} TCS events Q2>1\n",*n_Q2gt1);
+  fmt::print("{} tracks per event\n",*n_parts);
+
+  c = new TCanvas();
+  h_n_parts->DrawCopy();
+  c->SaveAs("results/tcs/n_parts.png");
+  c->SaveAs("results/tcs/n_parts.pdf");
+
+  c = new TCanvas();
+  h_ff_status->DrawCopy();
+  c->SaveAs("results/tcs/ff_status.png");
+  c->SaveAs("results/tcs/ff_status.pdf");
+}
diff --git a/benchmarks/tcs/config.yml b/benchmarks/tcs/config.yml
new file mode 100644
index 00000000..b2c7b42b
--- /dev/null
+++ b/benchmarks/tcs/config.yml
@@ -0,0 +1,26 @@
+tcs:process:
+  stage: process
+  extends: .phy_benchmark
+  tags:
+    - phy
+  needs: ["common:detector"]
+  parallel:
+    matrix:
+      - EBEAM: 5
+        PBEAM: 41
+        TAG: s450
+      - EBEAM: 10
+        PBEAM: 100
+        TAG: s100
+      - EBEAM: 18
+        PBEAM: 275
+        TAG: s800
+  script:
+    - compile_analyses.py tcs
+    - bash benchmarks/tcs/tcs.sh --all --ebeam ${EBEAM} --pbeam ${PBEAM} --tag ${TAG}
+
+tcs:results:
+  stage: collect
+  needs: ["tcs:process"]
+  script:
+    - ls -lrth
diff --git a/benchmarks/tcs/tcs.sh b/benchmarks/tcs/tcs.sh
new file mode 100644
index 00000000..760cae53
--- /dev/null
+++ b/benchmarks/tcs/tcs.sh
@@ -0,0 +1,173 @@
+#!/bin/bash
+set -Eu
+trap 's=$?; echo "$0: Error on line "$LINENO": $BASH_COMMAND"; exit $s' ERR
+IFS=$'\n\t'
+
+function print_the_help {
+  echo "USAGE: ${0} [--rec] [--sim] [--analysis] [--all] "
+  echo "    The default options are to run all steps (sim,rec,analysis) "
+  echo "OPTIONS: "
+  echo "  --data-init     download the input event data"
+  echo "  --sim,-s        Runs the Geant4 simulation"
+  echo "  --rec,-r        Run the juggler reconstruction"
+  echo "  --analysis,-a   Run the analysis scripts"
+  echo "  --all           (default) Do all steps. Argument is included so usage can convey intent."
+  exit 
+}
+
+DO_ALL=1
+DATA_INIT=
+DO_SIM=
+DO_REC=
+DO_ANALYSIS=
+EBEAM=
+PBEAM=
+TAG=
+
+POSITIONAL=()
+while [[ $# -gt 0 ]]
+do
+  key="$1"
+
+  case $key in
+    -h|--help)
+      shift # past argument
+      print_the_help
+      ;;
+    --all)
+      DO_ALL=2
+      if [[ ! "${DO_REC}${DO_SIM}${DO_ANALYSIS}" -eq "" ]] ; then
+        echo "Error: cannot use --all with other arguments." 1>&2
+        print_the_help
+        exit 1
+      fi
+      shift # past value
+      ;;
+    --tag)
+      shift # past argument
+      TAG=$1
+      shift # past value
+      ;;
+    --pbeam)
+      shift # past argument
+      PBEAM=$1
+      shift # past value
+      ;;
+    --ebeam)
+      shift # past argument
+      EBEAM=$1
+      shift # past value
+      ;;
+    -s|--sim)
+      DO_SIM=1
+      DO_ALL=
+      shift # past value
+      ;;
+    --data-init)
+      DATA_INIT=1
+      DO_ALL=
+      shift # past value
+      ;;
+    -r|--rec)
+      DO_REC=1
+      DO_ALL=
+      shift # past value
+      ;;
+    -a|--analysis)
+      DO_ANALYSIS=1
+      DO_ALL=
+      shift # past value
+      ;;
+    *)    # unknown option
+      #POSITIONAL+=("$1") # save it in an array for later
+      echo "unknown option $1"
+      print_the_help
+      shift # past argument
+      ;;
+  esac
+done
+set -- "${POSITIONAL[@]}" # restore positional parameters
+
+# assuming something like .local/bin/env.sh has already been sourced.
+print_env.sh
+
+FILE_NAME_TAG="tcs"
+DATA_URL="S3/eictest/ATHENA/EVGEN/EXCLUSIVE/TCS_ABCONV/${EBEAM}x${PBEAM}/hel_minus/TCS_gen_ab_hiAcc_${EBEAM}x${PBEAM}m_${TAG}_novtx.hepmc.gz"
+
+export JUGGLER_MC_FILE="${LOCAL_DATA_PATH}/mc_${FILE_NAME_TAG}.hepmc"
+export JUGGLER_SIM_FILE="${LOCAL_DATA_PATH}/sim_${FILE_NAME_TAG}.root"
+export JUGGLER_REC_FILE="${LOCAL_DATA_PATH}/rec_${FILE_NAME_TAG}.root"
+
+echo "FILE_NAME_TAG       = ${FILE_NAME_TAG}"
+echo "JUGGLER_N_EVENTS    = ${JUGGLER_N_EVENTS}"
+echo "JUGGLER_DETECTOR    = ${JUGGLER_DETECTOR}"
+
+
+## To run the reconstruction, we need the following global variables:
+## - JUGGLER_INSTALL_PREFIX: Install prefix for Juggler (simu/recon)
+## - JUGGLER_DETECTOR:       the detector package we want to use for this benchmark
+## - DETECTOR_PATH:          full path to the detector definitions
+
+## Step 1. Get the data
+if [[ -n "${DATA_INIT}" || -n "${DO_ALL}" ]] ; then
+  mc -C . config host add S3 https://dtn01.sdcc.bnl.gov:9000 $S3_ACCESS_KEY $S3_SECRET_KEY
+  mc -C . cat --insecure ${DATA_URL} | gunzip -c | head -n 1004 |  sanitize_hepmc3 > "${JUGGLER_MC_FILE}"
+  if [[ "$?" -ne "0" ]] ; then
+    echo "Failed to download hepmc file"
+    exit 1
+  fi
+fi
+
+### Step 2. Run the simulation (geant4)
+if [[ -n "${DO_SIM}" || -n "${DO_ALL}" ]] ; then
+  ## run geant4 simulations
+  npsim --runType batch \
+    --part.minimalKineticEnergy 1000*GeV  \
+    -v ERROR \
+    --numberOfEvents ${JUGGLER_N_EVENTS} \
+    --compactFile ${DETECTOR_PATH}/${JUGGLER_DETECTOR}.xml \
+    --inputFiles "${JUGGLER_MC_FILE}" \
+    --outputFile  ${JUGGLER_SIM_FILE}
+  if [ "$?" -ne "0" ] ; then
+    echo "ERROR running npsim"
+    exit 1
+  fi
+fi
+
+### Step 3. Run the reconstruction (juggler)
+if [[ -n "${DO_REC}" || -n "${DO_ALL}" ]] ; then
+  for rec in options/*.py ; do
+    unset tag
+    [[ $(basename ${rec} .py) =~ (.*)\.(.*) ]] && tag=".${BASH_REMATCH[2]}"
+    JUGGLER_REC_FILE=${JUGGLER_REC_FILE/.root/${tag:-}.root} \
+    xenv -x ${JUGGLER_INSTALL_PREFIX}/Juggler.xenv \
+      gaudirun.py ${rec} || [ $? -eq 4 ]
+  done
+
+  root_filesize=$(stat --format=%s "${JUGGLER_REC_FILE}")
+  if [[ "${JUGGLER_N_EVENTS}" -lt "500" ]] ; then 
+    # file must be less than 10 MB to upload
+    if [[ "${root_filesize}" -lt "10000000" ]] ; then 
+      cp ${JUGGLER_REC_FILE} results/.
+    fi
+  fi
+fi
+
+### Step 4. Run the analysis code
+if [[ -n "${DO_ANALYSIS}" || -n "${DO_ALL}" ]] ; then
+  echo "Running analysis scripts"
+  rootls -t  ${JUGGLER_REC_FILE}
+
+  # Store all plots here (preferribly png and pdf files)
+  mkdir -p results/tcs
+
+  # here you can add as many scripts as you want.
+  root -b -q "benchmarks/tcs/analysis/tcs_tests.cxx+(\"${JUGGLER_REC_FILE}\")"
+  if [[ "$?" -ne "0" ]] ; then
+    echo "ERROR running root script"
+    exit 1
+  fi
+fi
+
+
+
-- 
GitLab