modified: TrackRecon.C bookkeeping + introducing CO2 dependent Eloss + diagnostic plots to figure out teh slope correection for the PC model_invert
new file: eloss_calculations/alpha_lookup_20MeV_3pc_350Torr.dat new file: eloss_calculations/alpha_lookup_20MeV_4pc_350Torr.dat new file: eloss_calculations/aluminum_lookup_80MeV_3pc_350Torr.dat new file: eloss_calculations/aluminum_lookup_80MeV_4pc_350Torr.dat new file: eloss_calculations/fluorine_lookup_70MeV_3pc_350Torr.dat new file: eloss_calculations/fluorine_lookup_70MeV_4pc_350Torr.dat new file: eloss_calculations/oxygen_lookup_70MeV_3pc_350Torr.dat new file: eloss_calculations/oxygen_lookup_70MeV_4pc_350Torr.dat new file: eloss_calculations/proton_lookup_20MeV_3pc_350Torr.dat new file: eloss_calculations/proton_lookup_20MeV_4pc_350Torr.dat modified: run_tr.sh book keeping new file: scan_slope_runs.sh diagnostic plots to figure out the slope correection for the PC model_invert new file: scratch/plot_slope_scan.C diagnostic plots to figure out the slope correection for the PC model_invert
This commit is contained in:
parent
948c6e6ea2
commit
8dd6526221
61
TrackRecon.C
61
TrackRecon.C
|
|
@ -39,9 +39,9 @@ Int_t colors[40] = {
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
bool process_alpha_proton_scattering = false;
|
bool process_alpha_proton_scattering = false;
|
||||||
bool doMiscHistograms = true;
|
bool doMiscHistograms = false;
|
||||||
bool doPCSX3ClusterAnalysis = false;
|
bool doPCSX3ClusterAnalysis = true;
|
||||||
bool doPCQQQClusterAnalysis = false;
|
bool doPCQQQClusterAnalysis = true;
|
||||||
bool doOldAnalysis = false;
|
bool doOldAnalysis = false;
|
||||||
bool do27AlapAnalysis = false;
|
bool do27AlapAnalysis = false;
|
||||||
double source_vertex = 53; // 53
|
double source_vertex = 53; // 53
|
||||||
|
|
@ -169,7 +169,7 @@ void TrackRecon::Begin(TTree * /*tree*/)
|
||||||
source_vertex = (double)std::atof(std::string(getenv("source_vertex")).c_str());
|
source_vertex = (double)std::atof(std::string(getenv("source_vertex")).c_str());
|
||||||
|
|
||||||
if (getenv("CO2percent"))
|
if (getenv("CO2percent"))
|
||||||
CO2percent = (double)std::atof((getenv("CO2percent")));
|
CO2percent = std::atoi(getenv("CO2percent"));
|
||||||
std::cout << "CO2 percent set to " << CO2percent << std::endl;
|
std::cout << "CO2 percent set to " << CO2percent << std::endl;
|
||||||
|
|
||||||
pwinstance.ConstructGeo();
|
pwinstance.ConstructGeo();
|
||||||
|
|
@ -266,12 +266,29 @@ void TrackRecon::Begin(TTree * /*tree*/)
|
||||||
|
|
||||||
// ------------- ELOSS Correction read in from tables -------------
|
// ------------- ELOSS Correction read in from tables -------------
|
||||||
|
|
||||||
if (CO2percent == 4)
|
if (dataset == "17F" && CO2percent == 3)
|
||||||
|
{
|
||||||
|
MeV_to_cm = new TGraph("eloss_calculations/alpha_lookup_20MeV_3pc.dat", "%lf %*lf %lf");
|
||||||
|
MeV_to_cm_p = new TGraph("eloss_calculations/proton_lookup_20MeV_3pc.dat", "%lf %*lf %lf");
|
||||||
|
MeV_to_cm_27Al = new TGraph("eloss_calculations/aluminum_lookup_80MeV_3pc.dat", "%lf %*lf %lf");
|
||||||
|
MeV_to_cm_17F = new TGraph("eloss_calculations/fluorine_lookup_70MeV_3pc.dat", "%lf %*lf %lf");
|
||||||
|
|
||||||
|
// MeV_to_cm = new TGraph("eloss_calculations/alpha_lookup_20MeV_3pc_350Torr.dat", "%lf %*lf %lf");
|
||||||
|
// MeV_to_cm_p = new TGraph("eloss_calculations/proton_lookup_20MeV_3pc_350Torr.dat", "%lf %*lf %lf");
|
||||||
|
// MeV_to_cm_17F = new TGraph("eloss_calculations/fluorine_lookup_70MeV_3pc_350Torr.dat", "%lf %*lf %lf");
|
||||||
|
// MeV_to_cm_27Al = new TGraph("eloss_calculations/aluminum_lookup_80MeV_3pc_350Torr.dat", "%lf %*lf %lf");
|
||||||
|
}
|
||||||
|
else if (dataset == "17F" && CO2percent == 4)
|
||||||
{
|
{
|
||||||
MeV_to_cm = new TGraph("eloss_calculations/alpha_lookup_20MeV_4pc.dat", "%lf %*lf %lf");
|
MeV_to_cm = new TGraph("eloss_calculations/alpha_lookup_20MeV_4pc.dat", "%lf %*lf %lf");
|
||||||
MeV_to_cm_p = new TGraph("eloss_calculations/proton_lookup_20MeV_4pc.dat", "%lf %*lf %lf");
|
MeV_to_cm_p = new TGraph("eloss_calculations/proton_lookup_20MeV_4pc.dat", "%lf %*lf %lf");
|
||||||
MeV_to_cm_27Al = new TGraph("eloss_calculations/aluminum_lookup_80MeV_4pc.dat", "%lf %*lf %lf");
|
MeV_to_cm_27Al = new TGraph("eloss_calculations/aluminum_lookup_80MeV_4pc.dat", "%lf %*lf %lf");
|
||||||
MeV_to_cm_17F = new TGraph("eloss_calculations/fluorine_lookup_70MeV_4pc.dat", "%lf %*lf %lf");
|
MeV_to_cm_17F = new TGraph("eloss_calculations/fluorine_lookup_70MeV_4pc.dat", "%lf %*lf %lf");
|
||||||
|
|
||||||
|
// MeV_to_cm = new TGraph("eloss_calculations/alpha_lookup_20MeV_4pc_350Torr.dat", "%lf %*lf %lf");
|
||||||
|
// MeV_to_cm_p = new TGraph("eloss_calculations/proton_lookup_20MeV_4pc_350Torr.dat", "%lf %*lf %lf");
|
||||||
|
// MeV_to_cm_17F = new TGraph("eloss_calculations/fluorine_lookup_70MeV_4pc_350Torr.dat", "%lf %*lf %lf");
|
||||||
|
// MeV_to_cm_27Al = new TGraph("eloss_calculations/aluminum_lookup_80MeV_4pc_350Torr.dat", "%lf %*lf %lf");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -1068,13 +1085,13 @@ Bool_t TrackRecon::Process(Long64_t entry)
|
||||||
double beam_path_length = TMath::Abs(vertex_recon - z_entrance) * 0.1;
|
double beam_path_length = TMath::Abs(vertex_recon - z_entrance) * 0.1;
|
||||||
|
|
||||||
#ifdef AL_BEAM
|
#ifdef AL_BEAM
|
||||||
double beam_energy_at_vertex = cm_to_MeV_27Al->Eval(MeV_to_cm_27Al->Eval(72.0) - beam_path_length);
|
double beam_energy_at_vertex = cm_to_MeV_27Al->Eval(MeV_to_cm_27Al->Eval(65.195) - beam_path_length); // 72MeV is the energy of the 27Al beam right ebfore teh chamber
|
||||||
Kinematics apkin_p(mass_27Al, mass_4He, mass_1H, mass_30Si, beam_energy_at_vertex / mass_27Al);
|
Kinematics apkin_p(mass_27Al, mass_4He, mass_1H, mass_30Si, beam_energy_at_vertex / mass_27Al);
|
||||||
Kinematics apkin_a(mass_27Al, mass_4He, mass_4He, mass_30Si, beam_energy_at_vertex / mass_27Al);
|
Kinematics apkin_a(mass_27Al, mass_4He, mass_4He, mass_30Si, beam_energy_at_vertex / mass_27Al);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef F_BEAM
|
#ifdef F_BEAM
|
||||||
double beam_energy_at_vertex = cm_to_MeV_17F->Eval(MeV_to_cm_17F->Eval(65.0) - beam_path_length);
|
double beam_energy_at_vertex = cm_to_MeV_17F->Eval(MeV_to_cm_17F->Eval(60.741) - beam_path_length); // 67.8 MeV iws the energy of the 17F beam right before the chamber
|
||||||
Kinematics apkin_p(mass_17F, mass_4He, mass_1H, mass_20Ne, beam_energy_at_vertex / mass_17F);
|
Kinematics apkin_p(mass_17F, mass_4He, mass_1H, mass_20Ne, beam_energy_at_vertex / mass_17F);
|
||||||
Kinematics apkin_a(mass_17F, mass_4He, mass_4He, mass_20Ne, beam_energy_at_vertex / mass_17F);
|
Kinematics apkin_a(mass_17F, mass_4He, mass_4He, mass_20Ne, beam_energy_at_vertex / mass_17F);
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -1233,8 +1250,14 @@ void protonAlphaHistograms(HistPlotter *plotter, std::vector<Event> QQQ_Events,
|
||||||
|
|
||||||
// Sidetrack for a(p,p)
|
// Sidetrack for a(p,p)
|
||||||
std::string aplabel = "a(p,p)";
|
std::string aplabel = "a(p,p)";
|
||||||
Kinematics apkin_p(1.008664916, 4.002603254, 1.008664916, 4.002603254, 7.0); // m3 is proton
|
double initial_energy = 7.0;
|
||||||
Kinematics apkin_a(1.008664916, 4.002603254, 4.002603254, 1.008664916, 7.0); // m3 is alpha
|
if (dataset == "27Al")
|
||||||
|
initial_energy = 6.79;
|
||||||
|
if (dataset == "17F")
|
||||||
|
initial_energy = 6.78;
|
||||||
|
|
||||||
|
Kinematics apkin_p(1.008664916, 4.002603254, 1.008664916, 4.002603254, initial_energy); // m3 is proton
|
||||||
|
Kinematics apkin_a(1.008664916, 4.002603254, 4.002603254, 1.008664916, initial_energy); // m3 is alpha
|
||||||
|
|
||||||
for (auto qqqevent : QQQ_Events)
|
for (auto qqqevent : QQQ_Events)
|
||||||
{
|
{
|
||||||
|
|
@ -1397,6 +1420,7 @@ void PCSX3ClusterAnalysis(HistPlotter *plotter, std::vector<Event> QQQ_Events, s
|
||||||
double t_minimum = -1.0 * (x1.X() * v.X() + x1.Y() * v.Y()) / (v.X() * v.X() + v.Y() * v.Y());
|
double t_minimum = -1.0 * (x1.X() * v.X() + x1.Y() * v.Y()) / (v.X() * v.X() + v.Y() * v.Y());
|
||||||
TVector3 vector_closest_to_z_sx3 = x1 + t_minimum * v;
|
TVector3 vector_closest_to_z_sx3 = x1 + t_minimum * v;
|
||||||
plotter->Fill1D("VertexReconZ_SX3" + std::to_string(PCSX3TimeCut), 600, -1300, 1300, vector_closest_to_z_sx3.Z(), "hPCZSX3");
|
plotter->Fill1D("VertexReconZ_SX3" + std::to_string(PCSX3TimeCut), 600, -1300, 1300, vector_closest_to_z_sx3.Z(), "hPCZSX3");
|
||||||
|
plotter->Fill1D("VertexReconZ_SX3", 600, -1300, 1300, vector_closest_to_z_sx3.Z());
|
||||||
plotter->Fill2D("VertexReconXY_SX3" + std::to_string(PCSX3TimeCut), 100, -100, 100, 100, -100, 100, vector_closest_to_z_sx3.X(), vector_closest_to_z_sx3.Y(), "hPCZSX3");
|
plotter->Fill2D("VertexReconXY_SX3" + std::to_string(PCSX3TimeCut), 100, -100, 100, 100, -100, 100, vector_closest_to_z_sx3.X(), vector_closest_to_z_sx3.Y(), "hPCZSX3");
|
||||||
|
|
||||||
plotter->Fill2D("pcz_vs_time", 2000, 0, 2000, 600, -200, 200, pcevent.Time1 * 1e-9, pcevent.pos.Z()); // x-axis is all Si det, y-axis is PC anode+cathode only
|
plotter->Fill2D("pcz_vs_time", 2000, 0, 2000, 600, -200, 200, pcevent.Time1 * 1e-9, pcevent.pos.Z()); // x-axis is all Si det, y-axis is PC anode+cathode only
|
||||||
|
|
@ -1419,7 +1443,10 @@ void PCSX3ClusterAnalysis(HistPlotter *plotter, std::vector<Event> QQQ_Events, s
|
||||||
plotter->Fill1D("VertexRecon_pczfix", 800, -300, 300, r_rhoMin_fix.Z());
|
plotter->Fill1D("VertexRecon_pczfix", 800, -300, 300, r_rhoMin_fix.Z());
|
||||||
plotter->Fill1D("pczfix_A1C2_1d_sx3", 600, -200, 200, pcz_fix);
|
plotter->Fill1D("pczfix_A1C2_1d_sx3", 600, -200, 200, pcz_fix);
|
||||||
plotter->Fill2D("pczfix_vs_sx3pczguess_A1C2", 600, -200, 200, 600, -200, 200, pczguess, pcz_fix);
|
plotter->Fill2D("pczfix_vs_sx3pczguess_A1C2", 600, -200, 200, 600, -200, 200, pczguess, pcz_fix);
|
||||||
plotter->Fill2D("pcz_vs_sx3pczguess_A1C2_strip" + std::to_string(sx3event.ch2), 300, -200, 200, 600, -200, 200, pczguess, pcevent.pos.Z());
|
plotter->Fill2D("pczfix_residual_vs_pczguess_A1C2", 600, -200, 200, 200, -100, 100, pczguess, pcz_fix - pczguess);
|
||||||
|
plotter->Fill2D("pczfix_residual_vs_phi_A1C2", 200, 0, 6.28, 200, -100, 100, r_rhoMin_fix.Phi(), pcz_fix - pczguess);
|
||||||
|
plotter->Fill1D("pczfix-sx3pczguess_A1C2", 200, -100, 100, pcz_fix - pczguess);
|
||||||
|
plotter->Fill2D("pczfix_vs_sx3pczguess_A1C2_strip" + std::to_string(sx3event.ch2), 300, -200, 200, 600, -200, 200, pczguess, pcevent.pos.Z());
|
||||||
|
|
||||||
double sinTheta_customV = TMath::Sin((sx3event.pos - TVector3(0, 0, r_rhoMin_fix.Z())).Theta());
|
double sinTheta_customV = TMath::Sin((sx3event.pos - TVector3(0, 0, r_rhoMin_fix.Z())).Theta());
|
||||||
plotter->Fill2D("dE3_E_CathodeSX3_A1C2_TC" + std::to_string(PCSX3TimeCut) + "_PC" + std::to_string(phicut), 400, 0, 30, 800, 0, 10000, sx3event.Energy1, pcevent.Energy2 * sinTheta_customV);
|
plotter->Fill2D("dE3_E_CathodeSX3_A1C2_TC" + std::to_string(PCSX3TimeCut) + "_PC" + std::to_string(phicut), 400, 0, 30, 800, 0, 10000, sx3event.Energy1, pcevent.Energy2 * sinTheta_customV);
|
||||||
|
|
@ -2034,9 +2061,15 @@ void miscHistograms_oneWire(HistPlotter *plotter, std::vector<Event> QQQ_Events,
|
||||||
{
|
{
|
||||||
// consider the 'proton-like' QQQ branch seen in a,p data
|
// consider the 'proton-like' QQQ branch seen in a,p data
|
||||||
TRandom3 rand;
|
TRandom3 rand;
|
||||||
rand.SetSeed(); // random seed set
|
rand.SetSeed(); // random seed setW
|
||||||
// Kinematics apkin_a(1.008664916, 4.002603254, 4.002603254, 1.008664916, 6.34); // m3 is alpha, 6.411 MeV is 7.0 MeV proton energy after havar+mylar+kapton+100mm 4He gas (molar mass 5.3, 250 torr)
|
double initial_energy = 7.0;
|
||||||
Kinematics apkin_a(1.008664916, 4.002603254, 4.002603254, 1.008664916, 6.79); // m3 is alpha, 6.79 MeV is 7.0 MeV proton energy after kapton+100mm 4He gas (molar mass 5.2, 250 torr)
|
if (dataset == "27Al") /// m3 is alpha, 6.79 MeV is 7.0 MeV proton energy after kapton+100mm 4He gas (molar mass 5.6, 250 torr)
|
||||||
|
initial_energy = 6.79;
|
||||||
|
if (dataset == "17F")
|
||||||
|
initial_energy = 6.78; // m3 is alpha, 6.79 MeV is 7.0 MeV proton energy after kapton+100mm 4He gas (molar mass 5.6, 350 torr)
|
||||||
|
// initial_energy = 6.32; // m3 is alpha, 6.411 MeV is 7.0 MeV proton energy after havar+mylar+kapton+100mm 4He gas (molar mass 5.3, 250 torr)
|
||||||
|
|
||||||
|
Kinematics apkin_a(1.008664916, 4.002603254, 4.002603254, 1.008664916, initial_energy);
|
||||||
for (auto qqqevent : QQQ_Events)
|
for (auto qqqevent : QQQ_Events)
|
||||||
{
|
{
|
||||||
if (qqqevent.Energy1 < 0.6)
|
if (qqqevent.Energy1 < 0.6)
|
||||||
|
|
@ -2126,7 +2159,7 @@ void protonMiscHistograms(HistPlotter *plotter, std::vector<Event> QQQ_Events, s
|
||||||
if (dataset == "27Al")
|
if (dataset == "27Al")
|
||||||
initial_energy = 6.79; // m3 is alpha, 6.79 MeV is 7.0 MeV proton energy after kapton+100mm 4He gas (molar mass 5.2, 250 torr)
|
initial_energy = 6.79; // m3 is alpha, 6.79 MeV is 7.0 MeV proton energy after kapton+100mm 4He gas (molar mass 5.2, 250 torr)
|
||||||
if (dataset == "17F")
|
if (dataset == "17F")
|
||||||
initial_energy = 6.34; // m3 is alpha, 6.411 MeV is 7.0 MeV proton energy after Havar+kapton+100mm 4He gas (molar mass 5.2, 250 torr)
|
initial_energy = 6.32; // m3 is alpha, 6.411 MeV is 7.0 MeV proton energy after Havar+kapton+100mm 4He gas (molar mass 5.2, 250 torr)
|
||||||
|
|
||||||
Kinematics apkin_a(1.008664916, 4.002603254, 4.002603254, 1.008664916, initial_energy); // m3 is alpha
|
Kinematics apkin_a(1.008664916, 4.002603254, 4.002603254, 1.008664916, initial_energy); // m3 is alpha
|
||||||
|
|
||||||
|
|
|
||||||
31981
eloss_calculations/alpha_lookup_20MeV_3pc_350Torr.dat
Normal file
31981
eloss_calculations/alpha_lookup_20MeV_3pc_350Torr.dat
Normal file
File diff suppressed because it is too large
Load Diff
31981
eloss_calculations/alpha_lookup_20MeV_4pc_350Torr.dat
Normal file
31981
eloss_calculations/alpha_lookup_20MeV_4pc_350Torr.dat
Normal file
File diff suppressed because it is too large
Load Diff
4366
eloss_calculations/aluminum_lookup_80MeV_3pc_350Torr.dat
Normal file
4366
eloss_calculations/aluminum_lookup_80MeV_3pc_350Torr.dat
Normal file
File diff suppressed because it is too large
Load Diff
4366
eloss_calculations/aluminum_lookup_80MeV_4pc_350Torr.dat
Normal file
4366
eloss_calculations/aluminum_lookup_80MeV_4pc_350Torr.dat
Normal file
File diff suppressed because it is too large
Load Diff
6941
eloss_calculations/fluorine_lookup_70MeV_3pc_350Torr.dat
Normal file
6941
eloss_calculations/fluorine_lookup_70MeV_3pc_350Torr.dat
Normal file
File diff suppressed because it is too large
Load Diff
6941
eloss_calculations/fluorine_lookup_70MeV_4pc_350Torr.dat
Normal file
6941
eloss_calculations/fluorine_lookup_70MeV_4pc_350Torr.dat
Normal file
File diff suppressed because it is too large
Load Diff
8548
eloss_calculations/oxygen_lookup_70MeV_3pc_350Torr.dat
Normal file
8548
eloss_calculations/oxygen_lookup_70MeV_3pc_350Torr.dat
Normal file
File diff suppressed because it is too large
Load Diff
8548
eloss_calculations/oxygen_lookup_70MeV_4pc_350Torr.dat
Normal file
8548
eloss_calculations/oxygen_lookup_70MeV_4pc_350Torr.dat
Normal file
File diff suppressed because it is too large
Load Diff
397468
eloss_calculations/proton_lookup_20MeV_3pc_350Torr.dat
Normal file
397468
eloss_calculations/proton_lookup_20MeV_3pc_350Torr.dat
Normal file
File diff suppressed because it is too large
Load Diff
397468
eloss_calculations/proton_lookup_20MeV_4pc_350Torr.dat
Normal file
397468
eloss_calculations/proton_lookup_20MeV_4pc_350Torr.dat
Normal file
File diff suppressed because it is too large
Load Diff
60
run_tr.sh
60
run_tr.sh
|
|
@ -11,8 +11,8 @@ root -q -l -b -e '.L TrackRecon.C++O'
|
||||||
process_run() {
|
process_run() {
|
||||||
local wrun=$(printf "%03d" "$1")
|
local wrun=$(printf "%03d" "$1")
|
||||||
local prefix="${PREFIX:-Run_}"
|
local prefix="${PREFIX:-Run_}"
|
||||||
local outdir="${OUT_DIR:-output}" # Defaults to 'output' if OUT_DIR is not set
|
local outdir="${OUT_DIR:-Output_default}"
|
||||||
local out="$Output_{outdir}/results_run${wrun}.root"
|
local out="${outdir}/results_run${wrun}.root"
|
||||||
|
|
||||||
# Ensure the directory exists so ROOT doesn't fail silently
|
# Ensure the directory exists so ROOT doesn't fail silently
|
||||||
mkdir -p "$outdir"
|
mkdir -p "$outdir"
|
||||||
|
|
@ -27,16 +27,16 @@ process_run() {
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
export -f process_run
|
export -f process_run
|
||||||
export -f process_run
|
|
||||||
|
|
||||||
export CO2percent=3
|
export CO2percent=3
|
||||||
|
|
||||||
# --- Block 1: 27Al Source Runs No Gas (1-8) ---
|
# --- Block 1: 27Al Source Runs No Gas (1-8) ---
|
||||||
if [[ 1 -eq 0 ]]; then
|
if [[ 1 -eq 0 ]]; then
|
||||||
export DATASET="27Al"
|
export DATASET="27Al"
|
||||||
export PREFIX="Run_"
|
export PREFIX="Run_"
|
||||||
export OUT_DIR="av"
|
export OUT_DIR="Output_av"
|
||||||
echo "Starting parallel processing for 27Al runs..."
|
echo "Starting parallel processing for 27Al runs..."
|
||||||
rm -f p_output/all.root
|
rm -f ${OUT_DIR}/all.root
|
||||||
|
|
||||||
parallel --bar -j 6 process_run ::: {1..8}
|
parallel --bar -j 6 process_run ::: {1..8}
|
||||||
fi
|
fi
|
||||||
|
|
@ -45,81 +45,75 @@ fi
|
||||||
if [[ 1 -eq 0 ]]; then
|
if [[ 1 -eq 0 ]]; then
|
||||||
export DATASET="27Al"
|
export DATASET="27Al"
|
||||||
export PREFIX="Run_"
|
export PREFIX="Run_"
|
||||||
export timecut_low=400.0
|
export OUT_DIR="Output_a"
|
||||||
export source_vertex=53.44
|
|
||||||
export OUT_DIR="a"
|
|
||||||
echo "Processing 27Al alpha+gas runs..."
|
echo "Processing 27Al alpha+gas runs..."
|
||||||
parallel --bar -j 6 process_run ::: 9 12
|
export source_vertex=-5.36; export timecut_low=12.0; export timecut_high=119.0; process_run 9 "$slope"
|
||||||
|
export source_vertex=53.44; export timecut_low=400.0; process_run 12 "$slope"
|
||||||
|
|
||||||
unset timecut_low
|
unset timecut_low
|
||||||
|
unset timecut_high
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# --- Block 3: 27Al Protons+Gas Runs (15, 17-22) ---
|
# --- Block 3: 27Al Protons+Gas Runs (15, 17-22) ---
|
||||||
if [[ 1 -eq 1 ]]; then
|
if [[ 1 -eq 0 ]]; then
|
||||||
export DATASET="27Al"
|
export DATASET="27Al"
|
||||||
export PREFIX="Run_"
|
export PREFIX="Run_"
|
||||||
export OUT_DIR="p"
|
export OUT_DIR="Output_p"
|
||||||
export source_vertex=-200.0 # Source on the entrance window
|
export source_vertex=-200.0 # Source on the entrance window
|
||||||
echo "Starting parallel processing for 27Al proton runs..."
|
echo "Starting parallel processing for 27Al proton runs..."
|
||||||
# rm -f p_output/all.root
|
|
||||||
|
|
||||||
parallel --bar -j 6 process_run ::: 15 {17..22}
|
parallel --bar -j 6 process_run ::: 15 {17..22}
|
||||||
hadd -j 4 -k p_output/Al_protons.root p_output/results_run0{17..22}.root
|
hadd -j 4 -k ${OUT_DIR}/Al_protons.root ${OUT_DIR}/results_run0{17..22}.root
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# --- Block 4: 17F Source Runs (5-14) ---
|
# --- Block 4: 17F Source Runs (5-14) ---
|
||||||
if [[ 1 -eq 0 ]]; then
|
if [[ 1 -eq 0 ]]; then
|
||||||
export DATASET="17F"
|
export DATASET="17F"
|
||||||
export PREFIX="Source_"
|
export PREFIX="Source_"
|
||||||
export OUT_DIR="av"
|
export OUT_DIR="Output_av"
|
||||||
echo "Starting parallel processing for 17F source runs..."
|
echo "Starting parallel processing for 17F source runs..."
|
||||||
# rm -f p_output/all.root
|
|
||||||
|
|
||||||
parallel --bar -j 6 process_run ::: {5..13}
|
parallel --bar -j 6 process_run ::: {5..13}
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# --- Block 5: 17F Alpha Run with Gas (18-21) ---
|
# --- Block 5: 17F Alpha Run with Gas (18-21) ---
|
||||||
if [[ 1 -eq 0 ]]; then
|
if [[ 1 -eq 1 ]]; then
|
||||||
export DATASET="17F"
|
export DATASET="17F"
|
||||||
export PREFIX="SourceRun_"
|
export PREFIX="SourceRun_"
|
||||||
export OUT_DIR="a"
|
export OUT_DIR="Output_a"
|
||||||
echo "Processing 17F alpha runs with dynamic source vertices..."
|
echo "Processing 17F alpha runs with dynamic source vertices..."
|
||||||
|
|
||||||
# Running sequentially since the source_vertex variable changes per run
|
# Running sequentially since the source_vertex variable changes per run
|
||||||
export source_vertex=53.44; process_run 18
|
# export source_vertex=53.44; process_run 18
|
||||||
export source_vertex=14.24; process_run 19
|
export source_vertex=14.24; process_run 19
|
||||||
export source_vertex=-24.96; process_run 20
|
# export source_vertex=-24.96; process_run 20
|
||||||
export source_vertex=-73.96; process_run 21
|
# export source_vertex=-73.96; process_run 21
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# --- Block 6: 17F Proton Data ---
|
# --- Block 6: 17F Proton Data ---
|
||||||
if [[ 1 -eq 1 ]]; then
|
if [[ 1 -eq 0 ]]; then
|
||||||
export DATASET="17F"
|
export DATASET="17F"
|
||||||
export PREFIX="ProtonRun_"
|
export PREFIX="ProtonRun_"
|
||||||
export OUT_DIR="p"
|
export OUT_DIR="Output_p"
|
||||||
export source_vertex=-57.28
|
export source_vertex=-57.28
|
||||||
parallel --bar -j 6 process_run ::: {44..48} #3CO2
|
|
||||||
hadd -j 4 -k p_output/3pc.root p_output/results_run0{44..48}.root
|
# parallel --bar -j 6 process_run ::: {44..48} #3% CO2
|
||||||
|
# hadd -j 4 -k ${OUT_DIR}/3pc.root ${OUT_DIR}/results_run0{44..48}.root
|
||||||
|
|
||||||
export CO2percent=4
|
export CO2percent=4
|
||||||
parallel --bar -j 6 process_run ::: {38..42} #4% CO2
|
parallel --bar -j 6 process_run ::: {38..42} #4% CO2
|
||||||
hadd -j 4 -k p_output/4pc.root p_output/results_run0{38..42}.root
|
hadd -j 4 -k ${OUT_DIR}/4pc.root ${OUT_DIR}/results_run0{38..42}.root
|
||||||
exit
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# ==========================================
|
# ==========================================
|
||||||
# Cleanup Environment Variables
|
# Cleanup Environment Variables
|
||||||
# ==========================================
|
# ==========================================
|
||||||
unset flipa
|
unset source_vertex
|
||||||
unset flipc
|
|
||||||
unset anode_offset
|
|
||||||
unset cathode_offset
|
|
||||||
unset source_vertex # Fixed typo here
|
|
||||||
unset DATASET
|
unset DATASET
|
||||||
unset OUT_DIR
|
unset OUT_DIR
|
||||||
unset PREFIX
|
unset PREFIX
|
||||||
unset flip180
|
unset CO2percent
|
||||||
unset timecut_low
|
unset timecut_low
|
||||||
unset timecut_high
|
unset timecut_high
|
||||||
unset CO2percent
|
|
||||||
|
|
||||||
echo "Script execution finished."
|
echo "Script execution finished."
|
||||||
56
scan_slope_runs.sh
Normal file
56
scan_slope_runs.sh
Normal file
|
|
@ -0,0 +1,56 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# Scans model_invert slope from 0.44 to 0.56 (step 0.02).
|
||||||
|
# For each slope: patches PC_StepLadder_Correction.h, recompiles,
|
||||||
|
# runs all source runs, saves results under slope_scan/run<NNN>/slope_<val>.root
|
||||||
|
|
||||||
|
set -e
|
||||||
|
CORRECTION_H="Armory/PC_StepLadder_Correction.h"
|
||||||
|
SCAN_DIR="slope_scan"
|
||||||
|
|
||||||
|
process_run() {
|
||||||
|
local wrun=$(printf "%03d" "$1")
|
||||||
|
local slope="$2"
|
||||||
|
local outdir="${SCAN_DIR}/run${wrun}"
|
||||||
|
mkdir -p "$outdir"
|
||||||
|
local out="${outdir}/slope_${slope}.root"
|
||||||
|
root -q -l -b -x "../ANASEN_analysis/data/${DATASET}_Data/${PREFIX}${wrun}_mapped.root" \
|
||||||
|
-e "tree->Process(\"TrackRecon.C+\", \"${out}\")" > /dev/null 2>&1
|
||||||
|
[ -f "$out" ] && echo " run $wrun slope $slope OK" || echo " run $wrun slope $slope FAILED"
|
||||||
|
}
|
||||||
|
export -f process_run
|
||||||
|
export SCAN_DIR
|
||||||
|
|
||||||
|
for slope_x100 in 40 42 44 46 48 50 52 54 56 58 60 62 64 66; do
|
||||||
|
# for slope_x100 in 58 60 62 64 66; do
|
||||||
|
slope=$(awk "BEGIN{printf \"%.2f\", $slope_x100/100}")
|
||||||
|
echo "=== slope=${slope} ==="
|
||||||
|
|
||||||
|
sed -i "s/double slope = [0-9.]*/double slope = ${slope}/" "$CORRECTION_H"
|
||||||
|
|
||||||
|
echo " Compiling..."
|
||||||
|
root -q -l -b -e '.L TrackRecon.C++O' 2>/dev/null
|
||||||
|
|
||||||
|
# 27Al alpha+gas runs (9, 12, 13)
|
||||||
|
export DATASET="27Al" PREFIX="Run_"
|
||||||
|
echo " 27Al runs 9 12 13..."
|
||||||
|
# export source_vertex=53.44; export timecut_low=400.0; process_run 12 "$slope"
|
||||||
|
export source_vertex=-5.36; export timecut_low=12.0; export timecut_high=120.0; process_run 9 "$slope"
|
||||||
|
unset timecut_low
|
||||||
|
unset timecut_high
|
||||||
|
|
||||||
|
# 17F alpha runs with per-run source vertices
|
||||||
|
export DATASET="17F" PREFIX="SourceRun_"
|
||||||
|
echo " 17F runs 18-21..."
|
||||||
|
export source_vertex=53.44; process_run 18 "$slope"
|
||||||
|
export source_vertex=14.24; process_run 19 "$slope"
|
||||||
|
export source_vertex=-24.96; process_run 20 "$slope"
|
||||||
|
export source_vertex=-73.96; process_run 21 "$slope"
|
||||||
|
|
||||||
|
echo " done"
|
||||||
|
done
|
||||||
|
|
||||||
|
sed -i "s/double slope = [0-9.]*/double slope = 0.60/" "$CORRECTION_H"
|
||||||
|
echo "Restored slope = 0.60"
|
||||||
|
echo ""
|
||||||
|
echo "All done. Now run:"
|
||||||
|
echo " root -l 'scratch/plot_slope_scan.C'"
|
||||||
346
scratch/plot_slope_scan.C
Normal file
346
scratch/plot_slope_scan.C
Normal file
|
|
@ -0,0 +1,346 @@
|
||||||
|
#include <TFile.h>
|
||||||
|
#include <TH1.h>
|
||||||
|
#include <TF1.h>
|
||||||
|
#include <TFitResult.h>
|
||||||
|
#include <TGraph.h>
|
||||||
|
#include <TMultiGraph.h>
|
||||||
|
#include <TCanvas.h>
|
||||||
|
#include <TLegend.h>
|
||||||
|
#include <TLine.h>
|
||||||
|
#include <TString.h>
|
||||||
|
|
||||||
|
void plot_slope_scan()
|
||||||
|
{
|
||||||
|
// =========================================================================
|
||||||
|
// --- Configuration ---
|
||||||
|
// =========================================================================
|
||||||
|
|
||||||
|
// Set to true to inspect each Gaussian fit. Double-click the canvas to advance.
|
||||||
|
bool checkFits = false;
|
||||||
|
gStyle->SetOptStat(0);
|
||||||
|
double slopes[] = {0.40, 0.42, 0.44, 0.46, 0.48, 0.50, 0.52, 0.54, 0.56, 0.58, 0.60, 0.62, 0.64, 0.66};
|
||||||
|
const int N = 14; // Updated to 14 to match the size of your slopes array
|
||||||
|
|
||||||
|
// int runs[] = {9, 12, 18, 19, 20, 21};
|
||||||
|
// const int NRUNS = 6;
|
||||||
|
// int runs[] = {9, 12};
|
||||||
|
// const int NRUNS = 2;
|
||||||
|
int runs[] = {18, 19, 20, 21};
|
||||||
|
const int NRUNS = 4;
|
||||||
|
Int_t runColors[6] = {kRed + 1, kBlue + 2, kGreen + 2, kOrange + 1, kViolet + 2, kCyan + 2};
|
||||||
|
|
||||||
|
// --- Initialize Graphs ---
|
||||||
|
TGraph *gStdDevRun[NRUNS];
|
||||||
|
TGraph *gMeanRun[NRUNS];
|
||||||
|
for (int ir = 0; ir < NRUNS; ir++)
|
||||||
|
{
|
||||||
|
gStdDevRun[ir] = new TGraph(N);
|
||||||
|
gMeanRun[ir] = new TGraph(N);
|
||||||
|
}
|
||||||
|
TGraph *gStdDevSum = new TGraph(N);
|
||||||
|
TGraph *gMeanSum = new TGraph(N);
|
||||||
|
|
||||||
|
TH1 *h1[NRUNS][N];
|
||||||
|
|
||||||
|
// --- Load Data ---
|
||||||
|
for (int ir = 0; ir < NRUNS; ir++)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < N; i++)
|
||||||
|
{
|
||||||
|
h1[ir][i] = nullptr;
|
||||||
|
TString path = TString::Format("slope_scan/run%03d/slope_%.2f.root", runs[ir], slopes[i]);
|
||||||
|
TFile *f = TFile::Open(path);
|
||||||
|
|
||||||
|
if (!f || f->IsZombie())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
TH1 *t1 = (TH1 *)f->Get("pczfix-sx3pczguess_A1C2");
|
||||||
|
if (t1)
|
||||||
|
{
|
||||||
|
t1->SetDirectory(nullptr);
|
||||||
|
h1[ir][i] = t1;
|
||||||
|
}
|
||||||
|
f->Close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// --- Calculate Mean & StdDev with Bounded Gaussian Fit ---
|
||||||
|
// =========================================================================
|
||||||
|
std::vector<int> nPtsRun(NRUNS, 0);
|
||||||
|
int nPtsSum = 0;
|
||||||
|
double fitWindow = 15.0; // Window around the peak to fit (mm)
|
||||||
|
|
||||||
|
TCanvas *cDebug = nullptr;
|
||||||
|
if (checkFits)
|
||||||
|
{
|
||||||
|
cDebug = new TCanvas("cDebug", "Fit Diagnostic Debugger", 0, 0, 800, 600);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < N; i++)
|
||||||
|
{
|
||||||
|
TH1 *hsum = nullptr;
|
||||||
|
|
||||||
|
for (int ir = 0; ir < NRUNS; ir++)
|
||||||
|
{
|
||||||
|
if (!h1[ir][i] || h1[ir][i]->GetEntries() <= 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// 1. Find center of the highest peak
|
||||||
|
int maxBin = h1[ir][i]->GetMaximumBin();
|
||||||
|
double peakX = h1[ir][i]->GetXaxis()->GetBinCenter(maxBin);
|
||||||
|
|
||||||
|
// 2. Define the fit
|
||||||
|
TF1 *gfit = new TF1("gfit", "gaus", peakX - fitWindow, peakX + fitWindow);
|
||||||
|
|
||||||
|
// 3. Fit Conditionally (Draw if checking, otherwise run quietly in background)
|
||||||
|
TString fitOpt = checkFits ? "RQS" : "RQS0";
|
||||||
|
|
||||||
|
if (checkFits)
|
||||||
|
cDebug->cd(); // Ensure we draw on the debug canvas
|
||||||
|
TFitResultPtr fitRes = h1[ir][i]->Fit(gfit, fitOpt);
|
||||||
|
|
||||||
|
// --- DIAGNOSTIC PAUSE ---
|
||||||
|
if (checkFits)
|
||||||
|
{
|
||||||
|
h1[ir][i]->SetTitle(TString::Format("Run %d | Slope %.2f", runs[ir], slopes[i]));
|
||||||
|
h1[ir][i]->GetXaxis()->SetRangeUser(peakX - 50, peakX + 50); // Zoom in X
|
||||||
|
|
||||||
|
// Scale Y-axis to the maximum of this specific zoomed window + 20% headroom
|
||||||
|
h1[ir][i]->SetMaximum(h1[ir][i]->GetMaximum() * 1.2);
|
||||||
|
|
||||||
|
h1[ir][i]->Draw();
|
||||||
|
cDebug->Modified();
|
||||||
|
cDebug->Update();
|
||||||
|
printf("Visual Check: Run %d | Slope %.2f. Double-click canvas to continue...\n", runs[ir], slopes[i]);
|
||||||
|
while (cDebug->WaitPrimitive())
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
double mean, stddev;
|
||||||
|
if (fitRes >= 0)
|
||||||
|
{ // If fit succeeds
|
||||||
|
mean = gfit->GetParameter(1);
|
||||||
|
stddev = gfit->GetParameter(2);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ // Fallback to raw stats if fit fails
|
||||||
|
mean = h1[ir][i]->GetMean();
|
||||||
|
stddev = h1[ir][i]->GetStdDev();
|
||||||
|
}
|
||||||
|
|
||||||
|
gStdDevRun[ir]->SetPoint(nPtsRun[ir], slopes[i], stddev);
|
||||||
|
gMeanRun[ir]->SetPoint(nPtsRun[ir]++, slopes[i], mean);
|
||||||
|
|
||||||
|
delete gfit;
|
||||||
|
|
||||||
|
// Build the cumulative sum histogram
|
||||||
|
if (!hsum)
|
||||||
|
hsum = (TH1 *)h1[ir][i]->Clone(TString::Format("hsum_%.2f", slopes[i]));
|
||||||
|
else
|
||||||
|
hsum->Add(h1[ir][i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Process Summed Histogram ---
|
||||||
|
if (hsum && hsum->GetEntries() > 0)
|
||||||
|
{
|
||||||
|
int maxBinSum = hsum->GetMaximumBin();
|
||||||
|
double peakXSum = hsum->GetXaxis()->GetBinCenter(maxBinSum);
|
||||||
|
TF1 *gfitSum = new TF1("gfitSum", "gaus", peakXSum - fitWindow, peakXSum + fitWindow);
|
||||||
|
|
||||||
|
TString fitOptSum = checkFits ? "RQS" : "RQS0";
|
||||||
|
if (checkFits)
|
||||||
|
cDebug->cd();
|
||||||
|
|
||||||
|
TFitResultPtr fitResSum = hsum->Fit(gfitSum, fitOptSum);
|
||||||
|
|
||||||
|
// --- DIAGNOSTIC PAUSE FOR SUM ---
|
||||||
|
if (checkFits)
|
||||||
|
{
|
||||||
|
hsum->SetTitle(TString::Format("SUMMED RUNS | Slope %.2f", slopes[i]));
|
||||||
|
hsum->GetXaxis()->SetRangeUser(peakXSum - 50, peakXSum + 50);
|
||||||
|
|
||||||
|
// Scale Y-axis for the sum + 20% headroom
|
||||||
|
hsum->SetMaximum(hsum->GetMaximum() * 1.2);
|
||||||
|
|
||||||
|
hsum->Draw();
|
||||||
|
cDebug->Modified();
|
||||||
|
cDebug->Update();
|
||||||
|
printf("Visual Check: SUMMED | Slope %.2f. Double-click canvas to continue...\n", slopes[i]);
|
||||||
|
while (cDebug->WaitPrimitive())
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if (fitResSum >= 0)
|
||||||
|
// {
|
||||||
|
// gStdDevSum->SetPoint(nPtsSum, slopes[i], gfitSum->GetParameter(2));
|
||||||
|
// gMeanSum->SetPoint(nPtsSum++, slopes[i], gfitSum->GetParameter(1));
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// gStdDevSum->SetPoint(nPtsSum, slopes[i], hsum->GetStdDev());
|
||||||
|
// gMeanSum->SetPoint(nPtsSum++, slopes[i], hsum->GetMean());
|
||||||
|
// }
|
||||||
|
|
||||||
|
// delete gfitSum;
|
||||||
|
// delete hsum;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (checkFits && cDebug)
|
||||||
|
{
|
||||||
|
delete cDebug; // Clean up debug canvas before plotting final results
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// ---- Canvas 1: StdDev and Mean vs Slope
|
||||||
|
// =========================================================================
|
||||||
|
TCanvas *c1 = new TCanvas("c_stats", "1D Residual Stats vs Slope", 0, 0, 1600, 600);
|
||||||
|
c1->Divide(2, 1);
|
||||||
|
|
||||||
|
c1->cd(1);
|
||||||
|
gPad->SetGrid(1, 1);
|
||||||
|
TLegend *leg1 = new TLegend(0.78, 0.45, 0.97, 0.88);
|
||||||
|
leg1->SetBorderSize(1);
|
||||||
|
TMultiGraph *mg1 = new TMultiGraph("mg_stddev", "StdDev(pczfix - sx3pczguess) vs Slope;Slope;StdDev (mm)");
|
||||||
|
|
||||||
|
for (int ir = 0; ir < NRUNS; ir++)
|
||||||
|
{
|
||||||
|
if (nPtsRun[ir] == 0)
|
||||||
|
continue;
|
||||||
|
gStdDevRun[ir]->SetLineColor(runColors[ir]);
|
||||||
|
gStdDevRun[ir]->SetMarkerColor(runColors[ir]);
|
||||||
|
gStdDevRun[ir]->SetLineWidth(2);
|
||||||
|
gStdDevRun[ir]->SetMarkerStyle(20 + ir);
|
||||||
|
mg1->Add(gStdDevRun[ir], "PL");
|
||||||
|
leg1->AddEntry(gStdDevRun[ir], TString::Format("run %d", runs[ir]), "lp");
|
||||||
|
}
|
||||||
|
if (nPtsSum > 0)
|
||||||
|
{
|
||||||
|
gStdDevSum->SetLineColor(kBlack);
|
||||||
|
gStdDevSum->SetLineWidth(3);
|
||||||
|
gStdDevSum->SetLineStyle(kDashed);
|
||||||
|
gStdDevSum->SetMarkerStyle(29);
|
||||||
|
mg1->Add(gStdDevSum, "PL");
|
||||||
|
leg1->AddEntry(gStdDevSum, "sum", "lp");
|
||||||
|
}
|
||||||
|
mg1->Draw("A");
|
||||||
|
leg1->Draw();
|
||||||
|
|
||||||
|
double bestSlope = 0, bestStdDev = 1e9;
|
||||||
|
for (int i = 0; i < gStdDevRun[0]->GetN(); i++)
|
||||||
|
{
|
||||||
|
double x, y;
|
||||||
|
gStdDevRun[0]->GetPoint(i, x, y);
|
||||||
|
if (y > 0 && y < bestStdDev)
|
||||||
|
{
|
||||||
|
bestStdDev = y;
|
||||||
|
bestSlope = x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TLine *lb = new TLine(bestSlope, mg1->GetHistogram()->GetMinimum(),
|
||||||
|
bestSlope, mg1->GetHistogram()->GetMaximum());
|
||||||
|
lb->SetLineColor(kRed);
|
||||||
|
lb->SetLineStyle(kDashed);
|
||||||
|
lb->Draw();
|
||||||
|
printf(">>> Best slope (Run %d) = %.2f StdDev=%.2f mm\n", runs[0], bestSlope, bestStdDev);
|
||||||
|
|
||||||
|
c1->cd(2);
|
||||||
|
gPad->SetGrid(1, 1);
|
||||||
|
TLegend *leg2 = new TLegend(0.78, 0.45, 0.97, 0.88);
|
||||||
|
leg2->SetBorderSize(1);
|
||||||
|
TMultiGraph *mg2 = new TMultiGraph("mg_mean", "Mean(pczfix - sx3pczguess) vs Slope;Slope;Mean Offset (mm)");
|
||||||
|
|
||||||
|
for (int ir = 0; ir < NRUNS; ir++)
|
||||||
|
{
|
||||||
|
if (nPtsRun[ir] == 0)
|
||||||
|
continue;
|
||||||
|
gMeanRun[ir]->SetLineColor(runColors[ir]);
|
||||||
|
gMeanRun[ir]->SetMarkerColor(runColors[ir]);
|
||||||
|
gMeanRun[ir]->SetLineWidth(2);
|
||||||
|
gMeanRun[ir]->SetMarkerStyle(20 + ir);
|
||||||
|
mg2->Add(gMeanRun[ir], "PL");
|
||||||
|
leg2->AddEntry(gMeanRun[ir], TString::Format("run %d", runs[ir]), "lp");
|
||||||
|
}
|
||||||
|
if (nPtsSum > 0)
|
||||||
|
{
|
||||||
|
gMeanSum->SetLineColor(kBlack);
|
||||||
|
gMeanSum->SetLineWidth(3);
|
||||||
|
gMeanSum->SetLineStyle(kDashed);
|
||||||
|
gMeanSum->SetMarkerStyle(29);
|
||||||
|
mg2->Add(gMeanSum, "PL");
|
||||||
|
leg2->AddEntry(gMeanSum, "sum", "lp");
|
||||||
|
}
|
||||||
|
mg2->Draw("A");
|
||||||
|
|
||||||
|
TLine *lz = new TLine(slopes[0], 0, slopes[N - 1], 0);
|
||||||
|
lz->SetLineColor(kGray + 2);
|
||||||
|
lz->SetLineStyle(kDotted);
|
||||||
|
lz->Draw();
|
||||||
|
leg2->Draw();
|
||||||
|
|
||||||
|
c1->SaveAs("slope_scan_1d_metric.png");
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// ---- Canvas 2: Per-slope pads, overlaying the 1D Residual distributions
|
||||||
|
// =========================================================================
|
||||||
|
TCanvas *c2 = new TCanvas("c_perslope_1d", "Per-slope 1D Residuals: all runs overlaid", 0, 100, 1800, 1200);
|
||||||
|
c2->Divide(4, 4);
|
||||||
|
|
||||||
|
for (int i = 0; i < N; i++)
|
||||||
|
{
|
||||||
|
c2->cd(i + 1);
|
||||||
|
gPad->SetGrid(1, 1);
|
||||||
|
TLegend *legS = new TLegend(0.62, 0.55, 0.88, 0.88);
|
||||||
|
legS->SetBorderSize(0);
|
||||||
|
|
||||||
|
// --- STEP A: Pre-scan to find the highest Y value across all runs for this slope ---
|
||||||
|
double maxY = 0;
|
||||||
|
for (int ir = 0; ir < NRUNS; ir++)
|
||||||
|
{
|
||||||
|
if (!h1[ir][i] || h1[ir][i]->GetEntries() <= 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Set X range first so GetMaximum() doesn't accidentally grab a tail far away
|
||||||
|
h1[ir][i]->GetXaxis()->SetRangeUser(-50, 50);
|
||||||
|
if (h1[ir][i]->GetMaximum() > maxY)
|
||||||
|
{
|
||||||
|
maxY = h1[ir][i]->GetMaximum();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- STEP B: Draw with the dynamically scaled Y-axis ---
|
||||||
|
bool first = true;
|
||||||
|
for (int ir = 0; ir < NRUNS; ir++)
|
||||||
|
{
|
||||||
|
if (!h1[ir][i] || h1[ir][i]->GetEntries() <= 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
h1[ir][i]->SetLineColor(runColors[ir]);
|
||||||
|
h1[ir][i]->SetLineWidth(2);
|
||||||
|
h1[ir][i]->SetTitle(TString::Format("slope=%.2f;Residual (mm);Counts", slopes[i]));
|
||||||
|
|
||||||
|
if (first)
|
||||||
|
{
|
||||||
|
// Set the pad's Y-axis using the global max + 15% buffer so the legend fits cleanly
|
||||||
|
h1[ir][i]->SetMaximum(maxY * 1.15);
|
||||||
|
h1[ir][i]->Draw("HIST");
|
||||||
|
first = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
h1[ir][i]->Draw("HIST SAME");
|
||||||
|
}
|
||||||
|
legS->AddEntry(h1[ir][i], TString::Format("run %d", runs[ir]), "l");
|
||||||
|
}
|
||||||
|
if (!first)
|
||||||
|
legS->Draw();
|
||||||
|
}
|
||||||
|
|
||||||
|
c2->SaveAs("slope_scan_perslope_1d.png");
|
||||||
|
c2->Modified();
|
||||||
|
c2->Update();
|
||||||
|
while (gPad->WaitPrimitive())
|
||||||
|
;
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user