diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index eb6ca7ae0fb1427d8f07a0374e235bd8eaecb45c..86f311a8bb80da7d1718898ee1dbbaa13ff300de 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -28,6 +28,7 @@ stages:
   - initialize
   - data_init
   - simulate
+  - calibrate
   - benchmarks
   - collect
   - deploy
diff --git a/benchmarks/barrel_ecal/config.yml b/benchmarks/barrel_ecal/config.yml
index 5535659e2bbd6b0ce766415dc81cb685d1dac8f5..75406a39783d092445224e3082bb23750783f1d6 100644
--- a/benchmarks/barrel_ecal/config.yml
+++ b/benchmarks/barrel_ecal/config.yml
@@ -32,6 +32,17 @@ sim:emcal_barrel_pions_electrons:
     - bash benchmarks/barrel_ecal/run_emcal_barrel_electrons.sh
     - bash benchmarks/barrel_ecal/run_emcal_barrel_particles.sh piminus
 
+calib:emcal_barrel_electrons:
+  extends: .det_benchmark
+  stage: calibrate
+  needs:
+    - ["sim:emcal_barrel_electrons"]
+  script:
+    - ls -lhtR sim_output/
+    - rootls -t sim_output/sim_emcal_barrel_electron.root
+    - root -b -q 'benchmarks/barrel_ecal/scripts/emcal_barrel_particles_analysis.cxx+("electron", true)'
+    - echo "JSON file(s) from analysis:" ; cat results/*.json
+
 bench:emcal_barrel_pions:
   extends: .det_benchmark
   stage: benchmarks
@@ -40,24 +51,22 @@ bench:emcal_barrel_pions:
   script:
     - root -b -q benchmarks/barrel_ecal/scripts/emcal_barrel_pions_analysis.cxx+
 
-bench:emcal_barrel_pi0:
+bench:emcal_barrel_electrons_scan:
   extends: .det_benchmark
   stage: benchmarks
   needs:
-    - ["sim:emcal_barrel_pi0"]
+    - ["sim:emcal_barrel_electrons"]
   script:
-    - root -b -q benchmarks/barrel_ecal/scripts/emcal_barrel_pi0_analysis.cxx+
+    - if [[ "$RUN_EXTENDED_BENCHMARK" == "true" ]] ; then root -b -q 'benchmarks/barrel_ecal/scripts/emcal_barrel_energy_scan_analysis.cxx+("electron")' ; fi
 
-bench:emcal_barrel_electrons:
+bench:emcal_barrel_pi0:
   extends: .det_benchmark
   stage: benchmarks
   needs:
-    - ["sim:emcal_barrel_electrons"]
+    - ["sim:emcal_barrel_pi0", "calib:emcal_barrel_electrons"]
   script:
-    - ls -lhtR sim_output/
-    - rootls -t sim_output/sim_emcal_barrel_electron.root
-    - root -b -q 'benchmarks/barrel_ecal/scripts/emcal_barrel_particles_analysis.cxx+("electron")'
-    - if [[ "$RUN_EXTENDED_BENCHMARK" == "true" ]] ; then root -b -q 'benchmarks/barrel_ecal/scripts/emcal_barrel_energy_scan_analysis.cxx+("electron")' ; fi
+    - echo "JSON file(s) from analysis:" ; cat results/*.json
+    - root -b -q benchmarks/barrel_ecal/scripts/emcal_barrel_pi0_analysis.cxx+
 
 bench:emcal_barrel_photons:
   extends: .det_benchmark
@@ -67,7 +76,7 @@ bench:emcal_barrel_photons:
   script:
     - ls -lhtR sim_output/
     - rootls -t sim_output/sim_emcal_barrel_photon.root
-    - root -b -q 'benchmarks/barrel_ecal/scripts/emcal_barrel_particles_analysis.cxx+("photon")'
+    - root -b -q 'benchmarks/barrel_ecal/scripts/emcal_barrel_particles_analysis.cxx+("photon", false)'
     - if [[ "$RUN_EXTENDED_BENCHMARK" == "true" ]] ; then root -b -q 'benchmarks/barrel_ecal/scripts/emcal_barrel_energy_scan_analysis.cxx+("photon")' ; fi
 
 bench:emcal_barrel_pions_electrons:
@@ -85,7 +94,12 @@ collect_results:barrel_ecal:
   extends: .det_benchmark
   stage: collect
   needs: 
-    - ["bench:emcal_barrel_electrons", "bench:emcal_barrel_photons", "bench:emcal_barrel_pions", "bench:emcal_barrel_pi0", "bench:emcal_barrel_pions_electrons"]
+    - "calib:emcal_barrel_electrons"
+    - "bench:emcal_barrel_electrons_scan"
+    - "bench:emcal_barrel_photons"
+    - "bench:emcal_barrel_pions"
+    - "bench:emcal_barrel_pi0"
+    - "bench:emcal_barrel_pions_electrons"
   script:
     - ls -lrht
     - echo " FIX ME" 
diff --git a/benchmarks/barrel_ecal/run_emcal_barrel_energy_scan.sh b/benchmarks/barrel_ecal/run_emcal_barrel_energy_scan.sh
index b01aa080ea60310bc66391fc7397972939a09313..719a4f12136ce3f8cc4451d9791f45c01fd70212 100755
--- a/benchmarks/barrel_ecal/run_emcal_barrel_energy_scan.sh
+++ b/benchmarks/barrel_ecal/run_emcal_barrel_energy_scan.sh
@@ -10,7 +10,7 @@ if (( $JUGGLER_N_EVENTS < $MIN_N_EVENTS )); then
    echo "Setting JUGGLER_N_EVENTS to ${MIN_N_EVENTS}"
 fi
 #0.5 1 2 3 4 7 15 20
-for E in 0.5 1 2 3 4 7 15 20
+for E in 0.5 1 2 3 4 5 7 10 15 20
 do
    export E_START="$E"
    export E_END="$E"   
diff --git a/benchmarks/barrel_ecal/scripts/emcal_barrel_particles_analysis.cxx b/benchmarks/barrel_ecal/scripts/emcal_barrel_particles_analysis.cxx
index a1eb9d1459ff0e51354ed119cc9c89126e38f36a..4d52a6e5e8ddd47e0c24747591d529bc50070b3c 100644
--- a/benchmarks/barrel_ecal/scripts/emcal_barrel_particles_analysis.cxx
+++ b/benchmarks/barrel_ecal/scripts/emcal_barrel_particles_analysis.cxx
@@ -16,11 +16,13 @@
 #include "TH1.h"
 #include "TF1.h"
 #include "TH1D.h"
+#include <nlohmann/json.hpp>
 
 #include "emcal_barrel_common_functions.h"
 
 using ROOT::RDataFrame;
 using namespace ROOT::VecOps;
+using json = nlohmann::json;
 
 void save_canvas(TCanvas* c, std::string label)
 {
@@ -34,7 +36,7 @@ void save_canvas(TCanvas* c, std::string label, std::string particle_label)
   save_canvas(c, label_with_E);
 }
 
-void emcal_barrel_particles_analysis(std::string particle_name = "electron")
+void emcal_barrel_particles_analysis(std::string particle_name = "electron", bool save_calib = false)
 {
   // Setting for graphs
   gROOT->SetStyle("Plain");
@@ -47,13 +49,18 @@ void emcal_barrel_particles_analysis(std::string particle_name = "electron")
   gStyle->SetPadLeftMargin(0.14);
   gStyle->SetPadRightMargin(0.14);
 
+  json j;
+  // variables that will be saved in the JSON file
+  double Ethr_mean;
+  double fSam_mean;
+
   ROOT::EnableImplicitMT();
   std::string input_fname = fmt::format("sim_output/sim_emcal_barrel_{}.root", particle_name);
   ROOT::RDataFrame d0("events", input_fname);
 
   // Environment Variables
   std::string detector_path = "";
-  std::string detector_name = "topside";
+  std::string detector_name = "athena";
   if(std::getenv("DETECTOR_PATH")) {
     detector_path = std::getenv("DETECTOR_PATH");
   }
@@ -117,6 +124,7 @@ void emcal_barrel_particles_analysis(std::string particle_name = "electron")
     TCanvas* c1 = new TCanvas("c1", "c1", 700, 500);
     c1->SetLogy(1);
     auto h = hEthr->DrawCopy();
+    Ethr_mean = h->GetMean();
     h->SetLineWidth(2);
     h->SetLineColor(kBlue);
     save_canvas(c1,"Ethr",particle_name);
@@ -154,9 +162,22 @@ void emcal_barrel_particles_analysis(std::string particle_name = "electron")
     h->Fit("gaus", "", "", down_fit, up_fit);
     h->GetXaxis()->SetRangeUser(0.,up_fit);
     TF1 *gaus = h->GetFunction("gaus");
+    fSam_mean = gaus->GetParameter(1);
     gaus->SetLineWidth(2);
     gaus->SetLineColor(kRed); 
     save_canvas(c4,"fsam",particle_name);
   }
+
+  j[particle_name] = {
+    {"particle_name", particle_name},
+    {"thrown_energy", Ethr_mean},
+    {"sampling_fraction", fSam_mean}
+  };
+  if (save_calib) {
+    std::string calib_output_path = "results/emcal_barrel_calibration.json";
+    std::cout << "Saving calibration results to " << calib_output_path << std::endl;
+    std::ofstream o(calib_output_path);
+    o << std::setw(4) << j << std::endl;
+  }
 }
 
diff --git a/benchmarks/barrel_ecal/scripts/emcal_barrel_pi0_analysis.cxx b/benchmarks/barrel_ecal/scripts/emcal_barrel_pi0_analysis.cxx
index 3fa30561f652e32c1cb296f403fb87f64631ee2b..a63d15d76c57b0605cc0fcde3b5a6243a9227456 100644
--- a/benchmarks/barrel_ecal/scripts/emcal_barrel_pi0_analysis.cxx
+++ b/benchmarks/barrel_ecal/scripts/emcal_barrel_pi0_analysis.cxx
@@ -20,9 +20,11 @@
 #include "TF1.h"
 #include "TH1D.h"
 #include "TFitResult.h"
+#include <nlohmann/json.hpp>
 
 using ROOT::RDataFrame;
 using namespace ROOT::VecOps;
+using json = nlohmann::json;
 
 void emcal_barrel_pi0_analysis(const char* input_fname = "sim_output/sim_emcal_barrel_pi0.root")
 {
@@ -56,12 +58,15 @@ void emcal_barrel_pi0_analysis(const char* input_fname = "sim_output/sim_emcal_b
        {"quantity", "resolution (in %)"},
        {"target", std::to_string(resolutionTarget)}}};
 
+  json j;
+  std::ifstream prev_steps_ifstream("results/emcal_barrel_calibration.json");
+  prev_steps_ifstream >> j;
 
   ROOT::EnableImplicitMT();
   ROOT::RDataFrame d0("events", input_fname);
 
   // Sampling Fraction
-  double samp_frac = 0.0136;
+  double samp_frac = j["electron"]["sampling_fraction"];
 
   // Thrown Energy [GeV]
   auto Ethr = [](std::vector<dd4pod::Geant4ParticleData> const& input) {
@@ -139,7 +144,7 @@ void emcal_barrel_pi0_analysis(const char* input_fname = "sim_output/sim_emcal_b
   auto hEthr  = d1.Histo1D({"hEthr",  "Thrown Energy; Thrown Energy [GeV]; Events",        100,  0.0,    7.5}, "Ethr");
   auto hNhits = d1.Histo1D({"hNhits", "Number of hits per events; Number of hits; Events", 100,  0.0, 2000.0}, "nhits");
   auto hEsim  = d1.Histo1D({"hEsim",  "Energy Deposit; Energy Deposit [GeV]; Events",      100,  0.0,    1.0}, "Esim");
-  auto hfsam  = d1.Histo1D({"hfsam",  "Sampling Fraction; Sampling Fraction; Events",      100,  0.0,    0.1}, "fsam");
+  auto hfsam  = d1.Histo1D({"hfsam",  "Sampling Fraction; Sampling Fraction; Events",      150,  0.0,    0.15}, "fsam");
   auto hpid   = d1.Histo1D({"hpid",   "PID; PID; Count",                                   100,  -220,   220}, "pid");
   auto hdau   = d1.Histo1D({"hdau",   "Number of Daughters; Number of Daughters; Count",   10,   0,      10},  "dau");