modified: Calibration.C use both front and back gains
modified: GainMatchSX3.C changed structure a bit modified: GainMatchSX3Front.C removed some redundant code that I was trying out
This commit is contained in:
parent
ecd755e09c
commit
61473ca14e
|
@ -97,9 +97,9 @@ void Calibration::Begin(TTree * /*tree*/)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int id, bk, u, d;
|
int id, bk;
|
||||||
double gain;
|
double gain;
|
||||||
while (infile >> id >> bk >> u >> d >> gain)
|
while (infile >> id >> bk >> gain)
|
||||||
{
|
{
|
||||||
backGain[id][bk] = gain;
|
backGain[id][bk] = gain;
|
||||||
backGainValid[id][bk] = (gain > 0);
|
backGainValid[id][bk] = (gain > 0);
|
||||||
|
@ -253,30 +253,27 @@ Bool_t Calibration::Process(Long64_t entry)
|
||||||
int sx3ChUp = -1, sx3ChDn = -1, sx3ChBk = -1;
|
int sx3ChUp = -1, sx3ChDn = -1, sx3ChBk = -1;
|
||||||
float sx3EUp = 0.0f, sx3EDn = 0.0f, sx3EBk = 0.0f;
|
float sx3EUp = 0.0f, sx3EDn = 0.0f, sx3EBk = 0.0f;
|
||||||
|
|
||||||
for (auto &p : sx3ID)
|
for (size_t i = 0; i < sx3ID.size(); i++)
|
||||||
{
|
{
|
||||||
int index = p.second;
|
int index = sx3ID[i].second;
|
||||||
int ch = sx3.ch[index];
|
|
||||||
float e = sx3.e[index];
|
|
||||||
|
|
||||||
if (ch < 8)
|
if (sx3.ch[index] < 8)
|
||||||
{
|
{
|
||||||
if ((ch % 2) == 0) // even -> down
|
if ((sx3.ch[index] % 2) == 0) // even -> down
|
||||||
{
|
{
|
||||||
sx3ChDn = ch;
|
sx3ChDn = sx3.ch[index];
|
||||||
sx3EDn = e;
|
sx3EDn = sx3.e[index];
|
||||||
}
|
}
|
||||||
else // odd -> up
|
else // odd -> up
|
||||||
{
|
{
|
||||||
sx3ChUp = ch;
|
sx3ChUp = sx3.ch[index];
|
||||||
sx3EUp = e;
|
sx3EUp = sx3.e[index];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sx3ChBk = ch;
|
sx3ChBk = sx3.ch[index];
|
||||||
sx3EBk = e;
|
sx3EBk = sx3.e[index];
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool haveFrontPair = (sx3ChUp >= 0 || sx3ChDn >= 0);
|
bool haveFrontPair = (sx3ChUp >= 0 || sx3ChDn >= 0);
|
||||||
|
@ -288,40 +285,41 @@ Bool_t Calibration::Process(Long64_t entry)
|
||||||
// --- ALWAYS fill raw ADC for diagnostics
|
// --- ALWAYS fill raw ADC for diagnostics
|
||||||
// (temporarily use the existing spectrum to confirm fills)
|
// (temporarily use the existing spectrum to confirm fills)
|
||||||
// If you don't want raw values mixed with calibrated later, create a separate _raw array.
|
// If you don't want raw values mixed with calibrated later, create a separate _raw array.
|
||||||
hSX3Spectra[sx3ID[0].first][sx3ChBk][sx3ChUp][sx3ChDn]->Fill(sx3EUp);
|
hSX3Spectra[sx3ID[i].first][sx3ChBk][sx3ChUp][sx3ChDn]->Fill(sx3EUp);
|
||||||
|
|
||||||
// --- If gain is available, also fill calibrated energy
|
// --- If gain is available, also fill calibrated energy
|
||||||
if (frontGainValid[sx3ID[0].first][sx3ChBk][sx3ChUp][sx3ChDn])
|
if (frontGainValid[sx3ID[i].first][sx3ChBk][sx3ChUp][sx3ChDn])
|
||||||
{
|
{
|
||||||
GM_EUp = frontGain[sx3ID[0].first][sx3ChBk][sx3ChUp][sx3ChDn] * sx3EUp;
|
GM_EUp = frontGain[sx3ID[i].first][sx3ChBk][sx3ChUp][sx3ChDn] * sx3EUp;
|
||||||
if (GM_EUp > 50.0)
|
if (GM_EUp > 50.0)
|
||||||
hSX3Spectra[sx3ID[0].first][sx3ChBk][sx3ChUp][sx3ChDn]->Fill(GM_EUp); // optional: mixes raw+calib
|
hSX3Spectra[sx3ID[i].first][sx3ChBk][sx3ChUp][sx3ChDn]->Fill(GM_EUp); // optional: mixes raw+calib
|
||||||
}
|
}
|
||||||
// --- If back gain is available, also fill calibrated energy
|
// --- If back gain is available, also fill calibrated energy
|
||||||
hsx3E_raw->Fill(sx3EBk);
|
hsx3E_raw->Fill(sx3EBk);
|
||||||
|
|
||||||
if (backGainValid[sx3ID[0].first][sx3ChBk])
|
if (backGainValid[sx3ID[i].first][sx3ChBk])
|
||||||
{
|
{
|
||||||
calibEBack = backGain[sx3ID[0].first][sx3ChBk] * sx3EBk;
|
calibEBack = backGain[sx3ID[i].first][sx3ChBk] * sx3EBk;
|
||||||
if (calibEBack > 50.0)
|
if (calibEBack > 50.0)
|
||||||
hsx3E_calib->Fill(calibEBack); // optional: mixes raw+calib
|
hsx3E_calib->Fill(calibEBack); // optional: mixes raw+calib
|
||||||
}
|
}
|
||||||
|
|
||||||
// Keep the other diagnostic plots
|
// Keep the other diagnostic plots
|
||||||
hsx3IndexVE_gm->Fill(sx3.index[sx3ID[0].second], GM_EUp);
|
hsx3IndexVE_gm->Fill(sx3.index[sx3ID[i].second], GM_EUp);
|
||||||
hSX3->Fill(sx3ChDn + 4, sx3ChBk);
|
hSX3->Fill(sx3ChDn + 4, sx3ChBk);
|
||||||
hSX3->Fill(sx3ChUp, sx3ChBk);
|
hSX3->Fill(sx3ChUp, sx3ChBk);
|
||||||
hSX3FvsB->Fill(sx3EUp + sx3EDn, sx3EBk);
|
hSX3FvsB->Fill(sx3EUp + sx3EDn, sx3EBk);
|
||||||
|
|
||||||
if (GM_EUp > 50.0 && sx3EBk > 50.0)
|
if (GM_EUp > 50.0 && sx3EBk > 50.0)
|
||||||
{
|
{
|
||||||
sx3_contr.CalSX3Pos(sx3ID[0].first, sx3ChUp, sx3ChDn, sx3ChBk, GM_EUp, sx3EDn);
|
sx3_contr.CalSX3Pos(sx3ID[i].first, sx3ChUp, sx3ChDn, sx3ChBk, GM_EUp, sx3EDn);
|
||||||
hitPos = sx3_contr.GetHitPos();
|
hitPos = sx3_contr.GetHitPos();
|
||||||
HitNonZero = true;
|
HitNonZero = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ======================= QQQ =======================
|
// ======================= QQQ =======================
|
||||||
for (int i = 0; i < qqq.multi; i++)
|
for (int i = 0; i < qqq.multi; i++)
|
||||||
|
|
|
@ -283,7 +283,7 @@ void GainMatchSX3::Terminate()
|
||||||
continue; // not enough statistics
|
continue; // not enough statistics
|
||||||
|
|
||||||
// Build graph with errors
|
// Build graph with errors
|
||||||
const double fixedError = 10.0; // ADC channels
|
const double fixedError = 0.0; // ADC channels
|
||||||
std::vector<double> exVals(udE.size(), 0.0); // no x error
|
std::vector<double> exVals(udE.size(), 0.0); // no x error
|
||||||
std::vector<double> eyVals(udE.size(), fixedError); // constant y error
|
std::vector<double> eyVals(udE.size(), fixedError); // constant y error
|
||||||
|
|
||||||
|
@ -291,7 +291,7 @@ void GainMatchSX3::Terminate()
|
||||||
exVals.data(), eyVals.data());
|
exVals.data(), eyVals.data());
|
||||||
|
|
||||||
TF1 f("f", "[0]*x", 0, 16000);
|
TF1 f("f", "[0]*x", 0, 16000);
|
||||||
f.SetParameter(0, 1.0); // initial slope
|
// f.SetParameter(0, 1.0); // initial slope
|
||||||
|
|
||||||
if (drawCanvases)
|
if (drawCanvases)
|
||||||
{
|
{
|
||||||
|
@ -329,7 +329,7 @@ void GainMatchSX3::Terminate()
|
||||||
g.Fit(&f, "QNR");
|
g.Fit(&f, "QNR");
|
||||||
}
|
}
|
||||||
|
|
||||||
double slope = f.GetParameter(0);
|
double slope = 1/f.GetParameter(0);
|
||||||
if (std::abs(slope - 1.0) < 0.3) // sanity check
|
if (std::abs(slope - 1.0) < 0.3) // sanity check
|
||||||
{
|
{
|
||||||
backSlope[id][bk] = slope;
|
backSlope[id][bk] = slope;
|
||||||
|
|
|
@ -44,17 +44,15 @@ bool frontGainValid[MAX_DET][MAX_BK][MAX_UP][MAX_DOWN] = {{{{false}}}};
|
||||||
double uvdslope[MAX_DET][MAX_BK][MAX_UP][MAX_DOWN] = {{{{0}}}};
|
double uvdslope[MAX_DET][MAX_BK][MAX_UP][MAX_DOWN] = {{{{0}}}};
|
||||||
// ==== Configuration Flags ====
|
// ==== Configuration Flags ====
|
||||||
const bool interactiveMode = false; // If true: show canvas + wait for user
|
const bool interactiveMode = false; // If true: show canvas + wait for user
|
||||||
const bool interactiveMode1 = false; // If true: show canvas + wait for user
|
|
||||||
const bool verboseFit = true; // If true: print fit summary and chi²
|
const bool verboseFit = true; // If true: print fit summary and chi²
|
||||||
const bool drawCanvases = false; // If false: canvases won't be drawn at all
|
const bool drawCanvases = false; // If false: canvases won't be drawn at all
|
||||||
const bool drawCanvases1 = false; // If false: canvases won't be drawn at all
|
|
||||||
|
|
||||||
void GainMatchSX3Front::Begin(TTree * /*tree*/)
|
void GainMatchSX3Front::Begin(TTree * /*tree*/)
|
||||||
{
|
{
|
||||||
TString option = GetOption();
|
TString option = GetOption();
|
||||||
|
|
||||||
hSX3FvsB = new TH2F("hSX3FvsB", "SX3 Front vs Back; Front E; Back E", 400, 0, 16000, 400, 0, 16000);
|
hSX3FvsB = new TH2F("hSX3FvsB", "SX3 Front vs Back; Front E; Back E", 800, 0, 16000, 800, 0, 16000);
|
||||||
hSX3FvsB_g = new TH2F("hSX3FvsB_g", "SX3 Front vs Back; Front E; Back E", 400, 0, 16000, 400, 0, 16000);
|
hSX3FvsB_g = new TH2F("hSX3FvsB_g", "SX3 Front vs Back; Front E; Back E", 800, 0, 16000, 800, 0, 16000);
|
||||||
hsx3IndexVE = new TH2F("hsx3IndexVE", "SX3 index vs Energy; sx3 index ; Energy", 24 * 12, 0, 24 * 12, 400, 0, 5000);
|
hsx3IndexVE = new TH2F("hsx3IndexVE", "SX3 index vs Energy; sx3 index ; Energy", 24 * 12, 0, 24 * 12, 400, 0, 5000);
|
||||||
hsx3IndexVE_g = new TH2F("hsx3IndexVE_g", "SX3 index vs Energy; sx3 index ; Energy", 24 * 12, 0, 24 * 12, 400, 0, 5000);
|
hsx3IndexVE_g = new TH2F("hsx3IndexVE_g", "SX3 index vs Energy; sx3 index ; Energy", 24 * 12, 0, 24 * 12, 400, 0, 5000);
|
||||||
hSX3 = new TH2F("hSX3", "SX3 Front v Back; Fronts; Backs", 8, 0, 8, 4, 0, 4);
|
hSX3 = new TH2F("hSX3", "SX3 Front v Back; Fronts; Backs", 8, 0, 8, 4, 0, 4);
|
||||||
|
@ -84,27 +82,6 @@ void GainMatchSX3Front::Begin(TTree * /*tree*/)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
cut1->SetName("UvD");
|
cut1->SetName("UvD");
|
||||||
// std::string filename = "sx3_GainMatchback.txt";
|
|
||||||
|
|
||||||
// std::ifstream infile(filename);
|
|
||||||
// if (!infile.is_open())
|
|
||||||
// {
|
|
||||||
// std::cerr << "Error opening " << filename << "!" << std::endl;
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// int id, bk, u, d;
|
|
||||||
// double gain;
|
|
||||||
// while (infile >> id >> bk >> u >> d >> gain)
|
|
||||||
// {
|
|
||||||
// backGain[id][bk][u][d] = gain;
|
|
||||||
// if (backGain[id][bk][u][d] > 0)
|
|
||||||
// backGainValid[id][bk][u][d] = true;
|
|
||||||
// else
|
|
||||||
// backGainValid[id][bk][u][d] = false;
|
|
||||||
// }
|
|
||||||
// infile.close();
|
|
||||||
// std::cout << "Loaded back gains from " << filename << std::endl;
|
|
||||||
|
|
||||||
std::string filename = "sx3_BackGains.txt";
|
std::string filename = "sx3_BackGains.txt";
|
||||||
|
|
||||||
|
@ -115,7 +92,7 @@ void GainMatchSX3Front::Begin(TTree * /*tree*/)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int id, bk, u, d;
|
int id, bk;
|
||||||
double gain;
|
double gain;
|
||||||
while (infile >> id >> bk >> gain)
|
while (infile >> id >> bk >> gain)
|
||||||
{
|
{
|
||||||
|
@ -254,10 +231,10 @@ Bool_t GainMatchSX3Front::Process(Long64_t entry)
|
||||||
if (cut && cut->IsInside(sx3EUp + sx3EDn, sx3EBk) && cut1 && cut1->IsInside(sx3EUp / sx3EBk, sx3EDn / sx3EBk))
|
if (cut && cut->IsInside(sx3EUp + sx3EDn, sx3EBk) && cut1 && cut1->IsInside(sx3EUp / sx3EBk, sx3EDn / sx3EBk))
|
||||||
{
|
{
|
||||||
|
|
||||||
// if (backGainValid[sx3.id[i]][sx3ChBk])
|
if (backGainValid[sx3.id[i]][sx3ChBk])
|
||||||
// {
|
{
|
||||||
// sx3EBk *= backGain[sx3.id[i]][sx3ChBk];
|
sx3EBk *= backGain[sx3.id[i]][sx3ChBk];
|
||||||
// }
|
}
|
||||||
// Accumulate data for gain matching
|
// Accumulate data for gain matching
|
||||||
dataPoints[{sx3.id[i], sx3ChBk, sx3ChUp, sx3ChDn}].emplace_back(sx3EBk, sx3EUp, sx3EDn);
|
dataPoints[{sx3.id[i], sx3ChBk, sx3ChUp, sx3ChDn}].emplace_back(sx3EBk, sx3EUp, sx3EDn);
|
||||||
}
|
}
|
||||||
|
@ -290,7 +267,7 @@ void GainMatchSX3Front::Terminate()
|
||||||
auto [id, bk, u, d] = kv.first;
|
auto [id, bk, u, d] = kv.first;
|
||||||
const auto &pts = kv.second;
|
const auto &pts = kv.second;
|
||||||
|
|
||||||
if (pts.size() < 500)
|
if (pts.size() < 50)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
std::vector<double> uE, dE, udE, corrBkE;
|
std::vector<double> uE, dE, udE, corrBkE;
|
||||||
|
@ -322,20 +299,20 @@ void GainMatchSX3Front::Terminate()
|
||||||
// Build data with fixed error
|
// Build data with fixed error
|
||||||
for (size_t i = 0; i < udE.size(); ++i)
|
for (size_t i = 0; i < udE.size(); ++i)
|
||||||
{
|
{
|
||||||
double x = udE[i]; // front energy
|
double x = uE[i]; // front energy
|
||||||
double y = corrBkE[i]; // back energy
|
double y = dE[i]; // back energy
|
||||||
|
|
||||||
xVals.push_back(x);
|
xVals.push_back(x);
|
||||||
yVals.push_back(y);
|
yVals.push_back(y);
|
||||||
// exVals.push_back(fixedError); // error in front energy
|
exVals.push_back(fixedError); // error in up energy
|
||||||
eyVals.push_back(fixedError); // error in back energy
|
// eyVals.push_back(fixedError); // error in down energy
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build TGraphErrors with errors
|
// Build TGraphErrors with errors
|
||||||
TGraphErrors g(xVals.size(), xVals.data(), yVals.data(), exVals.data(), eyVals.data());
|
TGraphErrors g(xVals.size(), xVals.data(), yVals.data(), exVals.data(), eyVals.data());
|
||||||
|
|
||||||
TF1 f("f", "[0]*x", 0, 16000);
|
TF1 f("f", "[0]*x", 0, 16000);
|
||||||
f.SetParameter(0, 1.0); // Initial guess
|
f.SetParameter(0, -1.0); // Initial guess
|
||||||
|
|
||||||
if (drawCanvases)
|
if (drawCanvases)
|
||||||
{
|
{
|
||||||
|
@ -353,9 +330,9 @@ void GainMatchSX3Front::Terminate()
|
||||||
int ndf = f.GetNDF();
|
int ndf = f.GetNDF();
|
||||||
double reducedChi2 = (ndf != 0) ? chi2 / ndf : -1;
|
double reducedChi2 = (ndf != 0) ? chi2 / ndf : -1;
|
||||||
|
|
||||||
// std::cout << Form("Det%d U%d D%d B%d → Gain: %.4f | χ²/ndf = %.2f/%d = %.2f",
|
std::cout << Form("Det%d U%d D%d B%d → Gain: %.4f | χ²/ndf = %.2f/%d = %.2f",
|
||||||
// id, u, d, bk, f.GetParameter(0), chi2, ndf, reducedChi2)
|
id, u, d, bk, f.GetParameter(0), chi2, ndf, reducedChi2)
|
||||||
// << std::endl;
|
<< std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (interactiveMode)
|
if (interactiveMode)
|
||||||
|
@ -380,87 +357,6 @@ void GainMatchSX3Front::Terminate()
|
||||||
// printf("Front gain Det%d Back%d Up%dDn%d → %.4f\n", id, bk, u, d, frontGain[id][bk][u][d]);
|
// printf("Front gain Det%d Back%d Up%dDn%d → %.4f\n", id, bk, u, d, frontGain[id][bk][u][d]);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto &kv : dataPoints)
|
|
||||||
{
|
|
||||||
auto [id, bk, u, d] = kv.first;
|
|
||||||
const auto &pts = kv.second;
|
|
||||||
std::vector<double> uvals, dvals;
|
|
||||||
double front = frontGain[id][bk][u][d];
|
|
||||||
|
|
||||||
if (pts.size() < 5)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
std::vector<double> uE, dE, udE, corrBkE;
|
|
||||||
|
|
||||||
for (const auto &pr : pts)
|
|
||||||
{
|
|
||||||
double eBkCorr, eUp, eDn;
|
|
||||||
std::tie(eBkCorr, eUp, eDn) = pr;
|
|
||||||
if ((eBkCorr < 100) || (eUp < 100) || (eDn < 100))
|
|
||||||
continue; // Skip if any energy is zero
|
|
||||||
eUp *= front;
|
|
||||||
// eDn *= frontGain[id][bk][u][d];
|
|
||||||
|
|
||||||
uE.push_back(eUp / eBkCorr);
|
|
||||||
dE.push_back(eDn / eBkCorr);
|
|
||||||
corrBkE.push_back(eBkCorr);
|
|
||||||
}
|
|
||||||
for (size_t i = 0; i < uE.size(); ++i)
|
|
||||||
{
|
|
||||||
uvals.push_back(uE[i]);
|
|
||||||
dvals.push_back(dE[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
TGraph g1(uvals.size(), uvals.data(), dvals.data());
|
|
||||||
g1.SetMarkerStyle(20);
|
|
||||||
g1.SetMarkerColor(kBlue);
|
|
||||||
g1.SetTitle(Form("Det %d: U%d D%d B%d", id, u, d, bk));
|
|
||||||
|
|
||||||
// Fit function (straight line through origin)
|
|
||||||
TF1 f1("f1", "[0]*x+[1]", 0, 16000);
|
|
||||||
f1.SetParameter(0, -1.0);
|
|
||||||
|
|
||||||
if (drawCanvases1)
|
|
||||||
{
|
|
||||||
TCanvas *c1 = new TCanvas(Form("c_%d_%d_%d_%d", id, bk, u, d), "Fit", 800, 600);
|
|
||||||
g1.SetTitle(Form("Detector %d: U%d D%d B%d", id, u, d, bk));
|
|
||||||
g1.SetMarkerStyle(20);
|
|
||||||
g1.SetMarkerColor(kBlue);
|
|
||||||
g1.Draw("AP");
|
|
||||||
|
|
||||||
g1.Fit(&f1, interactiveMode1 ? "Q" : "QNR"); // 'R' avoids refit, 'N' skips drawing
|
|
||||||
|
|
||||||
if (verboseFit)
|
|
||||||
{
|
|
||||||
double chi2 = f1.GetChisquare();
|
|
||||||
int ndf1 = f1.GetNDF();
|
|
||||||
double reducedChi2 = (ndf1 != 0) ? chi2 / ndf1 : -1;
|
|
||||||
|
|
||||||
std::cout << Form("Det%d U%d D%d B%d → Gain: %.4f | χ²/ndf = %.2f/%d = %.2f",
|
|
||||||
id, u, d, bk, f1.GetParameter(0), chi2, ndf1, reducedChi2)
|
|
||||||
<< std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (interactiveMode1)
|
|
||||||
{
|
|
||||||
c1->Update();
|
|
||||||
gPad->WaitPrimitive();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
c1->Close(); // Optionally avoid clutter in batch
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
g1.Fit(&f1, "QNR");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Save slope
|
|
||||||
uvdslope[id][bk][u][d] = f1.GetParameter(0);
|
|
||||||
printf("UvD slope Det%d Back%d Up%dDn%d → %.4f\n", id, bk, u, d, uvdslope[id][bk][u][d]);
|
|
||||||
}
|
|
||||||
|
|
||||||
outFile.close();
|
outFile.close();
|
||||||
std::cout << "Gain matching complete." << std::endl;
|
std::cout << "Gain matching complete." << std::endl;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user