modified: TrackRecon.C mismatched braces
This commit is contained in:
parent
fce1fb6c1d
commit
4d9145d532
839
TrackRecon.C
839
TrackRecon.C
|
|
@ -1496,483 +1496,484 @@ Bool_t TrackRecon::Process(Long64_t entry)
|
||||||
for (int j = i + 1; j < pc.multi; j++)
|
for (int j = i + 1; j < pc.multi; j++)
|
||||||
{
|
{
|
||||||
if (doRawHistos)
|
if (doRawHistos)
|
||||||
|
{
|
||||||
plotter->Fill2D("PC_Coincidence_Matrix", 48, 0, 48, 48, 0, 48, pc.index[i], pc.index[j], "hRawPC");
|
plotter->Fill2D("PC_Coincidence_Matrix", 48, 0, 48, 48, 0, 48, pc.index[i], pc.index[j], "hRawPC");
|
||||||
// only tag with anodeT-cathodeT once both are real: with the sentinels still in
|
// only tag with anodeT-cathodeT once both are real: with the sentinels still in
|
||||||
// place the difference is -199998, which piled the early hits into the "_1" plot
|
// place the difference is -199998, which piled the early hits into the "_1" plot
|
||||||
if (anodeT != -99999 && cathodeT != 99999)
|
if (anodeT != -99999 && cathodeT != 99999)
|
||||||
plotter->Fill2D("PC_Coincidence_Matrix_anodeMinusCathode_lt_-200_" + std::to_string(anodeT - cathodeT < -200), 48, 0, 48, 48, 0, 48, pc.index[i], pc.index[j], "hRawPC");
|
plotter->Fill2D("PC_Coincidence_Matrix_anodeMinusCathode_lt_-200_" + std::to_string(anodeT - cathodeT < -200), 48, 0, 48, 48, 0, 48, pc.index[i], pc.index[j], "hRawPC");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (diagnostic_eplots)
|
if (diagnostic_eplots)
|
||||||
|
{
|
||||||
|
plotter->Fill2D("Anode_V_Anode", 24, 0, 24, 24, 0, 24, pc.index[i], pc.index[j], "hGMPC");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// anodeT - cathodeT is one number per event, so it gets filled once per event.
|
||||||
|
// This block used to sit inside the pc.multi loop above *and* wrap an inner loop
|
||||||
|
// over qqq.multi / sx3.multi, so the identical value was filled O(pc.multi x
|
||||||
|
// qqq.multi) times -- inflating the statistics and weighting every event by its
|
||||||
|
// own multiplicity. PC_Time_Vs_QQQ_ch genuinely needs the channel loop, so it
|
||||||
|
// keeps one; the rest do not.
|
||||||
|
if (diagnostic_tplots && anodeT != -99999 && cathodeT != 99999)
|
||||||
|
{
|
||||||
|
double pcDT = anodeT - cathodeT;
|
||||||
|
plotter->Fill1D("PC_Time", 200, -2000, 2000, pcDT, "hTiming");
|
||||||
|
if (qqq.multi > 0)
|
||||||
{
|
{
|
||||||
plotter->Fill2D("Anode_V_Anode", 24, 0, 24, 24, 0, 24, pc.index[i], pc.index[j], "hGMPC");
|
plotter->Fill1D("PC_Time_qqq", 200, -2000, 2000, pcDT, "hTiming");
|
||||||
|
plotter->Fill2D("PC_Time_vs_AIndex_qqq", 200, -2000, 2000, 24, -0.5, 23.5, pcDT, anodeIndex, "hTiming");
|
||||||
|
plotter->Fill2D("PC_Time_vs_CIndex_qqq", 200, -2000, 2000, 24, -0.5, 23.5, pcDT, cathodeIndex, "hTiming");
|
||||||
|
for (int j = 0; j < qqq.multi; j++)
|
||||||
|
plotter->Fill2D("PC_Time_Vs_QQQ_ch", 200, -2000, 2000, 16 * 8, -0.5, 16 * 8 - 0.5, pcDT, qqq.ch[j], "hTiming");
|
||||||
}
|
}
|
||||||
}
|
if (sx3.multi > 0)
|
||||||
}
|
|
||||||
|
|
||||||
// anodeT - cathodeT is one number per event, so it gets filled once per event.
|
|
||||||
// This block used to sit inside the pc.multi loop above *and* wrap an inner loop
|
|
||||||
// over qqq.multi / sx3.multi, so the identical value was filled O(pc.multi x
|
|
||||||
// qqq.multi) times -- inflating the statistics and weighting every event by its
|
|
||||||
// own multiplicity. PC_Time_Vs_QQQ_ch genuinely needs the channel loop, so it
|
|
||||||
// keeps one; the rest do not.
|
|
||||||
if (diagnostic_tplots && anodeT != -99999 && cathodeT != 99999)
|
|
||||||
{
|
|
||||||
double pcDT = anodeT - cathodeT;
|
|
||||||
plotter->Fill1D("PC_Time", 200, -2000, 2000, pcDT, "hTiming");
|
|
||||||
if (qqq.multi > 0)
|
|
||||||
{
|
|
||||||
plotter->Fill1D("PC_Time_qqq", 200, -2000, 2000, pcDT, "hTiming");
|
|
||||||
plotter->Fill2D("PC_Time_vs_AIndex_qqq", 200, -2000, 2000, 24, -0.5, 23.5, pcDT, anodeIndex, "hTiming");
|
|
||||||
plotter->Fill2D("PC_Time_vs_CIndex_qqq", 200, -2000, 2000, 24, -0.5, 23.5, pcDT, cathodeIndex, "hTiming");
|
|
||||||
for (int j = 0; j < qqq.multi; j++)
|
|
||||||
plotter->Fill2D("PC_Time_Vs_QQQ_ch", 200, -2000, 2000, 16 * 8, -0.5, 16 * 8 - 0.5, pcDT, qqq.ch[j], "hTiming");
|
|
||||||
}
|
|
||||||
if (sx3.multi > 0)
|
|
||||||
{
|
|
||||||
plotter->Fill1D("PC_Time_sx3", 200, -2000, 2000, pcDT, "hTiming");
|
|
||||||
plotter->Fill2D("PC_Time_vs_AIndex_sx3", 200, -2000, 2000, 24, -0.5, 23.5, pcDT, anodeIndex, "hTiming");
|
|
||||||
plotter->Fill2D("PC_Time_vs_CIndex_sx3", 200, -2000, 2000, 24, -0.5, 23.5, pcDT, cathodeIndex, "hTiming");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
anodeHits.clear();
|
|
||||||
cathodeHits.clear();
|
|
||||||
corrcatMax.clear();
|
|
||||||
|
|
||||||
for (int i = 0; i < pc.multi; i++)
|
|
||||||
{
|
|
||||||
// if (pc.e[i] > 100)
|
|
||||||
{
|
|
||||||
if (pc.index[i] < 24)
|
|
||||||
{
|
{
|
||||||
anodeHits.push_back(std::pair<int, double>(pc.index[i], pc.e[i]));
|
plotter->Fill1D("PC_Time_sx3", 200, -2000, 2000, pcDT, "hTiming");
|
||||||
}
|
plotter->Fill2D("PC_Time_vs_AIndex_sx3", 200, -2000, 2000, 24, -0.5, 23.5, pcDT, anodeIndex, "hTiming");
|
||||||
else if (pc.index[i] >= 24)
|
plotter->Fill2D("PC_Time_vs_CIndex_sx3", 200, -2000, 2000, 24, -0.5, 23.5, pcDT, cathodeIndex, "hTiming");
|
||||||
{
|
|
||||||
cathodeHits.push_back(std::pair<int, double>(pc.index[i] - 24, pc.e[i] * cathode_gain));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
std::sort(anodeHits.begin(), anodeHits.end(), [](std::pair<int, double> a, std::pair<int, double> b)
|
anodeHits.clear();
|
||||||
{ return a.first < b.first; });
|
cathodeHits.clear();
|
||||||
|
corrcatMax.clear();
|
||||||
|
|
||||||
std::sort(cathodeHits.begin(), cathodeHits.end(), [](std::pair<int, double> a, std::pair<int, double> b)
|
for (int i = 0; i < pc.multi; i++)
|
||||||
{ return a.first < b.first; });
|
|
||||||
|
|
||||||
// clusters = collection of (collection of wires) where each wire is (index, energy, timestamp)
|
|
||||||
std::vector<std::vector<std::tuple<int, double, double>>> aClusters = pwinstance.Make_Clusters(aWireEvents);
|
|
||||||
std::vector<std::vector<std::tuple<int, double, double>>> cClusters = pwinstance.Make_Clusters(cWireEvents);
|
|
||||||
|
|
||||||
for (const auto &aCluster : aClusters)
|
|
||||||
{
|
|
||||||
if (clusterHasExcludedAnode(aCluster))
|
|
||||||
continue;
|
|
||||||
if (aCluster.size() == 2)
|
|
||||||
{
|
{
|
||||||
double ae0 = std::get<1>(aCluster[0]);
|
// if (pc.e[i] > 100)
|
||||||
double ae1 = std::get<1>(aCluster[1]);
|
|
||||||
double alo = std::min(ae0, ae1);
|
|
||||||
double ahi = std::max(ae0, ae1);
|
|
||||||
|
|
||||||
// Calibrated (MeV) wire energies for the same pair -- same pcEnergySlope
|
|
||||||
// lookup used everywhere else (e.g. anodeE_MeV in protonAlphaElastic_core).
|
|
||||||
int wi0 = std::get<0>(aCluster[0]);
|
|
||||||
int wi1 = std::get<0>(aCluster[1]);
|
|
||||||
double ae0_MeV = (wi0 >= 0 && wi0 < 24) ? pcEnergySlope[wi0] * ae0 : -1.0;
|
|
||||||
double ae1_MeV = (wi1 >= 0 && wi1 < 24) ? pcEnergySlope[wi1] * ae1 : -1.0;
|
|
||||||
|
|
||||||
if (ahi > 0.0)
|
|
||||||
{
|
{
|
||||||
double aratio = alo / ahi;
|
if (pc.index[i] < 24)
|
||||||
plotter->Fill1D("A2_anode_ratio_raw", 120, 0, 1.2, aratio, "hGMPC");
|
{
|
||||||
// plotter->Fill2D("A2_anode_ratio_vs_sum", 800, 0, 40000, 120, 0, 1.2, ae0 + ae1, aratio, "hGMPC");
|
anodeHits.push_back(std::pair<int, double>(pc.index[i], pc.e[i]));
|
||||||
plotter->Fill2D("A1_vs_A2_raw", 800, 0, 40000, 800, 0, 40000, ae0, ae1, "hGMPC");
|
}
|
||||||
plotter->Fill2D("A2_anode_ratio_vs_lowerIndex", 24, 0, 24, 120, 0, 1.2,
|
else if (pc.index[i] >= 24)
|
||||||
std::min(std::get<0>(aCluster[0]), std::get<0>(aCluster[1])), aratio, "hGMPC");
|
{
|
||||||
|
cathodeHits.push_back(std::pair<int, double>(pc.index[i] - 24, pc.e[i] * cathode_gain));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calibrated equivalents -- guarded independently since a wire can lack
|
|
||||||
// a valid pcEnergySlope entry even when its raw ADC value is fine.
|
|
||||||
if (ae0_MeV >= 0.0 && ae1_MeV >= 0.0 && std::max(ae0_MeV, ae1_MeV) > 0.0)
|
|
||||||
{
|
|
||||||
double alo_MeV = std::min(ae0_MeV, ae1_MeV);
|
|
||||||
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.6, 800, 0, 0.6, 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");
|
|
||||||
}
|
|
||||||
|
|
||||||
plotter->Fill1D("Raw_A2_AnodeSum", 800, 0, 40000, ae0 + ae1, "hGMPC");
|
|
||||||
}
|
}
|
||||||
else if (aCluster.size() == 1)
|
|
||||||
|
std::sort(anodeHits.begin(), anodeHits.end(), [](std::pair<int, double> a, std::pair<int, double> b)
|
||||||
|
{ return a.first < b.first; });
|
||||||
|
|
||||||
|
std::sort(cathodeHits.begin(), cathodeHits.end(), [](std::pair<int, double> a, std::pair<int, double> b)
|
||||||
|
{ return a.first < b.first; });
|
||||||
|
|
||||||
|
// clusters = collection of (collection of wires) where each wire is (index, energy, timestamp)
|
||||||
|
std::vector<std::vector<std::tuple<int, double, double>>> aClusters = pwinstance.Make_Clusters(aWireEvents);
|
||||||
|
std::vector<std::vector<std::tuple<int, double, double>>> cClusters = pwinstance.Make_Clusters(cWireEvents);
|
||||||
|
|
||||||
|
for (const auto &aCluster : aClusters)
|
||||||
{
|
{
|
||||||
plotter->Fill1D("Raw_A1_AnodeSum", 800, 0, 40000, std::get<1>(aCluster[0]), "hGMPC");
|
if (clusterHasExcludedAnode(aCluster))
|
||||||
}
|
|
||||||
for (const auto &cCluster : cClusters)
|
|
||||||
{
|
|
||||||
if (aCluster.size() == 0)
|
|
||||||
continue;
|
continue;
|
||||||
if (cCluster.size() == 0)
|
if (aCluster.size() == 2)
|
||||||
continue;
|
|
||||||
// both have at least 1, here. Keep the a1, c1 events
|
|
||||||
auto [crossover, alpha, apSumE, cpSumE, apMaxE, cpMaxE, apTSMaxE, cpTSMaxE] = pwinstance.FindCrossoverProperties(aCluster, cCluster);
|
|
||||||
if (alpha != 9999999 && apSumE != -1)
|
|
||||||
{
|
{
|
||||||
// Event PCEvent(crossover,apMaxE,cpMaxE,apTSMaxE,cpTSMaxE);
|
double ae0 = std::get<1>(aCluster[0]);
|
||||||
// Event PCEvent(crossover,apSumE,cpSumE,apTSMaxE,cpTSMaxE);
|
double ae1 = std::get<1>(aCluster[1]);
|
||||||
Event PCEvent(crossover, apSumE, cpMaxE, cpSumE, apTSMaxE, cpTSMaxE); // run12 shows cathode-max and anode-sum provide best dE signals.
|
double alo = std::min(ae0, ae1);
|
||||||
// std::cout << apSumE << " " << crossover.Perp() << " " << apMaxE << " " << apTSMaxE << std::endl;
|
double ahi = std::max(ae0, ae1);
|
||||||
PCEvent.multi1 = aCluster.size();
|
|
||||||
PCEvent.multi2 = cCluster.size();
|
// Calibrated (MeV) wire energies for the same pair -- same pcEnergySlope
|
||||||
PCEvent.Anodech = std::get<0>(aCluster[0]);
|
// lookup used everywhere else (e.g. anodeE_MeV in protonAlphaElastic_core).
|
||||||
PCEvent.Cathodech = std::get<0>(cCluster[0]);
|
int wi0 = std::get<0>(aCluster[0]);
|
||||||
PC_Events.push_back(PCEvent);
|
int wi1 = std::get<0>(aCluster[1]);
|
||||||
|
double ae0_MeV = (wi0 >= 0 && wi0 < 24) ? pcEnergySlope[wi0] * ae0 : -1.0;
|
||||||
|
double ae1_MeV = (wi1 >= 0 && wi1 < 24) ? pcEnergySlope[wi1] * ae1 : -1.0;
|
||||||
|
|
||||||
|
if (ahi > 0.0)
|
||||||
|
{
|
||||||
|
double aratio = alo / ahi;
|
||||||
|
plotter->Fill1D("A2_anode_ratio_raw", 120, 0, 1.2, aratio, "hGMPC");
|
||||||
|
// plotter->Fill2D("A2_anode_ratio_vs_sum", 800, 0, 40000, 120, 0, 1.2, ae0 + ae1, aratio, "hGMPC");
|
||||||
|
plotter->Fill2D("A1_vs_A2_raw", 800, 0, 40000, 800, 0, 40000, ae0, ae1, "hGMPC");
|
||||||
|
plotter->Fill2D("A2_anode_ratio_vs_lowerIndex", 24, 0, 24, 120, 0, 1.2,
|
||||||
|
std::min(std::get<0>(aCluster[0]), std::get<0>(aCluster[1])), aratio, "hGMPC");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calibrated equivalents -- guarded independently since a wire can lack
|
||||||
|
// a valid pcEnergySlope entry even when its raw ADC value is fine.
|
||||||
|
if (ae0_MeV >= 0.0 && ae1_MeV >= 0.0 && std::max(ae0_MeV, ae1_MeV) > 0.0)
|
||||||
|
{
|
||||||
|
double alo_MeV = std::min(ae0_MeV, ae1_MeV);
|
||||||
|
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.6, 800, 0, 0.6, 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");
|
||||||
|
}
|
||||||
|
|
||||||
|
plotter->Fill1D("Raw_A2_AnodeSum", 800, 0, 40000, ae0 + ae1, "hGMPC");
|
||||||
|
}
|
||||||
|
else if (aCluster.size() == 1)
|
||||||
|
{
|
||||||
|
plotter->Fill1D("Raw_A1_AnodeSum", 800, 0, 40000, std::get<1>(aCluster[0]), "hGMPC");
|
||||||
|
}
|
||||||
|
for (const auto &cCluster : cClusters)
|
||||||
|
{
|
||||||
|
if (aCluster.size() == 0)
|
||||||
|
continue;
|
||||||
|
if (cCluster.size() == 0)
|
||||||
|
continue;
|
||||||
|
// both have at least 1, here. Keep the a1, c1 events
|
||||||
|
auto [crossover, alpha, apSumE, cpSumE, apMaxE, cpMaxE, apTSMaxE, cpTSMaxE] = pwinstance.FindCrossoverProperties(aCluster, cCluster);
|
||||||
|
if (alpha != 9999999 && apSumE != -1)
|
||||||
|
{
|
||||||
|
// Event PCEvent(crossover,apMaxE,cpMaxE,apTSMaxE,cpTSMaxE);
|
||||||
|
// Event PCEvent(crossover,apSumE,cpSumE,apTSMaxE,cpTSMaxE);
|
||||||
|
Event PCEvent(crossover, apSumE, cpMaxE, cpSumE, apTSMaxE, cpTSMaxE); // run12 shows cathode-max and anode-sum provide best dE signals.
|
||||||
|
// std::cout << apSumE << " " << crossover.Perp() << " " << apMaxE << " " << apTSMaxE << std::endl;
|
||||||
|
PCEvent.multi1 = aCluster.size();
|
||||||
|
PCEvent.multi2 = cCluster.size();
|
||||||
|
PCEvent.Anodech = std::get<0>(aCluster[0]);
|
||||||
|
PCEvent.Cathodech = std::get<0>(cCluster[0]);
|
||||||
|
PC_Events.push_back(PCEvent);
|
||||||
|
|
||||||
|
if (pcEnergyCalibLoaded)
|
||||||
|
{
|
||||||
|
Event PCEventCalibrated = PCEvent;
|
||||||
|
PCEventCalibrated.rawEnergy1 = PCEvent.Energy1; // stash BEFORE overwriting -- see rawEnergy1/2 comment on Event
|
||||||
|
PCEventCalibrated.rawEnergy2 = PCEvent.Energy2;
|
||||||
|
double anodeCalibSum = 0.0;
|
||||||
|
for (const auto &w : aCluster)
|
||||||
|
{
|
||||||
|
int wi = std::get<0>(w);
|
||||||
|
if (wi >= 0 && wi < 24)
|
||||||
|
anodeCalibSum += pcEnergySlope[wi] * std::get<1>(w);
|
||||||
|
}
|
||||||
|
PCEventCalibrated.Energy1 = anodeCalibSum;
|
||||||
|
// Cathode uses the single max-energy wire (cpMaxE). That wire is NOT
|
||||||
|
// necessarily cCluster[0], which is all PCEvent.Cathodech records, so
|
||||||
|
// pcEnergySlope[24 + Cathodech] was applying the wrong wire's constant to
|
||||||
|
// cpMaxE for every multi-wire cathode cluster -- i.e. for A1C2, the primary
|
||||||
|
// topology. GetPseudoWire tracks the max energy but not its index, so find
|
||||||
|
// it here rather than change that signature for its five call sites.
|
||||||
|
int cMaxWire = PCEvent.Cathodech;
|
||||||
|
double cMaxE = -1.0;
|
||||||
|
for (const auto &w : cCluster)
|
||||||
|
{
|
||||||
|
if (std::get<1>(w) > cMaxE)
|
||||||
|
{
|
||||||
|
cMaxE = std::get<1>(w);
|
||||||
|
cMaxWire = std::get<0>(w);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PCEventCalibrated.Energy2 = (cMaxWire >= 0 && cMaxWire < 24)
|
||||||
|
? pcEnergySlope[24 + cMaxWire] * cpMaxE
|
||||||
|
: cpMaxE;
|
||||||
|
PC_Events_calibrated.push_back(PCEventCalibrated);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
; // std::cout << "AAAA " << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cClusters.empty())
|
||||||
|
{
|
||||||
|
for (const auto &aCl : aClusters)
|
||||||
|
{
|
||||||
|
if (aCl.size() < 1 || aCl.size() > 2) // A1C0 (1 wire) or A2C0 (2 wires) --
|
||||||
|
continue; // reaction_ax_core / protonAlphaElastic_core's
|
||||||
|
// a1c0 convention, one wire wider for A2C0.
|
||||||
|
if (clusterHasExcludedAnode(aCl))
|
||||||
|
continue;
|
||||||
|
auto aPw = pwinstance.GetPseudoWire(aCl, "ANODE");
|
||||||
|
auto apwire = std::get<0>(aPw);
|
||||||
|
double apSumE = std::get<1>(aPw);
|
||||||
|
double apTSMaxE = std::get<3>(aPw);
|
||||||
|
int anodeIdx = std::get<0>(aCl[0]); // representative wire index (tag/sanity-check only,
|
||||||
|
if (anodeIdx < 0 || anodeIdx >= 24) // not assumed to be "the" wire for A2C0's 2-wire cluster)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
const Event *bestSi = nullptr;
|
||||||
|
bool bestIsQQQ = true;
|
||||||
|
double bestDphi = 1e9;
|
||||||
|
auto consider = [&](const std::vector<Event> &sis, bool isQQQ)
|
||||||
|
{
|
||||||
|
for (const auto &si : sis)
|
||||||
|
{
|
||||||
|
if (!siPcCoincident(si.Time1, apTSMaxE))
|
||||||
|
continue;
|
||||||
|
TVector3 pc = pwinstance.getClosestWirePosAtWirePhi(apwire, si.pos.Phi());
|
||||||
|
double dphi = TMath::Abs(si.pos.DeltaPhi(pc));
|
||||||
|
double phi_win = isQQQ ? TMath::Pi() / 4.0 : TMath::Pi() / 3.0; // per-detector, as elsewhere
|
||||||
|
if (dphi <= phi_win && dphi < bestDphi)
|
||||||
|
{
|
||||||
|
bestDphi = dphi;
|
||||||
|
bestSi = &si;
|
||||||
|
bestIsQQQ = isQQQ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
consider(QQQ_Events, true);
|
||||||
|
consider(SX3_Events, false);
|
||||||
|
if (!bestSi)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
bool isA2C0 = (aCl.size() == 2);
|
||||||
|
TVector3 pc = isA2C0 ? a2c0_wirePos(apwire, bestSi->pos.Phi(), bestIsQQQ)
|
||||||
|
: a1c0_wirePos(apwire, bestSi->pos.Phi(), bestIsQQQ); // same z reference as the benchmark
|
||||||
|
|
||||||
|
Event PCEventRaw(pc, apSumE, -1.0, apTSMaxE, -1.0);
|
||||||
|
PCEventRaw.multi1 = static_cast<int>(aCl.size());
|
||||||
|
PCEventRaw.multi2 = 0;
|
||||||
|
PCEventRaw.Anodech = anodeIdx;
|
||||||
|
PCEventRaw.Cathodech = -1;
|
||||||
|
PC_Events.push_back(PCEventRaw);
|
||||||
|
|
||||||
if (pcEnergyCalibLoaded)
|
if (pcEnergyCalibLoaded)
|
||||||
{
|
{
|
||||||
Event PCEventCalibrated = PCEvent;
|
|
||||||
PCEventCalibrated.rawEnergy1 = PCEvent.Energy1; // stash BEFORE overwriting -- see rawEnergy1/2 comment on Event
|
|
||||||
PCEventCalibrated.rawEnergy2 = PCEvent.Energy2;
|
|
||||||
double anodeCalibSum = 0.0;
|
double anodeCalibSum = 0.0;
|
||||||
for (const auto &w : aCluster)
|
for (const auto &w : aCl)
|
||||||
{
|
{
|
||||||
int wi = std::get<0>(w);
|
int wi = std::get<0>(w);
|
||||||
if (wi >= 0 && wi < 24)
|
if (wi >= 0 && wi < 24)
|
||||||
anodeCalibSum += pcEnergySlope[wi] * std::get<1>(w);
|
anodeCalibSum += pcEnergySlope[wi] * std::get<1>(w);
|
||||||
}
|
}
|
||||||
PCEventCalibrated.Energy1 = anodeCalibSum;
|
Event ev(pc, anodeCalibSum, -1.0, apTSMaxE, -1.0);
|
||||||
// Cathode uses the single max-energy wire (cpMaxE). That wire is NOT
|
ev.multi1 = static_cast<int>(aCl.size());
|
||||||
// necessarily cCluster[0], which is all PCEvent.Cathodech records, so
|
ev.multi2 = 0; // no cathode -> a1c0/a2c0 topology in pcCalibratedHistograms
|
||||||
// pcEnergySlope[24 + Cathodech] was applying the wrong wire's constant to
|
ev.Anodech = anodeIdx;
|
||||||
// cpMaxE for every multi-wire cathode cluster -- i.e. for A1C2, the primary
|
ev.Cathodech = -1;
|
||||||
// topology. GetPseudoWire tracks the max energy but not its index, so find
|
PC_Events_calibrated.push_back(ev);
|
||||||
// it here rather than change that signature for its five call sites.
|
|
||||||
int cMaxWire = PCEvent.Cathodech;
|
|
||||||
double cMaxE = -1.0;
|
|
||||||
for (const auto &w : cCluster)
|
|
||||||
{
|
|
||||||
if (std::get<1>(w) > cMaxE)
|
|
||||||
{
|
|
||||||
cMaxE = std::get<1>(w);
|
|
||||||
cMaxWire = std::get<0>(w);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
PCEventCalibrated.Energy2 = (cMaxWire >= 0 && cMaxWire < 24)
|
|
||||||
? pcEnergySlope[24 + cMaxWire] * cpMaxE
|
|
||||||
: cpMaxE;
|
|
||||||
PC_Events_calibrated.push_back(PCEventCalibrated);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
; // std::cout << "AAAA " << std::endl;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (cClusters.empty())
|
if (doPCEnergyCalibration)
|
||||||
{
|
|
||||||
for (const auto &aCl : aClusters)
|
|
||||||
{
|
{
|
||||||
if (aCl.size() < 1 || aCl.size() > 2) // A1C0 (1 wire) or A2C0 (2 wires) --
|
pcEnergyCalibrationAccumulate(PC_Events, QQQ_Events, SX3_Events);
|
||||||
continue; // reaction_ax_core / protonAlphaElastic_core's
|
pcEnergyCalibrationAccumulateProton(PC_Events, QQQ_Events, SX3_Events);
|
||||||
// a1c0 convention, one wire wider for A2C0.
|
}
|
||||||
if (clusterHasExcludedAnode(aCl))
|
|
||||||
continue;
|
|
||||||
auto aPw = pwinstance.GetPseudoWire(aCl, "ANODE");
|
|
||||||
auto apwire = std::get<0>(aPw);
|
|
||||||
double apSumE = std::get<1>(aPw);
|
|
||||||
double apTSMaxE = std::get<3>(aPw);
|
|
||||||
int anodeIdx = std::get<0>(aCl[0]); // representative wire index (tag/sanity-check only,
|
|
||||||
if (anodeIdx < 0 || anodeIdx >= 24) // not assumed to be "the" wire for A2C0's 2-wire cluster)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
const Event *bestSi = nullptr;
|
//////Timing stuff for F data
|
||||||
bool bestIsQQQ = true;
|
|
||||||
double bestDphi = 1e9;
|
TRandom3 &rnd = anasenRandom;
|
||||||
auto consider = [&](const std::vector<Event> &sis, bool isQQQ)
|
double dt_rf_mcp_event = -987654321;
|
||||||
|
double ts_rf_event = -987654321, ts_mcp_event = -987654321;
|
||||||
|
{
|
||||||
|
for (int j = 0; j < misc.multi; j++)
|
||||||
{
|
{
|
||||||
for (const auto &si : sis)
|
if (misc.ch[j] == 3)
|
||||||
|
ts_rf_event = static_cast<double>(misc.t[j]) + static_cast<double>(misc.tf[j]);
|
||||||
|
if (misc.ch[j] == 4)
|
||||||
|
ts_mcp_event = static_cast<double>(misc.t[j]) + static_cast<double>(misc.tf[j]);
|
||||||
|
}
|
||||||
|
if (ts_rf_event > -987654321 && ts_mcp_event > -987654321)
|
||||||
|
dt_rf_mcp_event = ts_rf_event - ts_mcp_event;
|
||||||
|
}
|
||||||
|
if (dataset == "17F" && reactiondata)
|
||||||
|
{
|
||||||
|
// misc.ch is a property of the event, not of any Si hit -- filled inside the
|
||||||
|
// per-QQQ and per-SX3 loops it was multiplied by the Si multiplicity.
|
||||||
|
for (int j = 0; j < misc.multi; j++)
|
||||||
|
{
|
||||||
|
if (QQQ_Events.size())
|
||||||
|
plotter->Fill1D("channels_misc_qqq", 20, -0.5, 19.5, misc.ch[j], "misc");
|
||||||
|
if (SX3_Events.size())
|
||||||
|
plotter->Fill1D("channels_misc_sx3", 20, -0.5, 19.5, misc.ch[j], "misc");
|
||||||
|
}
|
||||||
|
|
||||||
|
int ctr = 0;
|
||||||
|
for (const auto &qqqevent : QQQ_Events)
|
||||||
|
{
|
||||||
|
double ts_rf = -987654321;
|
||||||
|
double ts_needle = -987654321;
|
||||||
|
double ts_mcp = -987654321;
|
||||||
|
// Time1 already carries the +/-8 clock dither applied when the QQQ Event was
|
||||||
|
// built (tRing), so re-dithering here widened this folder's timing by sqrt(2)
|
||||||
|
// relative to every other timing plot in the analysis.
|
||||||
|
double ts_qqq = static_cast<double>(qqqevent.Time1);
|
||||||
|
bool found_rf = false;
|
||||||
|
bool found_mcp = false;
|
||||||
|
bool found_needle = false;
|
||||||
|
bool qqq_inner_ring = (qqqevent.ch1 % 16) < 8;
|
||||||
|
for (int j = 0; j < misc.multi; j++)
|
||||||
{
|
{
|
||||||
if (!siPcCoincident(si.Time1, apTSMaxE))
|
if (misc.ch[j] == 2)
|
||||||
continue;
|
{ // Needle
|
||||||
TVector3 pc = pwinstance.getClosestWirePosAtWirePhi(apwire, si.pos.Phi());
|
plotter->Fill2D("needle_vs_qqqE", 800, 0, 16384, 800, 0, 10, misc.e[j], qqqevent.Energy1, "misc");
|
||||||
double dphi = TMath::Abs(si.pos.DeltaPhi(pc));
|
ts_needle = static_cast<double>(misc.t[j]) + static_cast<double>(misc.tf[j]);
|
||||||
double phi_win = isQQQ ? TMath::Pi() / 4.0 : TMath::Pi() / 3.0; // per-detector, as elsewhere
|
found_needle = 1;
|
||||||
if (dphi <= phi_win && dphi < bestDphi)
|
plotter->Fill1D("dt_qqq_needle", 800, -2000, 2000, ts_qqq - ts_needle, "misc");
|
||||||
{
|
}
|
||||||
bestDphi = dphi;
|
if (misc.ch[j] == 3)
|
||||||
bestSi = &si;
|
{ // RF
|
||||||
bestIsQQQ = isQQQ;
|
ts_rf = static_cast<double>(misc.t[j]) + static_cast<double>(misc.tf[j]);
|
||||||
|
found_rf = 1;
|
||||||
|
plotter->Fill1D("dt_qqq_rf_innerring" + std::to_string(qqq_inner_ring), 800, -2000, 2000, ts_qqq - ts_rf, "misc");
|
||||||
|
}
|
||||||
|
if (misc.ch[j] == 4)
|
||||||
|
{ // mcp
|
||||||
|
ts_mcp = static_cast<double>(misc.t[j]) + static_cast<double>(misc.tf[j]);
|
||||||
|
found_mcp = 1;
|
||||||
|
plotter->Fill1D("dt_qqq_mcp_innerring" + std::to_string(qqq_inner_ring), 800, -2000, 2000, ts_qqq - ts_mcp, "misc");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
if (found_rf && found_mcp)
|
||||||
consider(QQQ_Events, true);
|
|
||||||
consider(SX3_Events, false);
|
|
||||||
if (!bestSi)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
bool isA2C0 = (aCl.size() == 2);
|
|
||||||
TVector3 pc = isA2C0 ? a2c0_wirePos(apwire, bestSi->pos.Phi(), bestIsQQQ)
|
|
||||||
: a1c0_wirePos(apwire, bestSi->pos.Phi(), bestIsQQQ); // same z reference as the benchmark
|
|
||||||
|
|
||||||
Event PCEventRaw(pc, apSumE, -1.0, apTSMaxE, -1.0);
|
|
||||||
PCEventRaw.multi1 = static_cast<int>(aCl.size());
|
|
||||||
PCEventRaw.multi2 = 0;
|
|
||||||
PCEventRaw.Anodech = anodeIdx;
|
|
||||||
PCEventRaw.Cathodech = -1;
|
|
||||||
PC_Events.push_back(PCEventRaw);
|
|
||||||
|
|
||||||
if (pcEnergyCalibLoaded)
|
|
||||||
{
|
|
||||||
double anodeCalibSum = 0.0;
|
|
||||||
for (const auto &w : aCl)
|
|
||||||
{
|
{
|
||||||
int wi = std::get<0>(w);
|
if (ctr == 0)
|
||||||
if (wi >= 0 && wi < 24)
|
plotter->Fill1D("dt_rf_mcp_qqq_innerring" + std::to_string(qqq_inner_ring), 500, -1000, 1000, ts_rf - ts_mcp, "misc");
|
||||||
anodeCalibSum += pcEnergySlope[wi] * std::get<1>(w);
|
double dt_rf_mcp = ts_rf - ts_mcp;
|
||||||
|
double dt_qqq_rf = ts_qqq - ts_rf;
|
||||||
|
double dt_qqq_mcp = ts_qqq - ts_mcp;
|
||||||
|
plotter->Fill2D("dt(qqq,rf)_vs_(rf,mcp)_innerring" + std::to_string(qqq_inner_ring), 800, -2000, 2000, 640, -2000, 2000, dt_qqq_rf, dt_rf_mcp, "misc");
|
||||||
|
plotter->Fill2D("dt_(qqq,mcp)_vs_(qqq,rf)_innerring" + std::to_string(qqq_inner_ring), 800, -1400, 2000, 640, -2000, 2000, dt_qqq_mcp, dt_qqq_rf, "misc");
|
||||||
|
plotter->Fill2D("dt_(qqq,mcp)_vs_(rf,mcp)_innerring" + std::to_string(qqq_inner_ring), 1000, -1400, 1000, 640, -2000, 2000, dt_qqq_mcp, dt_rf_mcp, "misc");
|
||||||
}
|
}
|
||||||
Event ev(pc, anodeCalibSum, -1.0, apTSMaxE, -1.0);
|
ctr += 1;
|
||||||
ev.multi1 = static_cast<int>(aCl.size());
|
}
|
||||||
ev.multi2 = 0; // no cathode -> a1c0/a2c0 topology in pcCalibratedHistograms
|
|
||||||
ev.Anodech = anodeIdx;
|
for (const auto &sx3event : SX3_Events)
|
||||||
ev.Cathodech = -1;
|
{
|
||||||
PC_Events_calibrated.push_back(ev);
|
double ts_rf = -987654321;
|
||||||
|
double ts_needle = -987654321;
|
||||||
|
double ts_mcp = -987654321;
|
||||||
|
// as with ts_qqq: det.ts was already dithered when the SX3 Event was built
|
||||||
|
double ts_sx3 = static_cast<double>(sx3event.Time1);
|
||||||
|
bool found_rf = false;
|
||||||
|
bool found_mcp = false;
|
||||||
|
bool found_needle = false;
|
||||||
|
for (int j = 0; j < misc.multi; j++)
|
||||||
|
{
|
||||||
|
if (misc.ch[j] == 2)
|
||||||
|
{ // Needle
|
||||||
|
plotter->Fill2D("needle_vs_sx3E", 800, 0, 16384, 800, 0, 10, misc.e[j], sx3event.Energy1, "misc");
|
||||||
|
ts_needle = static_cast<double>(misc.t[j]) + static_cast<double>(misc.tf[j]);
|
||||||
|
found_needle = 1;
|
||||||
|
plotter->Fill1D("dt_sx3_needle", 800, -2000, 2000, ts_sx3 - ts_needle, "misc");
|
||||||
|
}
|
||||||
|
if (misc.ch[j] == 3)
|
||||||
|
{ // RF
|
||||||
|
ts_rf = static_cast<double>(misc.t[j]) + static_cast<double>(misc.tf[j]);
|
||||||
|
found_rf = 1;
|
||||||
|
plotter->Fill1D("dt_sx3_rf", 800, -2000, 2000, ts_sx3 - ts_rf, "misc");
|
||||||
|
}
|
||||||
|
if (misc.ch[j] == 4)
|
||||||
|
{ // mcp
|
||||||
|
ts_mcp = static_cast<double>(misc.t[j]) + static_cast<double>(misc.tf[j]);
|
||||||
|
found_mcp = 1;
|
||||||
|
plotter->Fill1D("dt_sx3_mcp", 800, -2000, 2000, ts_sx3 - ts_mcp, "misc");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (found_rf && found_mcp)
|
||||||
|
{
|
||||||
|
if (ctr == 0)
|
||||||
|
plotter->Fill1D("dt_rf_mcp_sx3", 500, -1000, 1000, ts_rf - ts_mcp, "misc");
|
||||||
|
double dt_rf_mcp = ts_rf - ts_mcp;
|
||||||
|
double dt_sx3_rf = ts_sx3 - ts_rf;
|
||||||
|
double dt_sx3_mcp = ts_sx3 - ts_mcp;
|
||||||
|
plotter->Fill2D("dt(sx3,rf)_vs_(rf,mcp)", 800, -2000, 2000, 640, -2000, 2000, dt_sx3_rf, dt_rf_mcp, "misc");
|
||||||
|
plotter->Fill2D("dt_(sx3,mcp)_vs_(sx3,rf)", 800, -1400, 2000, 640, -2000, 2000, dt_sx3_mcp, dt_sx3_rf, "misc");
|
||||||
|
plotter->Fill2D("dt_(sx3,mcp)_vs_(rf,mcp)", 1000, -1400, 1000, 640, -2000, 2000, dt_sx3_mcp, dt_rf_mcp, "misc");
|
||||||
|
}
|
||||||
|
ctr += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (doPCEnergyCalibration)
|
if (process_alpha_proton_scattering)
|
||||||
{
|
|
||||||
pcEnergyCalibrationAccumulate(PC_Events, QQQ_Events, SX3_Events);
|
|
||||||
pcEnergyCalibrationAccumulateProton(PC_Events, QQQ_Events, SX3_Events);
|
|
||||||
}
|
|
||||||
|
|
||||||
//////Timing stuff for F data
|
|
||||||
|
|
||||||
TRandom3 &rnd = anasenRandom;
|
|
||||||
double dt_rf_mcp_event = -987654321;
|
|
||||||
double ts_rf_event = -987654321, ts_mcp_event = -987654321;
|
|
||||||
{
|
|
||||||
for (int j = 0; j < misc.multi; j++)
|
|
||||||
{
|
{
|
||||||
if (misc.ch[j] == 3)
|
protonAlphaHistograms(plotter, QQQ_Events, SX3_Events, PC_Events);
|
||||||
ts_rf_event = static_cast<double>(misc.t[j]) + static_cast<double>(misc.tf[j]);
|
// return kTRUE;
|
||||||
if (misc.ch[j] == 4)
|
} // end if(process_alpha_proton_scattering)
|
||||||
ts_mcp_event = static_cast<double>(misc.t[j]) + static_cast<double>(misc.tf[j]);
|
|
||||||
}
|
|
||||||
if (ts_rf_event > -987654321 && ts_mcp_event > -987654321)
|
|
||||||
dt_rf_mcp_event = ts_rf_event - ts_mcp_event;
|
|
||||||
}
|
|
||||||
if (dataset == "17F" && reactiondata)
|
|
||||||
{
|
|
||||||
// misc.ch is a property of the event, not of any Si hit -- filled inside the
|
|
||||||
// per-QQQ and per-SX3 loops it was multiplied by the Si multiplicity.
|
|
||||||
for (int j = 0; j < misc.multi; j++)
|
|
||||||
{
|
|
||||||
if (QQQ_Events.size())
|
|
||||||
plotter->Fill1D("channels_misc_qqq", 20, -0.5, 19.5, misc.ch[j], "misc");
|
|
||||||
if (SX3_Events.size())
|
|
||||||
plotter->Fill1D("channels_misc_sx3", 20, -0.5, 19.5, misc.ch[j], "misc");
|
|
||||||
}
|
|
||||||
|
|
||||||
int ctr = 0;
|
if (pcEnergyCalibLoaded)
|
||||||
|
pcCalibratedHistograms(plotter, QQQ_Events, SX3_Events, PC_Events_calibrated);
|
||||||
|
|
||||||
|
a1c1CalibDiagnostic(plotter, PC_Events); // <-- new, unconditional
|
||||||
|
pcVertexByWireGeometry(plotter, QQQ_Events, SX3_Events, PC_Events); // <-- new, unconditional
|
||||||
|
|
||||||
|
// phi_win matches every other Si-PC match in this file: SX3 sits at a longer lever
|
||||||
|
// arm (rho ~88mm vs the PC anode at 37mm) than QQQ, so its true phi spread is wider
|
||||||
|
// -- pi/4 for both detectors under-counted real SX3-PC coincidences. Also gated on
|
||||||
|
// siPcCoincident(): this used to be the one Si-PC match in the file with a phi
|
||||||
|
// window but no time gate, so "withPC" included phi-aligned but time-accidental
|
||||||
|
// pairs.
|
||||||
|
auto hasPCCoincidence = [&](const Event &sievent, bool isQQQ)
|
||||||
|
{
|
||||||
|
double phi_win = isQQQ ? TMath::Pi() / 4.0 : TMath::Pi() / 3.0;
|
||||||
|
for (const auto &pcevent : PC_Events)
|
||||||
|
{
|
||||||
|
if (pcevent.multi1 < 1)
|
||||||
|
continue;
|
||||||
|
if (!siPcCoincident(sievent.Time1, pcevent.Time1))
|
||||||
|
continue;
|
||||||
|
if (TMath::Abs(sievent.pos.DeltaPhi(pcevent.pos)) <= phi_win)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
for (const auto &qqqevent : QQQ_Events)
|
for (const auto &qqqevent : QQQ_Events)
|
||||||
{
|
{
|
||||||
double ts_rf = -987654321;
|
plotter->Fill1D("siE_qqq_calibrated_all", 800, 0, 15, qqqevent.Energy1, "siE");
|
||||||
double ts_needle = -987654321;
|
bool coinc = hasPCCoincidence(qqqevent, true);
|
||||||
double ts_mcp = -987654321;
|
plotter->Fill1D(coinc ? "siE_qqq_calibrated_withPC" : "siE_qqq_calibrated_noPC", 800, 0, 15, qqqevent.Energy1, "siE");
|
||||||
// Time1 already carries the +/-8 clock dither applied when the QQQ Event was
|
|
||||||
// built (tRing), so re-dithering here widened this folder's timing by sqrt(2)
|
|
||||||
// relative to every other timing plot in the analysis.
|
|
||||||
double ts_qqq = static_cast<double>(qqqevent.Time1);
|
|
||||||
bool found_rf = false;
|
|
||||||
bool found_mcp = false;
|
|
||||||
bool found_needle = false;
|
|
||||||
bool qqq_inner_ring = (qqqevent.ch1 % 16) < 8;
|
|
||||||
for (int j = 0; j < misc.multi; j++)
|
|
||||||
{
|
|
||||||
if (misc.ch[j] == 2)
|
|
||||||
{ // Needle
|
|
||||||
plotter->Fill2D("needle_vs_qqqE", 800, 0, 16384, 800, 0, 10, misc.e[j], qqqevent.Energy1, "misc");
|
|
||||||
ts_needle = static_cast<double>(misc.t[j]) + static_cast<double>(misc.tf[j]);
|
|
||||||
found_needle = 1;
|
|
||||||
plotter->Fill1D("dt_qqq_needle", 800, -2000, 2000, ts_qqq - ts_needle, "misc");
|
|
||||||
}
|
|
||||||
if (misc.ch[j] == 3)
|
|
||||||
{ // RF
|
|
||||||
ts_rf = static_cast<double>(misc.t[j]) + static_cast<double>(misc.tf[j]);
|
|
||||||
found_rf = 1;
|
|
||||||
plotter->Fill1D("dt_qqq_rf_innerring" + std::to_string(qqq_inner_ring), 800, -2000, 2000, ts_qqq - ts_rf, "misc");
|
|
||||||
}
|
|
||||||
if (misc.ch[j] == 4)
|
|
||||||
{ // mcp
|
|
||||||
ts_mcp = static_cast<double>(misc.t[j]) + static_cast<double>(misc.tf[j]);
|
|
||||||
found_mcp = 1;
|
|
||||||
plotter->Fill1D("dt_qqq_mcp_innerring" + std::to_string(qqq_inner_ring), 800, -2000, 2000, ts_qqq - ts_mcp, "misc");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (found_rf && found_mcp)
|
|
||||||
{
|
|
||||||
if (ctr == 0)
|
|
||||||
plotter->Fill1D("dt_rf_mcp_qqq_innerring" + std::to_string(qqq_inner_ring), 500, -1000, 1000, ts_rf - ts_mcp, "misc");
|
|
||||||
double dt_rf_mcp = ts_rf - ts_mcp;
|
|
||||||
double dt_qqq_rf = ts_qqq - ts_rf;
|
|
||||||
double dt_qqq_mcp = ts_qqq - ts_mcp;
|
|
||||||
plotter->Fill2D("dt(qqq,rf)_vs_(rf,mcp)_innerring" + std::to_string(qqq_inner_ring), 800, -2000, 2000, 640, -2000, 2000, dt_qqq_rf, dt_rf_mcp, "misc");
|
|
||||||
plotter->Fill2D("dt_(qqq,mcp)_vs_(qqq,rf)_innerring" + std::to_string(qqq_inner_ring), 800, -1400, 2000, 640, -2000, 2000, dt_qqq_mcp, dt_qqq_rf, "misc");
|
|
||||||
plotter->Fill2D("dt_(qqq,mcp)_vs_(rf,mcp)_innerring" + std::to_string(qqq_inner_ring), 1000, -1400, 1000, 640, -2000, 2000, dt_qqq_mcp, dt_rf_mcp, "misc");
|
|
||||||
}
|
|
||||||
ctr += 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto &sx3event : SX3_Events)
|
for (const auto &sx3event : SX3_Events)
|
||||||
{
|
{
|
||||||
double ts_rf = -987654321;
|
plotter->Fill1D("siE_sx3_calibrated_all", 800, 0, 15, sx3event.Energy1, "siE");
|
||||||
double ts_needle = -987654321;
|
bool coinc = hasPCCoincidence(sx3event, false);
|
||||||
double ts_mcp = -987654321;
|
plotter->Fill1D(coinc ? "siE_sx3_calibrated_withPC" : "siE_sx3_calibrated_noPC", 800, 0, 15, sx3event.Energy1, "siE");
|
||||||
// as with ts_qqq: det.ts was already dithered when the SX3 Event was built
|
|
||||||
double ts_sx3 = static_cast<double>(sx3event.Time1);
|
|
||||||
bool found_rf = false;
|
|
||||||
bool found_mcp = false;
|
|
||||||
bool found_needle = false;
|
|
||||||
for (int j = 0; j < misc.multi; j++)
|
|
||||||
{
|
|
||||||
if (misc.ch[j] == 2)
|
|
||||||
{ // Needle
|
|
||||||
plotter->Fill2D("needle_vs_sx3E", 800, 0, 16384, 800, 0, 10, misc.e[j], sx3event.Energy1, "misc");
|
|
||||||
ts_needle = static_cast<double>(misc.t[j]) + static_cast<double>(misc.tf[j]);
|
|
||||||
found_needle = 1;
|
|
||||||
plotter->Fill1D("dt_sx3_needle", 800, -2000, 2000, ts_sx3 - ts_needle, "misc");
|
|
||||||
}
|
|
||||||
if (misc.ch[j] == 3)
|
|
||||||
{ // RF
|
|
||||||
ts_rf = static_cast<double>(misc.t[j]) + static_cast<double>(misc.tf[j]);
|
|
||||||
found_rf = 1;
|
|
||||||
plotter->Fill1D("dt_sx3_rf", 800, -2000, 2000, ts_sx3 - ts_rf, "misc");
|
|
||||||
}
|
|
||||||
if (misc.ch[j] == 4)
|
|
||||||
{ // mcp
|
|
||||||
ts_mcp = static_cast<double>(misc.t[j]) + static_cast<double>(misc.tf[j]);
|
|
||||||
found_mcp = 1;
|
|
||||||
plotter->Fill1D("dt_sx3_mcp", 800, -2000, 2000, ts_sx3 - ts_mcp, "misc");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (found_rf && found_mcp)
|
|
||||||
{
|
|
||||||
if (ctr == 0)
|
|
||||||
plotter->Fill1D("dt_rf_mcp_sx3", 500, -1000, 1000, ts_rf - ts_mcp, "misc");
|
|
||||||
double dt_rf_mcp = ts_rf - ts_mcp;
|
|
||||||
double dt_sx3_rf = ts_sx3 - ts_rf;
|
|
||||||
double dt_sx3_mcp = ts_sx3 - ts_mcp;
|
|
||||||
plotter->Fill2D("dt(sx3,rf)_vs_(rf,mcp)", 800, -2000, 2000, 640, -2000, 2000, dt_sx3_rf, dt_rf_mcp, "misc");
|
|
||||||
plotter->Fill2D("dt_(sx3,mcp)_vs_(sx3,rf)", 800, -1400, 2000, 640, -2000, 2000, dt_sx3_mcp, dt_sx3_rf, "misc");
|
|
||||||
plotter->Fill2D("dt_(sx3,mcp)_vs_(rf,mcp)", 1000, -1400, 1000, 640, -2000, 2000, dt_sx3_mcp, dt_rf_mcp, "misc");
|
|
||||||
}
|
|
||||||
ctr += 1;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (process_alpha_proton_scattering)
|
if (doMiscHistograms && ta_foil_run)
|
||||||
{
|
{
|
||||||
protonAlphaHistograms(plotter, QQQ_Events, SX3_Events, PC_Events);
|
// det, si_ecut, perp_cut, phi_win -- identical per-detector cuts to the
|
||||||
|
// m17Fax/m27Alax reaction_ax_core calls below, by design. a1c0/a2c0 (the
|
||||||
|
// former miscHistograms_oneWire) is folded in here now, gated on
|
||||||
|
// onewire_analysis internally.
|
||||||
|
protonAlphaElastic_core(plotter, QQQ_Events, PC_Events, aClusters, true, "QQQ", 0.4, 6.0, TMath::Pi() / 4.0, 6.88);
|
||||||
|
protonAlphaElastic_core(plotter, SX3_Events, PC_Events, aClusters, false, "SX3", 0.5, 10.0, TMath::Pi() / 3.0, 6.88);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (reactiondata)
|
||||||
|
{
|
||||||
|
if (dataset == "17F")
|
||||||
|
miscHistograms_17Fax(plotter, QQQ_Events, SX3_Events, PC_Events, aClusters, "", dt_rf_mcp_event, ts_rf_event, ts_mcp_event);
|
||||||
|
if (dataset == "27Al")
|
||||||
|
miscHistograms_27Alax(plotter, QQQ_Events, SX3_Events, PC_Events, aClusters);
|
||||||
|
}
|
||||||
// return kTRUE;
|
// return kTRUE;
|
||||||
} // end if(process_alpha_proton_scattering)
|
|
||||||
|
|
||||||
if (pcEnergyCalibLoaded)
|
if (doRawHistos)
|
||||||
pcCalibratedHistograms(plotter, QQQ_Events, SX3_Events, PC_Events_calibrated);
|
|
||||||
|
|
||||||
a1c1CalibDiagnostic(plotter, PC_Events); // <-- new, unconditional
|
|
||||||
pcVertexByWireGeometry(plotter, QQQ_Events, SX3_Events, PC_Events); // <-- new, unconditional
|
|
||||||
|
|
||||||
// phi_win matches every other Si-PC match in this file: SX3 sits at a longer lever
|
|
||||||
// arm (rho ~88mm vs the PC anode at 37mm) than QQQ, so its true phi spread is wider
|
|
||||||
// -- pi/4 for both detectors under-counted real SX3-PC coincidences. Also gated on
|
|
||||||
// siPcCoincident(): this used to be the one Si-PC match in the file with a phi
|
|
||||||
// window but no time gate, so "withPC" included phi-aligned but time-accidental
|
|
||||||
// pairs.
|
|
||||||
auto hasPCCoincidence = [&](const Event &sievent, bool isQQQ)
|
|
||||||
{
|
|
||||||
double phi_win = isQQQ ? TMath::Pi() / 4.0 : TMath::Pi() / 3.0;
|
|
||||||
for (const auto &pcevent : PC_Events)
|
|
||||||
{
|
{
|
||||||
if (pcevent.multi1 < 1)
|
if (QQQ_Events.size() && PC_Events.size())
|
||||||
continue;
|
plotter->Fill2D("PCEv_vs_QQQEv", 20, 0, 20, 20, 0, 20, QQQ_Events.size(), PC_Events.size());
|
||||||
if (!siPcCoincident(sievent.Time1, pcevent.Time1))
|
|
||||||
continue;
|
plotter->Fill2D("ac_vs_cc", 20, 0, 20, 20, 0, 20, aClusters.size(), cClusters.size(), "wiremult");
|
||||||
if (TMath::Abs(sievent.pos.DeltaPhi(pcevent.pos)) <= phi_win)
|
for (const auto &cluster : aClusters)
|
||||||
return true;
|
{
|
||||||
|
plotter->Fill1D("aClusters" + std::to_string(aClusters.size()), 20, -0.5, 19.5, cluster.size(), "wiremult");
|
||||||
|
}
|
||||||
|
for (const auto &cluster : cClusters)
|
||||||
|
{
|
||||||
|
plotter->Fill1D("cClusters" + std::to_string(cClusters.size()), 20, -0.5, 19.5, cluster.size(), "wiremult");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cClusters.size() && aClusters.size())
|
||||||
|
{
|
||||||
|
plotter->Fill2D("ac_vs_cc_ign0", 20, 0, 20, 20, 0, 20, aClusters.size(), cClusters.size(), "wiremult");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return false;
|
if (doPCSX3ClusterAnalysis)
|
||||||
};
|
|
||||||
for (const auto &qqqevent : QQQ_Events)
|
|
||||||
{
|
|
||||||
plotter->Fill1D("siE_qqq_calibrated_all", 800, 0, 15, qqqevent.Energy1, "siE");
|
|
||||||
bool coinc = hasPCCoincidence(qqqevent, true);
|
|
||||||
plotter->Fill1D(coinc ? "siE_qqq_calibrated_withPC" : "siE_qqq_calibrated_noPC", 800, 0, 15, qqqevent.Energy1, "siE");
|
|
||||||
}
|
|
||||||
for (const auto &sx3event : SX3_Events)
|
|
||||||
{
|
|
||||||
plotter->Fill1D("siE_sx3_calibrated_all", 800, 0, 15, sx3event.Energy1, "siE");
|
|
||||||
bool coinc = hasPCCoincidence(sx3event, false);
|
|
||||||
plotter->Fill1D(coinc ? "siE_sx3_calibrated_withPC" : "siE_sx3_calibrated_noPC", 800, 0, 15, sx3event.Energy1, "siE");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (doMiscHistograms && ta_foil_run)
|
|
||||||
{
|
|
||||||
// det, si_ecut, perp_cut, phi_win -- identical per-detector cuts to the
|
|
||||||
// m17Fax/m27Alax reaction_ax_core calls below, by design. a1c0/a2c0 (the
|
|
||||||
// former miscHistograms_oneWire) is folded in here now, gated on
|
|
||||||
// onewire_analysis internally.
|
|
||||||
protonAlphaElastic_core(plotter, QQQ_Events, PC_Events, aClusters, true, "QQQ", 0.4, 6.0, TMath::Pi() / 4.0, 6.88);
|
|
||||||
protonAlphaElastic_core(plotter, SX3_Events, PC_Events, aClusters, false, "SX3", 0.5, 10.0, TMath::Pi() / 3.0, 6.88);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (reactiondata)
|
|
||||||
{
|
|
||||||
if (dataset == "17F")
|
|
||||||
miscHistograms_17Fax(plotter, QQQ_Events, SX3_Events, PC_Events, aClusters, "", dt_rf_mcp_event, ts_rf_event, ts_mcp_event);
|
|
||||||
if (dataset == "27Al")
|
|
||||||
miscHistograms_27Alax(plotter, QQQ_Events, SX3_Events, PC_Events, aClusters);
|
|
||||||
}
|
|
||||||
// return kTRUE;
|
|
||||||
|
|
||||||
if (doRawHistos)
|
|
||||||
{
|
|
||||||
if (QQQ_Events.size() && PC_Events.size())
|
|
||||||
plotter->Fill2D("PCEv_vs_QQQEv", 20, 0, 20, 20, 0, 20, QQQ_Events.size(), PC_Events.size());
|
|
||||||
|
|
||||||
plotter->Fill2D("ac_vs_cc", 20, 0, 20, 20, 0, 20, aClusters.size(), cClusters.size(), "wiremult");
|
|
||||||
for (const auto &cluster : aClusters)
|
|
||||||
{
|
{
|
||||||
plotter->Fill1D("aClusters" + std::to_string(aClusters.size()), 20, -0.5, 19.5, cluster.size(), "wiremult");
|
PCSX3ClusterAnalysis(plotter, QQQ_Events, SX3_Events, PC_Events, aClusters, cClusters);
|
||||||
}
|
}
|
||||||
for (const auto &cluster : cClusters)
|
if (doPCQQQClusterAnalysis)
|
||||||
{
|
{
|
||||||
plotter->Fill1D("cClusters" + std::to_string(cClusters.size()), 20, -0.5, 19.5, cluster.size(), "wiremult");
|
PCQQQClusterAnalysis(plotter, QQQ_Events, SX3_Events, PC_Events, aClusters, cClusters);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cClusters.size() && aClusters.size())
|
if (doOldAnalysis)
|
||||||
{
|
OldAnalysis();
|
||||||
plotter->Fill2D("ac_vs_cc_ign0", 20, 0, 20, 20, 0, 20, aClusters.size(), cClusters.size(), "wiremult");
|
return kTRUE;
|
||||||
}
|
|
||||||
}
|
|
||||||
if (doPCSX3ClusterAnalysis)
|
|
||||||
{
|
|
||||||
PCSX3ClusterAnalysis(plotter, QQQ_Events, SX3_Events, PC_Events, aClusters, cClusters);
|
|
||||||
}
|
|
||||||
if (doPCQQQClusterAnalysis)
|
|
||||||
{
|
|
||||||
PCQQQClusterAnalysis(plotter, QQQ_Events, SX3_Events, PC_Events, aClusters, cClusters);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (doOldAnalysis)
|
|
||||||
OldAnalysis();
|
|
||||||
return kTRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TrackRecon::Terminate()
|
void TrackRecon::Terminate()
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user