modified: TrackRecon.C removing double counting from the qqq and a si dither toggle
modified: eloss_calculations/Eloss.py changed from mass fraction to stoichiometry based on the catima documentation also regeneretated files and pushed modified: run_17F.sh modified: run_27Al.sh changed the Eloss dedx factor based on thenew stoichimetry basis as oppoosed to the mass fraction modified: run_tr.sh modified: scratch/overlay_2d.C restructured the beam E gates for the 2d overlay plots
This commit is contained in:
parent
14b1a89d65
commit
8043237b89
280
TrackRecon.C
280
TrackRecon.C
|
|
@ -45,10 +45,10 @@ bool process_alpha_proton_scattering = false,
|
|||
doMiscHistograms = true,
|
||||
doRawHistos = false,
|
||||
doSingles = false,
|
||||
diagnostic_eplots = true,
|
||||
diagnostic_eplots = false,
|
||||
diagnostic_tplots = true,
|
||||
doPCSX3ClusterAnalysis = false,
|
||||
doPCQQQClusterAnalysis = false,
|
||||
doPCSX3ClusterAnalysis = true,
|
||||
doPCQQQClusterAnalysis = true,
|
||||
BenchMark = true,
|
||||
onewire_analysis = true,
|
||||
doOldAnalysis = false,
|
||||
|
|
@ -57,6 +57,8 @@ bool process_alpha_proton_scattering = false,
|
|||
ta_foil_run = false,
|
||||
source_run = false;
|
||||
|
||||
bool si_pixel_dither = false;
|
||||
|
||||
// --- Geometry, Calibration, & Model Variables ---
|
||||
// z_entrance = -174.3 - 9.7 - 100.0,
|
||||
// new measurement of the chamber length puts the chamber at
|
||||
|
|
@ -495,6 +497,11 @@ static const std::set<int> badAnodeWires = {6, 12, 19, 21, 22, 23};
|
|||
bool excludeBadAnodeWires = false; // set in Begin() from DISABLE_BAD_ANODE_WIRES
|
||||
bool pcUniqueCathode = true; // set in Begin() from PC_UNIQUE_CATHODE
|
||||
bool pcA1C0PerCluster = true; // set in Begin() from PC_A1C0_PER_CLUSTER
|
||||
|
||||
std::vector<char> aClusterHasCathode;
|
||||
bool fillPooledTier = false;
|
||||
int qqqPairRule = 0;
|
||||
double qqqFbTol = 0.15;
|
||||
inline bool isAnodeWireExcluded(int wire)
|
||||
{
|
||||
return excludeBadAnodeWires && badAnodeWires.count(wire) > 0;
|
||||
|
|
@ -674,6 +681,20 @@ void TrackRecon::Begin(TTree * /*tree*/)
|
|||
a1c1_dead_cathode = &a1c1_dead_cathode_27Al;
|
||||
}
|
||||
a1c1_rebuild_dead_masks();
|
||||
if (getenv("QQQ_FB_TOL"))
|
||||
{
|
||||
qqqFbTol = std::atof(getenv("QQQ_FB_TOL"));
|
||||
std::cout << "QQQ front/back tolerance: " << qqqFbTol
|
||||
<< " (ratio " << (1 - qqqFbTol) / (1 + qqqFbTol) << " to "
|
||||
<< (1 + qqqFbTol) / (1 - qqqFbTol) << ")" << std::endl;
|
||||
}
|
||||
if (getenv("QQQ_PAIR_RULE"))
|
||||
{
|
||||
std::string r = getenv("QQQ_PAIR_RULE");
|
||||
qqqPairRule = (r == "worst") ? 1 : (r == "all") ? 2
|
||||
: 0;
|
||||
std::cout << "QQQ pairing rule: " << r << " (" << qqqPairRule << ")" << std::endl;
|
||||
}
|
||||
if (getenv("A1C1_LOWBAND_RFACTOR"))
|
||||
a1c1_lowband_rfactor = std::atof(getenv("A1C1_LOWBAND_RFACTOR"));
|
||||
if (getenv("A1C1_Z_SCALE_QQQ"))
|
||||
|
|
@ -1379,6 +1400,14 @@ Bool_t TrackRecon::Process(Long64_t entry)
|
|||
// QQQ Processing
|
||||
|
||||
int qqqCount = 0;
|
||||
|
||||
struct QQQCand
|
||||
{
|
||||
int id, chRing, chWedge;
|
||||
double mismatch;
|
||||
Event ev;
|
||||
};
|
||||
std::vector<QQQCand> qqqCands;
|
||||
std::vector<Event> QQQ_Events, PC_Events;
|
||||
std::vector<Event> PC_Events_calibrated; // independent of PC_Events; ADC->MeV via pcEnergySlope/Intercept
|
||||
// std::vector<Event> QQQ_Events_Raw, PC_Events_Raw;
|
||||
|
|
@ -1471,7 +1500,21 @@ Bool_t TrackRecon::Process(Long64_t entry)
|
|||
eWedgeMeV = eWedge * qqqCalib[qqq.id[i]][chWedge][chRing] / 1000;
|
||||
eRingMeV = eRing * qqqCalib[qqq.id[i]][chWedge][chRing] / 1000;
|
||||
|
||||
if (eRingMeV / eWedgeMeV > 3.0 || eRingMeV / eWedgeMeV < 1.0 / 3.0)
|
||||
// Front/back energy consistency. qqqFbTol <= 0 restores the legacy
|
||||
// 1/3 < ratio < 3 behaviour for A/B comparison.
|
||||
if (qqqFbTol > 0.0)
|
||||
{
|
||||
double sumE = eRingMeV + eWedgeMeV;
|
||||
plotter->Fill1D("QQQdiag_fbAsym", 400, -1, 1,
|
||||
sumE > 0 ? (eRingMeV - eWedgeMeV) / sumE : -2.0, "QQQdiag");
|
||||
if (!(sumE > 0) || TMath::Abs(eRingMeV - eWedgeMeV) / sumE > qqqFbTol)
|
||||
{
|
||||
plotter->Fill1D("QQQdiag_fbReject", 2, 0, 2, 1.0, "QQQdiag");
|
||||
continue; // front and back disagree -- skip this ring/wedge pair
|
||||
}
|
||||
plotter->Fill1D("QQQdiag_fbReject", 2, 0, 2, 0.0, "QQQdiag");
|
||||
}
|
||||
else if (eRingMeV / eWedgeMeV > 3.0 || eRingMeV / eWedgeMeV < 1.0 / 3.0)
|
||||
continue;
|
||||
// if(eRingMeV<1.2 || eWedgeMeV<1.2) continue;
|
||||
|
||||
|
|
@ -1484,7 +1527,9 @@ Bool_t TrackRecon::Process(Long64_t entry)
|
|||
Event qqqevent(TVector3(rho * TMath::Cos(phi_qqq), rho * TMath::Sin(phi_qqq), qqq_z), eRingMeV, eWedgeMeV, tRing, tWedge, chRing + qqq.id[i] * 16, chWedge + qqq.id[i] * 16);
|
||||
// Event qqqeventr(TVector3(rho * TMath::Cos(theta), rho * TMath::Sin(theta), qqq_z), eRing, eWedge, tRing, tWedge, chRing + qqq.id[i] * 16, chWedge + qqq.id[i] * 16);
|
||||
|
||||
QQQ_Events.push_back(qqqevent);
|
||||
qqqCands.push_back({qqq.id[i], chRing, chWedge,
|
||||
TMath::Abs(eRingMeV - eWedgeMeV) / (eRingMeV + eWedgeMeV),
|
||||
qqqevent});
|
||||
// QQQ_Events_Raw.push_back(qqqeventr);
|
||||
if (diagnostic_eplots)
|
||||
{
|
||||
|
|
@ -1569,6 +1614,98 @@ Bool_t TrackRecon::Process(Long64_t entry)
|
|||
} // j loop end
|
||||
} // i loop end
|
||||
|
||||
for (int id = 0; id < 8; ++id)
|
||||
{
|
||||
const QQQCand *cs[64];
|
||||
int nc = 0;
|
||||
for (const auto &c : qqqCands)
|
||||
if (c.id == id && nc < 64)
|
||||
cs[nc++] = &c;
|
||||
if (nc == 0)
|
||||
continue;
|
||||
bool seenR[16] = {}, seenW[16] = {};
|
||||
int nR = 0, nW = 0;
|
||||
for (int i = 0; i < nc; ++i)
|
||||
{
|
||||
if (cs[i]->chRing >= 0 && cs[i]->chRing < 16 && !seenR[cs[i]->chRing])
|
||||
{
|
||||
seenR[cs[i]->chRing] = true;
|
||||
++nR;
|
||||
}
|
||||
if (cs[i]->chWedge >= 0 && cs[i]->chWedge < 16 && !seenW[cs[i]->chWedge])
|
||||
{
|
||||
seenW[cs[i]->chWedge] = true;
|
||||
++nW;
|
||||
}
|
||||
}
|
||||
plotter->Fill1D("QQQdiag_nCand", 12, 0, 12, nc, "QQQdiag");
|
||||
// Single-candidate events: ring and wedge are opposite faces of the same
|
||||
// detector and both collect the full charge, so E_ring/E_wedge should be 1.
|
||||
// A strip next to a dead one leaks part of its charge into the dead strip
|
||||
// and shows a deficit -- with no multiplicity to flag it.
|
||||
if (nc == 1 && cs[0]->ev.Energy2 > 0 && cs[0]->ev.Energy1 > 0)
|
||||
{
|
||||
plotter->Fill2D(Form("QQQdiag_ringRatio_vs_ring_det%d", id), 16, 0, 16, 300, 0, 3,
|
||||
cs[0]->chRing, cs[0]->ev.Energy1 / cs[0]->ev.Energy2, "QQQdiag");
|
||||
plotter->Fill2D(Form("QQQdiag_wedgeRatio_vs_wedge_det%d", id), 16, 0, 16, 300, 0, 3,
|
||||
cs[0]->chWedge, cs[0]->ev.Energy2 / cs[0]->ev.Energy1, "QQQdiag");
|
||||
}
|
||||
plotter->Fill2D("QQQdiag_nRing_vs_nWedge", 6, 0, 6, 6, 0, 6, nR, nW, "QQQdiag");
|
||||
|
||||
if (nc == 2 && nR == 2 && nW == 1)
|
||||
{ // two rings sharing one wedge
|
||||
int dr = TMath::Abs(cs[0]->chRing - cs[1]->chRing);
|
||||
double sum = cs[0]->ev.Energy1 + cs[1]->ev.Energy1;
|
||||
double w = cs[0]->ev.Energy2;
|
||||
plotter->Fill1D("QQQdiag_dRing", 16, 0, 16, dr, "QQQdiag");
|
||||
if (w > 0)
|
||||
{
|
||||
plotter->Fill2D("QQQdiag_sumRing_over_wedge_vs_dRing", 16, 0, 16, 300, 0, 3, dr, sum / w, "QQQdiag");
|
||||
plotter->Fill2D("QQQdiag_maxRing_over_wedge_vs_dRing", 16, 0, 16, 300, 0, 3, dr,
|
||||
TMath::Max(cs[0]->ev.Energy1, cs[1]->ev.Energy1) / w, "QQQdiag");
|
||||
}
|
||||
}
|
||||
if (nc == 2 && nW == 2 && nR == 1)
|
||||
{ // two wedges sharing one ring
|
||||
int dw = TMath::Abs(cs[0]->chWedge - cs[1]->chWedge);
|
||||
double sum = cs[0]->ev.Energy2 + cs[1]->ev.Energy2;
|
||||
double r = cs[0]->ev.Energy1;
|
||||
plotter->Fill1D("QQQdiag_dWedge", 16, 0, 16, dw, "QQQdiag");
|
||||
if (r > 0)
|
||||
{
|
||||
plotter->Fill2D("QQQdiag_sumWedge_over_ring_vs_dWedge", 16, 0, 16, 300, 0, 3, dw, sum / r, "QQQdiag");
|
||||
plotter->Fill2D("QQQdiag_maxWedge_over_ring_vs_dWedge", 16, 0, 16, 300, 0, 3, dw,
|
||||
TMath::Max(cs[0]->ev.Energy2, cs[1]->ev.Energy2) / r, "QQQdiag");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (qqqPairRule == 2)
|
||||
{
|
||||
for (const auto &c : qqqCands)
|
||||
QQQ_Events.push_back(c.ev);
|
||||
}
|
||||
else
|
||||
{
|
||||
const bool worstFirst = (qqqPairRule == 1);
|
||||
std::sort(qqqCands.begin(), qqqCands.end(),
|
||||
[worstFirst](const QQQCand &a, const QQQCand &b)
|
||||
{ return worstFirst ? (a.mismatch > b.mismatch) : (a.mismatch < b.mismatch); });
|
||||
bool usedRing[8][16] = {};
|
||||
bool usedWedge[8][16] = {};
|
||||
for (const auto &c : qqqCands)
|
||||
{
|
||||
if (c.id < 0 || c.id >= 8 || c.chRing < 0 || c.chRing >= 16 ||
|
||||
c.chWedge < 0 || c.chWedge >= 16)
|
||||
continue;
|
||||
if (usedRing[c.id][c.chRing] || usedWedge[c.id][c.chWedge])
|
||||
continue;
|
||||
usedRing[c.id][c.chRing] = true;
|
||||
usedWedge[c.id][c.chWedge] = true;
|
||||
QQQ_Events.push_back(c.ev);
|
||||
}
|
||||
}
|
||||
|
||||
PCQQQTimeCut = PCAQQQTimeCut && PCCQQQTimeCut;
|
||||
if (doRawHistos)
|
||||
plotter->Fill1D("QQQ_Multiplicity", 11, -0.5, 10.5, qqqCount, "hRawQQQ");
|
||||
|
|
@ -1781,8 +1918,10 @@ Bool_t TrackRecon::Process(Long64_t entry)
|
|||
return scan(QQQ_Events, true) || scan(SX3_Events, false);
|
||||
};
|
||||
|
||||
for (const auto &aCluster : aClusters)
|
||||
aClusterHasCathode.assign(aClusters.size(), 0);
|
||||
for (size_t aClusterIdx = 0; aClusterIdx < aClusters.size(); ++aClusterIdx)
|
||||
{
|
||||
const auto &aCluster = aClusters[aClusterIdx];
|
||||
if (clusterHasExcludedAnode(aCluster))
|
||||
continue;
|
||||
if (aCluster.size() == 2)
|
||||
|
|
@ -1817,7 +1956,7 @@ Bool_t TrackRecon::Process(Long64_t entry)
|
|||
double ahi_MeV = std::max(ae0_MeV, ae1_MeV);
|
||||
double aratio_MeV = alo_MeV / ahi_MeV;
|
||||
plotter->Fill1D("A2_anode_ratio_calib", 120, 0, 1.2, aratio_MeV, "hGMPC");
|
||||
plotter->Fill2D("A1_vs_A2_calib", 800, 0, 0.4, 800, 0, 0.4, ae0_MeV, ae1_MeV, "hGMPC");
|
||||
plotter->Fill2D("A1_vs_A2_calib", 800, 0, 0.2, 800, 0, 0.2, ae0_MeV, ae1_MeV, "hGMPC");
|
||||
plotter->Fill2D("A2_anode_ratio_calib_vs_lowerIndex", 24, 0, 24, 120, 0, 1.2,
|
||||
std::min(wi0, wi1), aratio_MeV, "hGMPC");
|
||||
}
|
||||
|
|
@ -1925,6 +2064,8 @@ Bool_t TrackRecon::Process(Long64_t entry)
|
|||
if (pcUniqueCathode && bestC)
|
||||
pushPaired(*bestC);
|
||||
|
||||
aClusterHasCathode[aClusterIdx] = (nCathodeMatches > 0) ? 1 : 0;
|
||||
|
||||
if (pcA1C0PerCluster && nCathodeMatches == 0)
|
||||
pushAnodeOnly(aCluster);
|
||||
}
|
||||
|
|
@ -3947,6 +4088,7 @@ template <typename FillOneTier>
|
|||
static void forEachTier(const std::string &topo1, const std::string &topo2,
|
||||
const std::string &methodGroup, FillOneTier &&fillOneTier)
|
||||
{
|
||||
if (fillPooledTier)
|
||||
fillOneTier("");
|
||||
fillOneTier(topo1);
|
||||
if (!topo2.empty())
|
||||
|
|
@ -3955,6 +4097,18 @@ static void forEachTier(const std::string &topo1, const std::string &topo2,
|
|||
fillOneTier(methodGroup);
|
||||
}
|
||||
|
||||
static TVector3 siPixelSpread(const TVector3 &si, bool isQQQ, TRandom3 &rand)
|
||||
{
|
||||
if (!si_pixel_dither)
|
||||
return si;
|
||||
const double phi_pitch = isQQQ ? qqq_wedge_pitch : sx3_phi_pitch;
|
||||
double phi = si.Phi() + rand.Uniform(-phi_pitch / 2.0, phi_pitch / 2.0);
|
||||
double rho = si.Perp();
|
||||
if (isQQQ)
|
||||
rho += rand.Uniform(-qqq_ring_pitch / 2.0, qqq_ring_pitch / 2.0);
|
||||
return TVector3(rho * TMath::Cos(phi), rho * TMath::Sin(phi), si.Z());
|
||||
}
|
||||
|
||||
void protonAlphaElastic_core(HistPlotter *plotter, const std::vector<Event> &Si_Events, const std::vector<Event> &PC_Events,
|
||||
const std::vector<std::vector<std::tuple<int, double, double>>> &aClusters,
|
||||
bool isQQQ, const std::string &det, double si_ecut, double perp_cut, double phi_win,
|
||||
|
|
@ -3975,6 +4129,8 @@ void protonAlphaElastic_core(HistPlotter *plotter, const std::vector<Event> &Si_
|
|||
if (sievent.Energy1 < si_ecut)
|
||||
continue; // coarse gating
|
||||
|
||||
TVector3 si_pos = sievent.pos;
|
||||
|
||||
// Shared vertex/beam reconstruction + proton/alpha dispatch, called from
|
||||
// both the PC_Events loop (a1c1/a1c2) and the aClusters loop (a1c0/a2c0)
|
||||
// below -- pid is classified by the caller (each loop's anode source is
|
||||
|
|
@ -3983,14 +4139,14 @@ void protonAlphaElastic_core(HistPlotter *plotter, const std::vector<Event> &Si_
|
|||
double anodeE_MeV, SiPcPid pid, int multi1, int multi2, int anodeCh, bool hasCathode)
|
||||
{
|
||||
TVector3 x2f(pcXY.X(), pcXY.Y(), pcz_fix);
|
||||
TVector3 r_rhoMin_fix = beamVertex(sievent.pos, x2f - sievent.pos);
|
||||
TVector3 r_rhoMin_fix = beamVertex(si_pos, x2f - si_pos);
|
||||
double vertex_z = r_rhoMin_fix.Z();
|
||||
const bool axisSafe = (multi2 == 2) || (multi1 == 2 && multi2 == 0);
|
||||
// fillBeamProfile(plotter, r_rhoMin_fix, sievent.pos, x2f - sievent.pos, "elastic_" + det, axisSafe);
|
||||
// fillBeamProfile(plotter, r_rhoMin_fix, si_pos, x2f - si_pos, "elastic_" + det, axisSafe);
|
||||
if (vertex_z < z_entrance)
|
||||
return;
|
||||
double theta = (sievent.pos - r_rhoMin_fix).Theta();
|
||||
double path_length = pathLengthCm(sievent.pos, r_rhoMin_fix);
|
||||
double theta = (si_pos - r_rhoMin_fix).Theta();
|
||||
double path_length = pathLengthCm(si_pos, r_rhoMin_fix);
|
||||
|
||||
double beam_path_length = TMath::Abs(vertex_z - z_entrance) * 0.1;
|
||||
double beam_energy_at_vertex = evalElossForward(MeV_to_cm_p_spl, cm_to_MeVp_spl, initial_energy, beam_path_length);
|
||||
|
|
@ -4047,7 +4203,7 @@ void protonAlphaElastic_core(HistPlotter *plotter, const std::vector<Event> &Si_
|
|||
if (TMath::Abs(sievent.pos.DeltaPhi(pcevent.pos)) > phi_win)
|
||||
continue;
|
||||
plotter->Fill2D(rx + "_Ex_vs_dT" + ejtag + sfx, 500, -2000, 2000, 600, -10, 20, (sievent.Time1 - pcevent.Time1), Ex, pmlabel);
|
||||
plotter->Fill2D(rx + "_dEgasCalib_vs_dT" + ejtag + sfx, 500, -2000, 2000, 800, 0, 0.4, (sievent.Time1 - pcevent.Time1), anodeE_MeV, pmlabel);
|
||||
plotter->Fill2D(rx + "_dEgasCalib_vs_dT" + ejtag + sfx, 500, -2000, 2000, 800, 0, 0.2, (sievent.Time1 - pcevent.Time1), anodeE_MeV, pmlabel);
|
||||
}
|
||||
|
||||
// Ground-state beam-energy consistency check -- elastic scattering has
|
||||
|
|
@ -4080,10 +4236,10 @@ void protonAlphaElastic_core(HistPlotter *plotter, const std::vector<Event> &Si_
|
|||
beam_energy_at_vertex, ebeam_kin, pmlabel);
|
||||
plotter->Fill2D(rx + "_EKin_vs_ESi" + ejtag + t + sfx, 400, 0, initial_energy * 1.5, 800, 0, 10, ebeam_kin, sievent.Energy1, pmlabel);
|
||||
}
|
||||
PCCollect pcc = pcCollectionPath(r_rhoMin_fix, sievent.pos);
|
||||
PCCollect pcc = pcCollectionPath(r_rhoMin_fix, si_pos);
|
||||
if (pcc.ok && anodeE_MeV > 0.0)
|
||||
{
|
||||
plotter->Fill2D(rx + "_dEgasCalib_vs_Ex" + ejtag + t + sfx, 800, -10, 10, 800, 0, 0.4, Ex, anodeE_MeV, pmlabel);
|
||||
plotter->Fill2D(rx + "_dEgasCalib_vs_Ex" + ejtag + t + sfx, 800, -10, 10, 800, 0, 0.2, Ex, anodeE_MeV, pmlabel);
|
||||
}
|
||||
};
|
||||
std::string topo1;
|
||||
|
|
@ -4098,25 +4254,25 @@ void protonAlphaElastic_core(HistPlotter *plotter, const std::vector<Event> &Si_
|
|||
|
||||
// Gas segmentation validation (dEgas family), uniform for every
|
||||
// topology including a1c0/a2c0.
|
||||
PCCollect pcc = pcCollectionPath(r_rhoMin_fix, sievent.pos);
|
||||
PCCollect pcc = pcCollectionPath(r_rhoMin_fix, si_pos);
|
||||
if (pcc.ok)
|
||||
{
|
||||
double E_gu = evalEloss(ej_fwd, ej_inv, sievent.Energy1, pcc.guard_cm);
|
||||
double E_ca = evalEloss(ej_fwd, ej_inv, sievent.Energy1, pcc.cathode_cm);
|
||||
double dE_pred = E_gu - E_ca;
|
||||
plotter->Fill2D(rx + "_dEgas_vs_Ef" + ejtag + sfx, 400, 0, 10, 400, 0, 0.4, Efix, dE_pred, pmlabel);
|
||||
plotter->Fill2D(rx + "_dEgas_vs_Ef" + ejtag + sfx, 400, 0, 10, 400, 0, 0.2, Efix, dE_pred, pmlabel);
|
||||
if (anodeE_MeV > 0.0)
|
||||
{
|
||||
plotter->Fill2D(rx + "_dEgasCalib_vs_Ef" + ejtag + sfx, 400, 0, 10, 800, 0, 0.4, Efix, anodeE_MeV, pmlabel);
|
||||
plotter->Fill2D(rx + "_dEgasCalib_vs_E" + ejtag + sfx, 400, 0, 10, 800, 0, 0.4, sievent.Energy1, anodeE_MeV, pmlabel);
|
||||
plotter->Fill2D(rx + "_dEgasCalib_vs_VertexZ" + ejtag + sfx, 800, -400, 400, 800, 0, 0.4, vertex_z, anodeE_MeV, pmlabel);
|
||||
plotter->Fill2D(rx + "_dEgasCalib_vs_theta" + ejtag + sfx, 100, 0, 180, 800, 0, 0.4, theta * 180 / M_PI, anodeE_MeV, pmlabel);
|
||||
plotter->Fill2D(rx + "_dEgasCalib_vs_phi" + ejtag + sfx, 100, -200, 200, 800, 0, 0.4, sievent.pos.Phi() * 180 / M_PI, anodeE_MeV, pmlabel);
|
||||
plotter->Fill2D(rx + "_dEgasCalib_vs_Ef" + ejtag + sfx, 400, 0, 10, 800, 0, 0.2, Efix, anodeE_MeV, pmlabel);
|
||||
plotter->Fill2D(rx + "_dEgasCalib_vs_E" + ejtag + sfx, 400, 0, 10, 800, 0, 0.2, sievent.Energy1, anodeE_MeV, pmlabel);
|
||||
plotter->Fill2D(rx + "_dEgasCalib_vs_VertexZ" + ejtag + sfx, 800, -400, 400, 800, 0, 0.2, vertex_z, anodeE_MeV, pmlabel);
|
||||
plotter->Fill2D(rx + "_dEgasCalib_vs_theta" + ejtag + sfx, 100, 0, 180, 800, 0, 0.2, theta * 180 / M_PI, anodeE_MeV, pmlabel);
|
||||
plotter->Fill2D(rx + "_dEgasCalib_vs_phi" + ejtag + sfx, 100, -200, 200, 800, 0, 0.2, sievent.pos.Phi() * 180 / M_PI, anodeE_MeV, pmlabel);
|
||||
if (anodeCh >= 0 && anodeCh < 24)
|
||||
// plotter->Fill2D(rx + "_dEgasCalib_vs_E" + ejtag + sfx + "_anode" + pad2(anodeCh),
|
||||
// 400, 0, 10, 800, 0, 0.4, sievent.Energy1, anodeE_MeV, pmlabel);
|
||||
plotter->Fill2D(rx + "_dEgasCalib_vs_Z" + ejtag + sfx, 800, -400, 400, 800, 0, 0.4, vertex_z, anodeE_MeV, pmlabel);
|
||||
plotter->Fill2D(rx + "_dEgasPred_vs_dEgasCalib" + ejtag + sfx, 800, 0, 0.4, 800, 0, 0.4, anodeE_MeV, dE_pred, pmlabel);
|
||||
// 400, 0, 10, 800, 0, 0.2, sievent.Energy1, anodeE_MeV, pmlabel);
|
||||
plotter->Fill2D(rx + "_dEgasCalib_vs_Z" + ejtag + sfx, 800, -400, 400, 800, 0, 0.2, vertex_z, anodeE_MeV, pmlabel);
|
||||
plotter->Fill2D(rx + "_dEgasPred_vs_dEgasCalib" + ejtag + sfx, 800, 0, 0.2, 800, 0, 0.2, anodeE_MeV, dE_pred, pmlabel);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
@ -4141,6 +4297,7 @@ void protonAlphaElastic_core(HistPlotter *plotter, const std::vector<Event> &Si_
|
|||
if (!(phicut && timecut))
|
||||
continue;
|
||||
|
||||
si_pos = siPixelSpread(sievent.pos, isQQQ, rand);
|
||||
bool hasCathode = (pcevent.Cathodech >= 0);
|
||||
|
||||
// Timing/geometry QA, independent of particle ID.
|
||||
|
|
@ -4187,11 +4344,11 @@ void protonAlphaElastic_core(HistPlotter *plotter, const std::vector<Event> &Si_
|
|||
auto fillCmp = [&](double pcz, const std::string &m)
|
||||
{
|
||||
TVector3 x2(pcevent.pos.X(), pcevent.pos.Y(), pcz);
|
||||
TVector3 rv = beamVertex(sievent.pos, x2 - sievent.pos);
|
||||
TVector3 rv = beamVertex(si_pos, x2 - si_pos);
|
||||
if (beamPerp(rv) > perp_cut)
|
||||
return;
|
||||
double th = (sievent.pos - rv).Theta();
|
||||
double pl = pathLengthCm(sievent.pos, rv);
|
||||
double th = (si_pos - rv).Theta();
|
||||
double pl = pathLengthCm(si_pos, rv);
|
||||
double Ef = evalEloss(MeV_to_cm_spl, cm_to_MeV_spl, sievent.Energy1, pl);
|
||||
double beam_pl_cmp = TMath::Abs(rv.Z() - z_entrance) * 0.1;
|
||||
double beam_E_cmp = evalElossForward(MeV_to_cm_p_spl, cm_to_MeVp_spl, initial_energy, beam_pl_cmp);
|
||||
|
|
@ -4296,9 +4453,14 @@ void protonAlphaElastic_core(HistPlotter *plotter, const std::vector<Event> &Si_
|
|||
if (pid == SiPcPid::kUnknown)
|
||||
plotter->Fill1D(rx + "_pidUnknown" + sfx, 2, 0, 2, 1.0, misclabel);
|
||||
|
||||
double pcz_a0 = isA2C0 ? pc.Z() : rand.Gaus(pc.Z(), dither_sigma); // a1c0 dithered, a2c0 unambiguous (2 wires)
|
||||
// Hybrid: a track from the beam axis has one phi at the Si and the PC, so the
|
||||
// wire point is re-looked-up at the spread Si phi (== pc when SI_PIXEL_DITHER=0).
|
||||
si_pos = siPixelSpread(sievent.pos, isQQQ, rand);
|
||||
TVector3 pc_rec = isA2C0 ? a2c0_wirePos(apwire, si_pos.Phi(), isQQQ)
|
||||
: a1c0_wirePos(apwire, si_pos.Phi(), isQQQ);
|
||||
double pcz_a0 = isA2C0 ? pc_rec.Z() : rand.Gaus(pc_rec.Z(), dither_sigma); // a1c0 dithered, a2c0 unambiguous (2 wires)
|
||||
|
||||
reconstructAndFill(pcz_a0, pc, apSumE, -1.0, anodeE_MeV_a0, pid,
|
||||
reconstructAndFill(pcz_a0, pc_rec, apSumE, -1.0, anodeE_MeV_a0, pid,
|
||||
static_cast<int>(aCl.size()), 0, anodeCh_a0, false);
|
||||
}
|
||||
} // end aClusters loop (a1c0/a2c0)
|
||||
|
|
@ -4381,22 +4543,23 @@ static void reaction_ax_core(HistPlotter *plotter, const std::vector<Event> &Si_
|
|||
plotter->Fill2D(rx + "_dt_si_mcp_vs_dt_si_rf" + sfx, 640, -1400, 2000, 640, -2000, 2000, dt_si_mcp, dt_si_rf,
|
||||
folderPrefix + globaltag + "_" + rx + "+misc_" + det);
|
||||
}
|
||||
TVector3 si_pos = sievent.pos;
|
||||
|
||||
auto reconstructAndFill = [&](double pcz_fix, const TVector3 &pcXY, double anodeE, double cathodeE, double anodeE_MeV, double cathodeE_MeV,
|
||||
const std::string &topo1, const std::string &topo2 = "", int anodeCh = -1,
|
||||
const std::string &methodGroup = "")
|
||||
{
|
||||
TVector3 x2f(pcXY.X(), pcXY.Y(), pcz_fix);
|
||||
TVector3 r_rhoMin_fix = beamVertex(sievent.pos, x2f - sievent.pos);
|
||||
TVector3 r_rhoMin_fix = beamVertex(si_pos, x2f - si_pos);
|
||||
double vertex_z = r_rhoMin_fix.Z();
|
||||
const bool axisSafe = (topo1 == "a1c2fix") || (topo1 == "a2c0") || (topo2 == "a1c1_inband");
|
||||
// fillBeamProfile(plotter, r_rhoMin_fix, sievent.pos, x2f - sievent.pos, "reaction_" + rx + "_" + det, axisSafe);
|
||||
// fillBeamProfile(plotter, r_rhoMin_fix, si_pos, x2f - si_pos, "reaction_" + rx + "_" + det, axisSafe);
|
||||
// if (beamPerp(r_rhoMin_fix) > perp_cut || vertex_z < z_entrance || vertex_z > 30.0)
|
||||
if (vertex_z < z_entrance || vertex_z > 30.0)
|
||||
return;
|
||||
|
||||
double theta = (sievent.pos - r_rhoMin_fix).Theta();
|
||||
double phi = (sievent.pos - r_rhoMin_fix).Phi();
|
||||
double theta = (si_pos - r_rhoMin_fix).Theta();
|
||||
double phi = (si_pos - r_rhoMin_fix).Phi();
|
||||
|
||||
double beam_path_length = TMath::Abs(vertex_z - z_entrance) * 0.1; // mm -> cm
|
||||
double beam_energy_at_vertex = evalElossForward(beam_MeV_to_cm, beam_cm_to_MeV, beamE0, beam_path_length);
|
||||
|
|
@ -4411,7 +4574,7 @@ static void reaction_ax_core(HistPlotter *plotter, const std::vector<Event> &Si_
|
|||
{
|
||||
// ---- kinematics for this mass hypothesis ----
|
||||
Kinematics kin(m_beam, mass_4He, m3, m4, beam_energy_at_vertex / m_beam); // beamE given as E/u
|
||||
double path_length = pathLengthCm(sievent.pos, r_rhoMin_fix);
|
||||
double path_length = pathLengthCm(si_pos, r_rhoMin_fix);
|
||||
double Efix = evalEloss(ej_fwd, ej_inv, sievent.Energy1, path_length);
|
||||
double Ex = kin.getExc(Efix, theta * 180 / M_PI);
|
||||
|
||||
|
|
@ -4521,8 +4684,8 @@ static void reaction_ax_core(HistPlotter *plotter, const std::vector<Event> &Si_
|
|||
if (TMath::Abs(sievent.pos.DeltaPhi(pcevent.pos)) > phi_win)
|
||||
continue;
|
||||
plotter->Fill2D(rx + "_Ex_vs_dT" + ejtag + sfx, 500, -2000, 2000, 600, -10, 20, (sievent.Time1 - pcevent.Time1), Ex, pmlabel);
|
||||
plotter->Fill2D(rx + "_dEgasCalib_vs_dT" + ejtag + sfx, 500, -2000, 2000, 800, 0, 0.4, (sievent.Time1 - pcevent.Time1), anodeE_MeV, pmlabel);
|
||||
plotter->Fill2D(rx + "_dEgasCalibCathode_vs_dT" + ejtag + sfx, 500, -2000, 2000, 800, 0, 0.4, (sievent.Time1 - pcevent.Time1), cathodeE_MeV, pmlabel);
|
||||
plotter->Fill2D(rx + "_dEgasCalib_vs_dT" + ejtag + sfx, 500, -2000, 2000, 800, 0, 0.2, (sievent.Time1 - pcevent.Time1), anodeE_MeV, pmlabel);
|
||||
plotter->Fill2D(rx + "_dEgasCalibCathode_vs_dT" + ejtag + sfx, 500, -2000, 2000, 800, 0, 0.2, (sievent.Time1 - pcevent.Time1), cathodeE_MeV, pmlabel);
|
||||
}
|
||||
|
||||
if (dt_rf_mcp > -900000000)
|
||||
|
|
@ -4532,31 +4695,34 @@ static void reaction_ax_core(HistPlotter *plotter, const std::vector<Event> &Si_
|
|||
forEachTier(topo1, topo2, methodGroup, plot_with_tag);
|
||||
|
||||
// Gas segmentation validation
|
||||
PCCollect pcc = pcCollectionPath(r_rhoMin_fix, sievent.pos);
|
||||
PCCollect pcc = pcCollectionPath(r_rhoMin_fix, si_pos);
|
||||
if (pcc.ok)
|
||||
{
|
||||
double E_gu = evalEloss(ej_fwd, ej_inv, sievent.Energy1, pcc.guard_cm);
|
||||
double E_ca = evalEloss(ej_fwd, ej_inv, sievent.Energy1, pcc.cathode_cm);
|
||||
double dE_pred = E_gu - E_ca;
|
||||
plotter->Fill2D(rx + "_dEgas_vs_Ef" + ejtag + sfx, 400, 0, ef_max, 800, 0, 0.4, Efix, dE_pred, pmlabel);
|
||||
plotter->Fill2D(rx + "_dEgas_vs_Ef" + ejtag + sfx, 400, 0, ef_max, 800, 0, 0.2, Efix, dE_pred, pmlabel);
|
||||
if (anodeE_MeV >= 0.0)
|
||||
{
|
||||
plotter->Fill2D(rx + "_dEgasCalib_vs_E" + sfx, 400, 0, ef_max, 800, 0, 0.4, sievent.Energy1, anodeE_MeV, folderPrefix + "EdEComparison");
|
||||
plotter->Fill2D(rx + "_dEgasCalib*sintheta_vs_E" + sfx, 400, 0, ef_max, 800, 0, 0.4, sievent.Energy1, anodeE_MeV * sin(theta), folderPrefix + "EdEComparison");
|
||||
plotter->Fill2D(rx + "_dEgasCalib_vs_Ef" + ejtag + sfx, 400, 0, ef_max, 800, 0, 0.4, Efix, anodeE_MeV, pmlabel);
|
||||
plotter->Fill2D(rx + "_dEgasCalib_vs_EBeam" + ejtag + sfx, 400, 0, beamE0 * 1.5, 800, 0, 0.4, beam_energy_at_vertex, anodeE_MeV, pmlabel);
|
||||
plotter->Fill2D(rx + "_dEgasCalib_vs_E" + sfx, 400, 0, ef_max, 800, 0, 0.2, sievent.Energy1, anodeE_MeV, folderPrefix + "EdEComparison");
|
||||
plotter->Fill2D(rx + "_dEgasCalib*sintheta_vs_E" + sfx, 400, 0, ef_max, 800, 0, 0.2, sievent.Energy1, anodeE_MeV * sin(theta), folderPrefix + "EdEComparison");
|
||||
plotter->Fill2D(rx + "_dEgasCalib_vs_Ef" + ejtag + sfx, 400, 0, ef_max, 800, 0, 0.2, Efix, anodeE_MeV, pmlabel);
|
||||
plotter->Fill2D(rx + "_dEgasCalib_vs_EBeam" + ejtag + sfx, 400, 0, beamE0 * 1.5, 800, 0, 0.2, beam_energy_at_vertex, anodeE_MeV, pmlabel);
|
||||
plotter->Fill2D(rx + "_dEgasRaw_vs_EBeam" + ejtag + sfx, 400, 0, beamE0 * 1.5, 800, 0, 20000, beam_energy_at_vertex, anodeE, pmlabel);
|
||||
plotter->Fill2D(rx + "_dEgasCalib_vs_E" + ejtag + sfx, 400, 0, ef_max, 800, 0, 0.4, sievent.Energy1, anodeE_MeV, pmlabel);
|
||||
plotter->Fill2D(rx + "_dEgasCalib_vs_VertexZ" + ejtag + sfx, 800, -400, 400, 800, 0, 0.4, vertex_z, anodeE_MeV, pmlabel);
|
||||
plotter->Fill2D(rx + "_dEgasCalib_vs_E" + ejtag + sfx, 400, 0, ef_max, 800, 0, 0.2, sievent.Energy1, anodeE_MeV, pmlabel);
|
||||
plotter->Fill2D(rx + "_dEgasCalib_vs_VertexZ" + ejtag + sfx, 800, -400, 400, 800, 0, 0.2, vertex_z, anodeE_MeV, pmlabel);
|
||||
plotter->Fill2D(rx + "_dEgasRaw_vs_VertexZ" + ejtag + sfx, 800, -400, 400, 800, 0, 20000, vertex_z, anodeE, pmlabel);
|
||||
plotter->Fill2D(rx + "_dEgasRaw_vs_theta" + ejtag + sfx, 180, 0, 180, 800, 0, 20000, theta * 180 / M_PI, anodeE, pmlabel);
|
||||
plotter->Fill2D(rx + "_dEgasCalib_vs_theta" + ejtag + sfx, 360, 0, 180, 800, 0, 0.4, theta * 180 / M_PI, anodeE_MeV, pmlabel);
|
||||
plotter->Fill2D(rx + "_dEgasCalib_vs_phi" + ejtag + sfx, 90, -180, 180, 800, 0, 0.4, phi * 180 / M_PI, anodeE_MeV, pmlabel);
|
||||
plotter->Fill2D(rx + "_dEgasCalib_vs_theta" + ejtag + sfx, 360, 0, 180, 800, 0, 0.2, theta * 180 / M_PI, anodeE_MeV, pmlabel);
|
||||
plotter->Fill2D(rx + "_dEgasCalib_vs_phi" + ejtag + sfx, 90, -180, 180, 800, 0, 0.2, phi * 180 / M_PI, anodeE_MeV, pmlabel);
|
||||
// if (anodeCh >= 0)
|
||||
// plotter->Fill2D(rx + "_dEgasCalib_vs_E" + ejtag + sfx + "_anode" + pad2(anodeCh), 400, 0, ef_max, 800, 0, 0.4, sievent.Energy1, anodeE_MeV, pmlabel);
|
||||
plotter->Fill2D(rx + "_dEgasCalib_vs_Ex" + ejtag + sfx, 600, -10, 20, 800, 0, 0.4, Ex, anodeE_MeV, pmlabel);
|
||||
plotter->Fill2D(rx + "_dEgasCalib_vs_Z" + ejtag + sfx, 800, -400, 400, 800, 0, 0.4, vertex_z, anodeE_MeV, pmlabel);
|
||||
plotter->Fill2D(rx + "_dEgasPred_vs_dEgasCalib" + ejtag + sfx, 800, 0, 0.4, 800, 0, 0.4, anodeE_MeV, dE_pred, pmlabel);
|
||||
// plotter->Fill2D(rx + "_dEgasCalib_vs_E" + ejtag + sfx + "_anode" + pad2(anodeCh), 400, 0, ef_max, 800, 0, 0.2, sievent.Energy1, anodeE_MeV, pmlabel);
|
||||
plotter->Fill2D(rx + "_dEgasCalib_vs_Ex" + ejtag + sfx, 600, -10, 20, 800, 0, 0.2, Ex, anodeE_MeV, pmlabel);
|
||||
forEachTier(topo1, topo2, methodGroup, [&](const std::string &topo)
|
||||
{ if (!topo.empty())
|
||||
plotter->Fill2D(rx + "_dEgasCalib_vs_Ex" + ejtag + "_" + topo + sfx, 600, -10, 20, 800, 0, 0.4, Ex, anodeE_MeV, pmlabel); });
|
||||
plotter->Fill2D(rx + "_dEgasCalib_vs_Z" + ejtag + sfx, 800, -400, 400, 800, 0, 0.2, vertex_z, anodeE_MeV, pmlabel);
|
||||
plotter->Fill2D(rx + "_dEgasPred_vs_dEgasCalib" + ejtag + sfx, 800, 0, 0.2, 800, 0, 0.4, anodeE_MeV, dE_pred, pmlabel);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
@ -4588,6 +4754,7 @@ static void reaction_ax_core(HistPlotter *plotter, const std::vector<Event> &Si_
|
|||
bool timecut = siPcCoincident(sievent.Time1, pcevent.Time1);
|
||||
if (!(phicut && timecut))
|
||||
continue;
|
||||
si_pos = siPixelSpread(sievent.pos, isQQQ, rand);
|
||||
double anodeE_MeV = (pcevent.Anodech >= 0 && pcevent.Anodech < 24) ? pcevent.Energy1MeV : -1.0;
|
||||
double cathodeE_MeV = (pcevent.Cathodech >= 0 && pcevent.Cathodech < 24) ? pcevent.Energy2MeV : -1.0;
|
||||
|
||||
|
|
@ -4628,8 +4795,11 @@ static void reaction_ax_core(HistPlotter *plotter, const std::vector<Event> &Si_
|
|||
}
|
||||
}
|
||||
|
||||
for (const auto &aCl : aClusters)
|
||||
for (size_t aClIdx = 0; aClIdx < aClusters.size(); ++aClIdx)
|
||||
{
|
||||
const auto &aCl = aClusters[aClIdx];
|
||||
if (aClIdx < aClusterHasCathode.size() && aClusterHasCathode[aClIdx])
|
||||
continue;
|
||||
if (aCl.size() < 1 || aCl.size() > 2)
|
||||
continue;
|
||||
|
||||
|
|
@ -4677,8 +4847,12 @@ static void reaction_ax_core(HistPlotter *plotter, const std::vector<Event> &Si_
|
|||
if (anodeCh_a0 < 0 || anodeCh_a0 >= 24)
|
||||
anodeCh_a0 = -1;
|
||||
|
||||
double pcz_a0 = isA2C0 ? pc.Z() : rand.Gaus(pc.Z(), dither_sigma);
|
||||
reconstructAndFill(pcz_a0, pc, apSumE, -1.0, anodeE_MeV_a0, -1.0, a0tag, "", anodeCh_a0);
|
||||
// Hybrid: wire point re-looked-up at the spread Si phi, as in protonAlphaElastic_core.
|
||||
si_pos = siPixelSpread(sievent.pos, isQQQ, rand);
|
||||
TVector3 pc_rec = isA2C0 ? a2c0_wirePos(apwire, si_pos.Phi(), isQQQ)
|
||||
: a1c0_wirePos(apwire, si_pos.Phi(), isQQQ);
|
||||
double pcz_a0 = isA2C0 ? pc_rec.Z() : rand.Gaus(pc_rec.Z(), dither_sigma);
|
||||
reconstructAndFill(pcz_a0, pc_rec, apSumE, -1.0, anodeE_MeV_a0, -1.0, a0tag, "", anodeCh_a0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,15 +2,16 @@ import pycatima as catima
|
|||
import numpy as np
|
||||
import os
|
||||
|
||||
DEDX_SCALE = float(os.environ.get("DEDX_SCALE", "0.89"))
|
||||
DEDX_SCALE = float(os.environ.get("DEDX_SCALE", "1"))
|
||||
print(f"Using dEdX scale factor: {DEDX_SCALE}")
|
||||
|
||||
# --- 1. Constants ---
|
||||
P_TORR = 250
|
||||
# Same variables TrackRecon.C reads, so the table written is the one it loads.
|
||||
P_TORR = int(os.environ.get("pressure_in_torr", "250"))
|
||||
TEMP_K = 293.15
|
||||
R = 8.3144
|
||||
MEV2U = 1.0 / 931.494
|
||||
P_CO2 = 3
|
||||
P_CO2 = int(os.environ.get("CO2percent", "3"))
|
||||
|
||||
# Gas Density Calculations
|
||||
p_pa = P_TORR * 133.322
|
||||
|
|
@ -21,7 +22,7 @@ rho_g_cm3 = (molar_density * m_mix_avg) / 1e6
|
|||
print(f"Gas density at {P_TORR} Torr: {rho_g_cm3:.6e} g/cm^3")
|
||||
|
||||
# --- 2. Material & Step Setup ---
|
||||
material_def = [(m_he, 2, (1 - P_CO2 / 100)), (m_c, 6, P_CO2 / 100), (m_o, 8, 2*P_CO2 / 100)]
|
||||
material_def = [(m_he, 2, 100 - P_CO2), (m_c, 6, P_CO2), (m_o, 8, 2 * P_CO2)]
|
||||
gas_mix = catima.Material(material_def)
|
||||
gas_mix.density(rho_g_cm3)
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -8,7 +8,6 @@ export pressure_in_torr=250
|
|||
export CATHODE_GAIN=1
|
||||
export source_vertex=-200.0
|
||||
export DEDX_SCALE=0.89
|
||||
export A1C1_LOWBAND_RFACTOR=7.0
|
||||
export CUTLIST=cuts_list.txt
|
||||
|
||||
run_once() {
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ export CO2percent=3
|
|||
export pressure_in_torr=250
|
||||
export CATHODE_GAIN=3.0
|
||||
export source_vertex=-200.0
|
||||
export DEDX_SCALE=0.89
|
||||
export DEDX_SCALE=0.962
|
||||
|
||||
# export BEAM_AXIS_Z0=-200
|
||||
export BEAM_AXIS_X=0
|
||||
|
|
@ -60,8 +60,8 @@ export -f process_run
|
|||
python3 eloss_calculations/Eloss.py
|
||||
|
||||
echo "Starting parallel processing..."
|
||||
# time parallel --bar -j 12 process_run ::: {24..41} 44 45 46 {50..59}
|
||||
time parallel --bar -j 12 process_run ::: {24..41}
|
||||
time parallel --bar -j 12 process_run ::: {24..41} 44 45 46 {50..59}
|
||||
# time parallel --bar -j 12 process_run ::: {24..41}
|
||||
# time parallel --bar -j 10 process_run ::: 44 45 46 {50..59}
|
||||
# time parallel --bar -j 1 process_run ::: 48 # pc without coincidence
|
||||
# mv "${CURRENT_OUT_DIR}/results_run048.root" "Output_27Al_run48/."
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ if [[ 1 -eq 0 ]]; then
|
|||
rm -f ${OUT_DIR}/all.root
|
||||
|
||||
parallel --bar -j 6 process_run ::: {1..8}
|
||||
exit
|
||||
# exit
|
||||
fi
|
||||
|
||||
# --- Block 2: 17F Source Runs (5-14) ---
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ void overlay_2d(TString rootFile, TString xAxisLabel, TString yAxisLabel,
|
|||
// ---- Hardcoded selection: edit these to choose what to plot ----
|
||||
TString reaction = "m27Alax"; // reaction tag, e.g. "m27Alax", "m17Fax"
|
||||
TString ejtag = "p"; // ejectile: "p" (proton) or "a" (alpha)
|
||||
TString topology = "a1c1_inband"; // e.g. "a1c0", "a1c1", "a1c2fix", "a2c0", "a1c1c2"
|
||||
TString topology = "a1c0"; // e.g. "a1c0", "a1c1", "a1c2fix", "a2c0", "a1c1c2"
|
||||
TString detector = "sx3"; // "sx3" or "qqq"
|
||||
|
||||
// Excited states to overlay, in the same order as labels[]/xlo[]/xhi[]
|
||||
|
|
@ -76,16 +76,22 @@ void overlay_2d(TString rootFile, TString xAxisLabel, TString yAxisLabel,
|
|||
// note 3498's tag is lowercase "kev" (TrackRecon.C:4028), unlike every
|
||||
// other state's "keV". 3774 keV is deliberately left out (too close
|
||||
// to 3498, spin-parity predicts it's weaker anyway).
|
||||
TString states[] = {"GS", "2235keV", "3498keV", "4810keV", "6550keV"};
|
||||
TString labels[] = {"Ground State", "2.235 MeV", "3.498 MeV",
|
||||
"4.810 MeV", "6.550 MeV"};
|
||||
// TString states[] = {"GS", "2235keV", "3498keV", "4810keV", "6550keV"};
|
||||
// TString labels[] = {"Ground State", "2.235 MeV", "3.498 MeV", "4.810 MeV", "6.550 MeV"};
|
||||
// // double xlo[] = {0, 4, 12, 24, 36};
|
||||
// // double xhi[] = {4, 12, 24, 36, 90};
|
||||
|
||||
// Per-state display window (MeV), same order as states[] above.
|
||||
// See the header comment for why these are currently a no-op.
|
||||
// double xlo[] = {0, 4, 12, 24, 36};
|
||||
// double xhi[] = {4, 12, 24, 36, 90};
|
||||
double xlo[] = {0, 4, 16, 28, 36};
|
||||
double xhi[] = {4, 16, 28, 36, 90};
|
||||
// TString states[] = {"GS", "2235keV", "3498keV", "5279keV"};//, "6550keV"};
|
||||
// TString labels[] = {"Ground State", "2.235 MeV", "3.498 MeV", "5.279 MeV"};//, "6.550 MeV"};
|
||||
// double xlo[] = {0, 4, 16, 28};
|
||||
// double xhi[] = {4, 16, 28, 90};
|
||||
|
||||
TString states[] = {"2235keV", "3498keV", "5279keV", "5951keV"}; //"GS", "6550keV"
|
||||
TString labels[] = {"2.235 MeV", "3.498 MeV", "5.279 MeV", "5.951 MeV"}; //"Ground State", "6.550 MeV"
|
||||
// Boundary where the band centroid (a7_band_slices.csv) passes midway
|
||||
// between the two assumed states: 2.87, 4.39, 5.62 MeV.
|
||||
double xlo[] = {4, 16, 27, 35};
|
||||
double xhi[] = {16, 27, 35, 90};
|
||||
|
||||
const size_t nStates = sizeof(states) / sizeof(states[0]);
|
||||
if (sizeof(labels) / sizeof(labels[0]) != nStates ||
|
||||
|
|
@ -154,7 +160,14 @@ void overlay_2d(TString rootFile, TString xAxisLabel, TString yAxisLabel,
|
|||
}
|
||||
hists[i]->RebinX(rebinX);
|
||||
hists[i]->RebinY(rebinY);
|
||||
hists[i]->SetMinimum(minz);
|
||||
// hists[i]->SetMinimum(minz);
|
||||
// Display floor per state: never above minz, but lowered for a sparse
|
||||
// window so it is not hidden -- 2% of this state's own peak bin, at
|
||||
// least 2 counts.
|
||||
double thr = std::min(minz, std::max(2.0, 0.02 * hists[i]->GetMaximum()));
|
||||
hists[i]->SetMinimum(thr);
|
||||
std::cout << states[i] << ": peak " << hists[i]->GetMaximum()
|
||||
<< ", floor " << thr << "\n";
|
||||
}
|
||||
|
||||
double globalMax = 0;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user