30 int nBins_sin2th23 = 100;
31 int nBins_sin2th13 = 100;
32 int nBins_sin2th12 = 100;
33 int nBins_delm23 = 3000;
34 int nBins_delm12 = 100;
37 double sin2th23_min = 0.45;
38 double sin2th23_max = 0.57;
39 double sin2th13_min = 0.015;
40 double sin2th13_max = 0.03;
41 double sin2th12_min = 0.24;
42 double sin2th12_max = 0.36;
43 double delm23_no_min = 0.00245;
44 double delm23_no_max = 0.0026;
45 double delm23_io_min = -delm23_no_max;
46 double delm23_io_max = -delm23_no_min;
47 double delm12_min = 6.5e-5;
48 double delm12_max = 8.5e-5;
50 auto normalizeHist = [&](TH1 *h) {
52 double integral = h->Integral();
53 if (integral > 0.0) h->Scale(1.0 / integral);
56 auto printHistStats = [&](
const std::string &label, TH1 *h) {
58 std::cout <<
"[DEBUG] " << label <<
" : histogram is null" << std::endl;
61 std::cout << std::fixed << std::setprecision(6)
62 <<
"[DEBUG] " << label
63 <<
" entries=" << h->GetEntries()
64 <<
" effEntries=" << h->GetEffectiveEntries()
65 <<
" integral=" << h->Integral()
66 <<
" mean=" << h->GetMean()
67 <<
" rms=" << h->GetRMS()
79 bool use_reference_chain =
false;
80 bool use_reference_LLH_scan =
true;
82 double asimovSin2th12 = std::numeric_limits<double>::quiet_NaN();
83 double asimovSin2th23 = std::numeric_limits<double>::quiet_NaN();
84 double asimovSin2th13 = std::numeric_limits<double>::quiet_NaN();
85 double asimovDelm12 = std::numeric_limits<double>::quiet_NaN();
86 double asimovDelm23 = std::numeric_limits<double>::quiet_NaN();
87 double asimovDcp = std::numeric_limits<double>::quiet_NaN();
88 double asimovBaseline = std::numeric_limits<double>::quiet_NaN();
89 double asimovElectronDensity = std::numeric_limits<double>::quiet_NaN();
92 std::string referenceFile =
"";
93 std::string referenceTreeName =
"";
95 if(use_reference_chain) {
96 referenceFile =
"/home/driley/projects/def-blairt2k/driley/T2K_outputs/umbrella_testing/fixing_params/allfixed/all_oscParams_fixed_hadded.root";
97 referenceTreeName =
"posteriors";
101 std::string referenceLLHScanFile =
"";
102 std::string referenceLLHScanDcpHistName =
"";
103 std::string referenceLLHScanDcp_NO_histName =
"";
104 std::string referenceLLHScanDcp_IO_histName =
"";
106 if(use_reference_LLH_scan) {
107 referenceLLHScanFile =
"/home/driley/Projects-T2K-MaCh3/umbrella_t2k/mcm_utils/target_1D_histos.root";
108 referenceLLHScanDcpHistName =
"dcp";
109 referenceLLHScanDcp_NO_histName =
"dcp_NO";
110 referenceLLHScanDcp_IO_histName =
"dcp_IO";
114 if (!f || f->IsZombie()) {
115 std::cerr <<
"Error: Cannot open file!" << std::endl;
120 TTree *tree = (TTree*)f->Get(
"posteriors");
122 std::cerr <<
"Error: Cannot find tree!" << std::endl;
128 bool isAsimovChain =
false;
130 auto calculateJarlskog = [&](
double sin2th12,
double sin2th23,
double sin2th13,
double dcp) {
131 if (!std::isfinite(sin2th12) || !std::isfinite(sin2th23) || !std::isfinite(sin2th13) || !std::isfinite(dcp)) {
132 return std::numeric_limits<double>::quiet_NaN();
134 return std::sqrt(std::max(0.0, sin2th12) * std::max(0.0, 1.0 - sin2th12) *
135 std::max(0.0, sin2th23) * std::max(0.0, 1.0 - sin2th23)) *
136 std::max(0.0, 1.0 - sin2th13) * std::sqrt(std::max(0.0, sin2th13)) *
140 const double asimovJarlskog = calculateJarlskog(asimovSin2th12, asimovSin2th23, asimovSin2th13, asimovDcp);
142 auto drawAsimovLineWithLegend = [&](
double xValue, TLegend *existingLegend =
nullptr) {
143 if (!isAsimovChain || !std::isfinite(xValue) || !gPad)
return;
145 const double yMin = gPad->GetUymin();
146 const double yMax = gPad->GetUymax();
147 TLine *asimovLine =
new TLine(xValue, yMin, xValue, yMax);
148 asimovLine->SetLineColor(kBlack);
149 asimovLine->SetLineStyle(3);
150 asimovLine->SetLineWidth(2);
151 asimovLine->Draw(
"SAME");
153 if (existingLegend) {
154 existingLegend->AddEntry(asimovLine,
"Asimov point",
"l");
155 existingLegend->Draw();
157 TLegend *asimovLegend =
new TLegend(0.14, 0.83, 0.34, 0.91);
158 asimovLegend->SetBorderSize(0);
159 asimovLegend->SetFillStyle(0);
160 asimovLegend->AddEntry(asimovLine,
"Asimov point",
"l");
161 asimovLegend->Draw();
165 auto drawAsimovMarkerWithLegend = [&](
double xValue,
double yValue, TLegend *existingLegend =
nullptr) {
166 if (!isAsimovChain || !std::isfinite(xValue) || !std::isfinite(yValue) || !gPad)
return;
169 const double xMin = gPad->GetUxmin();
170 const double xMax = gPad->GetUxmax();
171 const double yMin = gPad->GetUymin();
172 const double yMax = gPad->GetUymax();
173 const double dx = 0.012 * (xMax - xMin);
174 const double dy = 0.012 * (yMax - yMin);
176 TLine *l1 =
new TLine(xValue - dx, yValue - dy, xValue + dx, yValue + dy);
177 l1->SetLineColor(kRed);
181 TLine *l2 =
new TLine(xValue - dx, yValue + dy, xValue + dx, yValue - dy);
182 l2->SetLineColor(kRed);
186 if (existingLegend) {
187 existingLegend->AddEntry(l1,
"Asimov point",
"l");
188 existingLegend->Draw();
190 TLegend *lm =
new TLegend(0.14, 0.83, 0.34, 0.91);
191 lm->SetBorderSize(0);
193 lm->AddEntry(l1,
"Asimov point",
"l");
200 bool hasReferenceDcp =
false;
201 bool hasReferenceSin2Th23 =
false;
202 bool hasReferenceDelm23 =
false;
203 TH1D *hRefDcpShape =
nullptr;
204 TH1D *hRefSin2Th23Shape =
nullptr;
205 TH1D *hRefDelm23Shape =
nullptr;
207 if (!fRef || fRef->IsZombie()) {
208 std::cerr <<
"Warning: Cannot open reference file: " << referenceFile << std::endl;
210 TTree *refTree = (TTree*)fRef->Get(referenceTreeName.c_str());
212 std::cerr <<
"Warning: Cannot find reference tree: " << referenceTreeName << std::endl;
213 }
else if (!refTree->GetBranch(
"dcp") && !refTree->GetBranch(
"delta_cp")) {
214 std::cerr <<
"Warning: dcp branch not found in reference tree." << std::endl;
215 }
else if (refTree->GetBranch(
"delta_cp")) {
216 hRefDcpShape =
new TH1D(
"hRefDcpShape",
"", nBins_dcp, -3.1415, 3.1415);
217 refTree->Draw(
"delta_cp>>hRefDcpShape",
"",
"goff");
218 hRefDcpShape->SetDirectory(0);
219 hasReferenceDcp =
true;
220 std::cout <<
"Loaded reference dcp histogram from " << referenceTreeName << std::endl;
222 hRefDcpShape =
new TH1D(
"hRefDcpShape",
"", nBins_dcp, -3.1415, 3.1415);
223 refTree->Draw(
"dcp>>hRefDcpShape",
"",
"goff");
224 hRefDcpShape->SetDirectory(0);
225 hasReferenceDcp =
true;
226 std::cout <<
"Loaded reference dcp histogram from " << referenceTreeName << std::endl;
229 if (!refTree->GetBranch(
"theta23") && !refTree->GetBranch(
"sin2th_23")) {
230 std::cerr <<
"Warning: theta23 branch not found in reference tree." << std::endl;
231 }
else if (refTree->GetBranch(
"sin2th_23")) {
232 hRefSin2Th23Shape =
new TH1D(
"hRefSin2Th23Shape",
"", nBins_sin2th23, sin2th23_min, sin2th23_max);
233 refTree->Draw(
"sin2th_23>>hRefSin2Th23Shape",
"",
"goff");
234 hRefSin2Th23Shape->SetDirectory(0);
235 hasReferenceSin2Th23 =
true;
236 std::cout <<
"Loaded reference sin^{2}(theta23) histogram from " << referenceTreeName << std::endl;
239 hRefSin2Th23Shape =
new TH1D(
"hRefSin2Th23Shape",
"", nBins_sin2th23, sin2th23_min, sin2th23_max);
240 refTree->Draw(
"theta23>>hRefSin2Th23Shape",
"",
"goff");
241 hRefSin2Th23Shape->SetDirectory(0);
242 hasReferenceSin2Th23 =
true;
243 std::cout <<
"Loaded reference sin^{2}(theta23) histogram from " << referenceTreeName << std::endl;
246 if (!refTree->GetBranch(
"dm23") && !refTree->GetBranch(
"delm2_23")) {
247 std::cerr <<
"Warning: dm23 branch not found in reference tree." << std::endl;
248 }
else if (refTree->GetBranch(
"delm2_23")) {
249 hRefDelm23Shape =
new TH1D(
"hRefDelm23Shape",
"", nBins_delm23, delm23_io_min, delm23_no_max);
250 refTree->Draw(
"delm2_23>>hRefDelm23Shape",
"",
"goff");
251 TH1D *hRefDelm23IO_dbg =
new TH1D(
"hRefDelm23IO_dbg",
"", nBins_delm23, delm23_io_min, delm23_io_max);
252 TH1D *hRefDelm23NO_dbg =
new TH1D(
"hRefDelm23NO_dbg",
"", nBins_delm23, delm23_no_min, delm23_no_max);
253 refTree->Draw(
"delm2_23>>hRefDelm23IO_dbg",
"delm2_23 < 0",
"goff");
254 refTree->Draw(
"delm2_23>>hRefDelm23NO_dbg",
"delm2_23 > 0",
"goff");
255 printHistStats(
"Reference delm23 IO (raw)", hRefDelm23IO_dbg);
256 printHistStats(
"Reference delm23 NO (raw)", hRefDelm23NO_dbg);
257 hRefDelm23Shape->SetDirectory(0);
258 normalizeHist(hRefDelm23Shape);
259 hasReferenceDelm23 =
true;
260 std::cout <<
"Loaded reference delm23 histogram from " << referenceTreeName << std::endl;
263 hRefDelm23Shape =
new TH1D(
"hRefDelm23Shape",
"", nBins_delm23, delm23_io_min, delm23_no_max);
264 refTree->Draw(
"dm23>>hRefDelm23Shape",
"",
"goff");
265 TH1D *hRefDm23IO_dbg =
new TH1D(
"hRefDm23IO_dbg",
"", nBins_delm23, delm23_io_min, delm23_io_max);
266 TH1D *hRefDm23NO_dbg =
new TH1D(
"hRefDm23NO_dbg",
"", nBins_delm23, delm23_no_min, delm23_no_max);
267 refTree->Draw(
"dm23>>hRefDm23IO_dbg",
"dm23 < 0",
"goff");
268 refTree->Draw(
"dm23>>hRefDm23NO_dbg",
"dm23 > 0",
"goff");
269 printHistStats(
"Reference dm23 IO (raw)", hRefDm23IO_dbg);
270 printHistStats(
"Reference dm23 NO (raw)", hRefDm23NO_dbg);
271 hRefDelm23Shape->SetDirectory(0);
272 normalizeHist(hRefDelm23Shape);
273 hasReferenceDelm23 =
true;
274 std::cout <<
"Loaded reference dm23 histograms from " << referenceTreeName << std::endl;
282 bool hasReferenceLLH_Dcp =
false;
283 bool hasReferenceLLH_Dcp_NO =
false;
284 bool hasReferenceLLH_Dcp_IO =
false;
285 TH1D *hRefLLH_Dcp =
nullptr;
286 TH1D *hRefLLH_Dcp_NO =
nullptr;
287 TH1D *hRefLLH_Dcp_IO =
nullptr;
289 if (use_reference_LLH_scan && !referenceLLHScanFile.empty()) {
290 TFile *fLLH =
TFile::Open(referenceLLHScanFile.c_str());
291 if (!fLLH || fLLH->IsZombie()) {
292 std::cerr <<
"Warning: Cannot open reference LLH-scan file: " << referenceLLHScanFile << std::endl;
295 auto loadAndNormalize1D = [&](
const std::string &name, TH1D *&outHist,
bool &outFlag) {
296 TObject *obj = fLLH->Get(name.c_str());
298 std::cerr <<
"Warning: LLH-scan histogram '" << name <<
"' not found in " << referenceLLHScanFile << std::endl;
301 TH1 *htmp =
dynamic_cast<TH1*
>(obj);
303 std::cerr <<
"Warning: Object '" << name <<
"' is not a histogram." << std::endl;
306 outHist = (TH1D*)htmp->Clone((std::string(
"hRefLLH_") + name +
"_clone").c_str());
307 outHist->SetDirectory(0);
309 double I = outHist->Integral();
310 if (I > 0) outHist->Scale(1.0 / I);
312 printHistStats(std::string(
"Reference LLH ") + name, outHist);
315 if (!referenceLLHScanDcpHistName.empty()) loadAndNormalize1D(referenceLLHScanDcpHistName, hRefLLH_Dcp, hasReferenceLLH_Dcp);
316 if (!referenceLLHScanDcp_NO_histName.empty()) loadAndNormalize1D(referenceLLHScanDcp_NO_histName, hRefLLH_Dcp_NO, hasReferenceLLH_Dcp_NO);
317 if (!referenceLLHScanDcp_IO_histName.empty()) loadAndNormalize1D(referenceLLHScanDcp_IO_histName, hRefLLH_Dcp_IO, hasReferenceLLH_Dcp_IO);
323 bool hasUmbrellaWeight =
false;
325 if (!tree->GetBranch(
"umbrella_weight")) {
326 std::cerr <<
"Warning: umbrella_weight branch not found, plotting as unweighted umbrella" << std::endl;
328 hasUmbrellaWeight =
true;
333 std::cout <<
"[DEBUG] Chain entries total=" << tree->GetEntries() << std::endl;
334 TH1D *hChainDelm23IO_dbg =
new TH1D(
"hChainDelm23IO_dbg",
"", nBins_delm23, delm23_io_min, delm23_io_max);
335 TH1D *hChainDelm23NO_dbg =
new TH1D(
"hChainDelm23NO_dbg",
"", nBins_delm23, delm23_no_min, delm23_no_max);
336 tree->Draw(
"delm2_23>>hChainDelm23IO_dbg",
"delm2_23 < 0",
"goff");
337 tree->Draw(
"delm2_23>>hChainDelm23NO_dbg",
"delm2_23 > 0",
"goff");
338 printHistStats(
"Chain delm23 IO (raw)", hChainDelm23IO_dbg);
339 printHistStats(
"Chain delm23 NO (raw)", hChainDelm23NO_dbg);
341 if (hasUmbrellaWeight) {
342 TH1D *hChainDelm23IO_w_dbg =
new TH1D(
"hChainDelm23IO_w_dbg",
"", nBins_delm23, delm23_io_min, delm23_io_max);
343 TH1D *hChainDelm23NO_w_dbg =
new TH1D(
"hChainDelm23NO_w_dbg",
"", nBins_delm23, delm23_no_min, delm23_no_max);
344 tree->Draw(
"delm2_23>>hChainDelm23IO_w_dbg",
"(delm2_23 < 0) * umbrella_weight",
"goff");
345 tree->Draw(
"delm2_23>>hChainDelm23NO_w_dbg",
"(delm2_23 > 0) * umbrella_weight",
"goff");
346 printHistStats(
"Chain delm23 IO (weighted)", hChainDelm23IO_w_dbg);
347 printHistStats(
"Chain delm23 NO (weighted)", hChainDelm23NO_w_dbg);
351 TCanvas *c1 =
new TCanvas(
"c1",
"Delta CP vs Delta m23", 900, 700);
352 c1->SetRightMargin(0.15);
354 TH2F *h2d =
new TH2F(
"h2d",
"#Delta m_{23}^{2} vs #delta_{CP};#delta_{CP};#Delta m_{23}^{2} (eV^{2})",
355 nBins_dcp, -3.14159, 3.14159,
356 nBins_delm23, delm23_io_min, delm23_no_max);
358 tree->Draw(
"delm2_23:delta_cp>>h2d",
"",
"COLZ");
363 h2d->GetXaxis()->SetTitle(
"#delta_{CP}");
364 h2d->GetYaxis()->SetTitle(
"#Delta m_{23}^{2} (eV^{2})");
365 h2d->GetZaxis()->SetTitle(
"Normalized Entries");
369 drawAsimovMarkerWithLegend(asimovDcp, asimovDelm23,
nullptr);
370 c1->SaveAs((outputDir +
"delm23_vs_dcp.png").c_str());
372 if (hasUmbrellaWeight){
373 tree->Draw(
"delm2_23:delta_cp>>h2d",
"umbrella_weight",
"COLZ");
377 drawAsimovMarkerWithLegend(asimovDcp, asimovDelm23,
nullptr);
378 c1->SaveAs((outputDir +
"delm23_vs_dcp_weighted.png").c_str());
383 TCanvas *c2 =
new TCanvas(
"c2",
"Delta m23 IO and NO", 1800, 700);
388 gPad->SetRightMargin(0.15);
390 TH2F *h2d_IO =
new TH2F(
"h2d_IO",
"Inverted Ordering;#Delta m_{23}^{2} (eV^{2});#delta_{CP}",
391 nBins_delm23, delm23_io_min, delm23_io_max,
392 nBins_dcp, -3.1415, 3.1415);
394 tree->Draw(
"delta_cp:delm2_23>>h2d_IO",
"delm2_23 < 0",
"COLZ");
395 normalizeHist(h2d_IO);
396 h2d_IO->Draw(
"COLZ");
399 h2d_IO->GetXaxis()->SetTitle(
"#Delta m_{23}^{2} (eV^{2})");
400 h2d_IO->GetYaxis()->SetTitle(
"#delta_{CP} / #pi");
401 h2d_IO->GetZaxis()->SetTitle(
"Normalized Entries");
406 gPad->SetRightMargin(0.15);
408 TH2F *h2d_NO =
new TH2F(
"h2d_NO",
"Normal Ordering;#Delta m_{23}^{2} (eV^{2});#delta_{CP}",
409 nBins_delm23, delm23_no_min, delm23_no_max,
410 nBins_dcp, -3.1415, 3.1415);
412 tree->Draw(
"delta_cp:delm2_23>>h2d_NO",
"delm2_23 > 0",
"COLZ");
413 normalizeHist(h2d_NO);
414 h2d_NO->Draw(
"COLZ");
417 h2d_NO->GetXaxis()->SetTitle(
"#Delta m_{23}^{2} (eV^{2})");
418 h2d_NO->GetYaxis()->SetTitle(
"#delta_{CP} / #pi");
419 h2d_NO->GetZaxis()->SetTitle(
"Normalized Entries");
425 drawAsimovMarkerWithLegend(asimovDelm23, asimovDcp,
nullptr);
427 drawAsimovMarkerWithLegend(asimovDelm23, asimovDcp,
nullptr);
429 c2->SaveAs((outputDir +
"delm23_vs_dcp_IO_NO.png").c_str());
431 if (hasUmbrellaWeight){
434 tree->Draw(
"delta_cp:delm2_23>>h2d_IO",
"(delm2_23 < 0) * umbrella_weight",
"COLZ");
435 normalizeHist(h2d_IO);
436 h2d_IO->Draw(
"COLZ");
440 tree->Draw(
"delta_cp:delm2_23>>h2d_NO",
"(delm2_23 > 0) * umbrella_weight",
"COLZ");
441 normalizeHist(h2d_NO);
442 h2d_NO->Draw(
"COLZ");
447 drawAsimovMarkerWithLegend(asimovDelm23, asimovDcp,
nullptr);
449 drawAsimovMarkerWithLegend(asimovDelm23, asimovDcp,
nullptr);
451 c2->SaveAs((outputDir +
"delm23_vs_dcp_IO_NO_weighted.png").c_str());
455 auto calculateHPDLevel = [](TH2F *hist,
double confidenceLevel) ->
double {
456 std::vector<double> binContents;
457 for (
int i = 1; i <= hist->GetNbinsX(); ++i) {
458 for (
int j = 1; j <= hist->GetNbinsY(); ++j) {
459 double content = hist->GetBinContent(i, j);
461 binContents.push_back(content);
466 if (binContents.empty())
return 0.0;
468 std::sort(binContents.rbegin(), binContents.rend());
471 for (
double val : binContents) totalSum += val;
473 double targetSum = confidenceLevel * totalSum;
474 double runningSum = 0;
476 for (
double val : binContents) {
478 if (runningSum >= targetSum) {
482 return binContents.back();
486 auto createWrappedHistogram = [](TH2F *originalHist,
const std::string &name) -> TH2F* {
487 int nBinsX = originalHist->GetNbinsX();
488 int nBinsY = originalHist->GetNbinsY();
490 double xMin = originalHist->GetXaxis()->GetBinLowEdge(1);
491 double xMax = originalHist->GetXaxis()->GetBinUpEdge(nBinsX);
492 double yMin = originalHist->GetYaxis()->GetBinLowEdge(1);
493 double yMax = originalHist->GetYaxis()->GetBinUpEdge(nBinsY);
494 double yRange = yMax - yMin;
497 TH2F *wrapped =
new TH2F(name.c_str(),
"",
499 nBinsY * 3, yMin - yRange, yMax + yRange);
500 wrapped->SetDirectory(0);
503 for (
int i = 1; i <= nBinsX; ++i) {
504 for (
int j = 1; j <= nBinsY; ++j) {
505 double content = originalHist->GetBinContent(i, j);
507 wrapped->SetBinContent(i, j + nBinsY, content);
509 wrapped->SetBinContent(i, j, content);
511 wrapped->SetBinContent(i, j + 2*nBinsY, content);
519 auto computeOneSidedBoundsValues = [&](TH1 *hist,
double targets[3],
double outBounds[3],
bool &integrateLeftToRight) {
520 for (
int i = 0; i < 3; ++i) outBounds[i] = std::numeric_limits<double>::quiet_NaN();
521 integrateLeftToRight =
true;
523 double total = hist->Integral();
524 if (total <= 0)
return;
525 int nBins = hist->GetNbinsX();
526 double leftSum = 0.0;
527 double rightSum = 0.0;
528 for (
int b = 1; b <= nBins; ++b) {
529 double center = hist->GetBinCenter(b);
530 double c = hist->GetBinContent(b);
531 if (center < 0) leftSum += c;
else rightSum += c;
533 integrateLeftToRight = (leftSum >= rightSum);
535 for (
int t = 0; t < 3; ++t) {
536 double target = targets[t];
538 if (integrateLeftToRight) {
539 for (
int b = 1; b <= nBins; ++b) {
540 cum += hist->GetBinContent(b);
541 if (cum / total >= target) {
542 outBounds[t] = hist->GetBinLowEdge(b+1);
546 if (!std::isfinite(outBounds[t])) outBounds[t] = hist->GetXaxis()->GetXmax();
548 for (
int b = nBins; b >= 1; --b) {
549 cum += hist->GetBinContent(b);
550 if (cum / total >= target) {
551 outBounds[t] = hist->GetBinLowEdge(b);
555 if (!std::isfinite(outBounds[t])) outBounds[t] = hist->GetXaxis()->GetXmin();
560 auto drawAbsDelm23Overlay = [&](
const std::string &suffix,
561 const std::string &ioSelection,
562 const std::string &noSelection) {
563 const int nBinsAbsDelm23 = 80;
564 const int nBinsAbsDcp = 60;
567 gStyle->SetPalette(kGreyScale);
568 TColor::InvertPalette();
570 TCanvas *cAbs =
new TCanvas((
"c_abs_" + suffix).c_str(),
"Delta m23 magnitude overlay", 900, 700);
571 cAbs->SetRightMargin(0.15);
572 cAbs->SetLeftMargin(0.12);
573 cAbs->SetBottomMargin(0.12);
575 TH2F *hAbsFrame =
new TH2F((
"hAbsFrame_" + suffix).c_str(),
576 "|#Delta m_{23}^{2}| vs #delta_{CP};|#Delta m_{23}^{2}| (eV^{2});#delta_{CP} / #pi",
577 nBinsAbsDelm23, delm23_no_min, delm23_no_max,
578 nBinsAbsDcp, -3.1415, 3.1415);
579 hAbsFrame->SetStats(0);
582 TH2F *hAbsIO =
new TH2F((
"hAbsIO_" + suffix).c_str(),
"",
583 nBinsAbsDelm23, delm23_no_min, delm23_no_max,
584 nBinsAbsDcp, -3.1415, 3.1415);
585 TH2F *hAbsNO =
new TH2F((
"hAbsNO_" + suffix).c_str(),
"",
586 nBinsAbsDelm23, delm23_no_min, delm23_no_max,
587 nBinsAbsDcp, -3.1415, 3.1415);
589 std::string ioDrawExpr = std::string(
"delta_cp:TMath::Abs(delm2_23)>>") + hAbsIO->GetName();
590 std::string noDrawExpr = std::string(
"delta_cp:TMath::Abs(delm2_23)>>") + hAbsNO->GetName();
591 tree->Draw(ioDrawExpr.c_str(), ioSelection.c_str(),
"goff");
592 tree->Draw(noDrawExpr.c_str(), noSelection.c_str(),
"goff");
594 hAbsIO->SetDirectory(0);
595 hAbsNO->SetDirectory(0);
596 printHistStats(
"Abs delm23 IO", hAbsIO);
597 printHistStats(
"Abs delm23 NO", hAbsNO);
600 double hpdLevel1SigmaNO = calculateHPDLevel(hAbsNO, 0.683);
602 double hpdLevel1SigmaIO = calculateHPDLevel(hAbsIO, 0.683);
605 hAbsNO->SetLineColor(kAzure + 2);
606 hAbsNO->SetLineWidth(1);
607 hAbsNO->Draw(
"COLZ");
609 hAbsIO->SetLineColor(kOrange + 7);
610 hAbsIO->SetLineWidth(1);
611 hAbsIO->Draw(
"COLZ SAME");
614 TH2F *hNO_contour = (TH2F *)hAbsNO->Clone(
"hNO_contour");
615 TH2F *hIO_contour = (TH2F *)hAbsIO->Clone(
"hIO_contour");
616 hNO_contour->SetDirectory(0);
617 hIO_contour->SetDirectory(0);
619 hNO_contour->Smooth(1,
"k5a");
620 hIO_contour->Smooth(1,
"k5a");
622 double noLevels[1] = {hpdLevel1SigmaNO};
623 hNO_contour->SetContour(1, noLevels);
624 hNO_contour->SetLineColor(kAzure + 2);
625 hNO_contour->SetLineWidth(3);
626 hNO_contour->Draw(
"CONT3 SAME");
628 double ioLevels[1] = {hpdLevel1SigmaIO};
629 hIO_contour->SetContour(1, ioLevels);
630 hIO_contour->SetLineColor(kOrange + 7);
631 hIO_contour->SetLineWidth(3);
632 hIO_contour->Draw(
"CONT3 SAME");
634 TLegend *legend =
new TLegend(0.68, 0.73, 0.88, 0.91);
635 legend->SetBorderSize(0);
636 legend->SetFillStyle(0);
637 legend->AddEntry(hAbsNO,
"NO 1#sigma",
"l");
638 legend->AddEntry(hAbsIO,
"IO 1#sigma",
"l");
641 drawAsimovMarkerWithLegend(std::abs(asimovDelm23), asimovDcp, legend);
643 cAbs->SaveAs((outputDir +
"delm23_vs_dcp_abs_IO_NO" + suffix +
".png").c_str());
646 drawAbsDelm23Overlay(
"",
"delm2_23 < 0",
"delm2_23 > 0");
648 if (hasUmbrellaWeight) {
649 drawAbsDelm23Overlay(
"_weighted",
650 "(delm2_23 < 0) * umbrella_weight",
651 "(delm2_23 > 0) * umbrella_weight");
655 gStyle->SetPalette(kBird);
658 TCanvas *c4 =
new TCanvas(
"c4",
"Delta m23 NO vs sin^{2}(#theta_{23})", 900, 700);
659 c4->SetRightMargin(0.15);
661 TH2F *h2d_sin =
new TH2F(
"h2d_sin",
"#Delta m_{23}^{2} vs sin^{2}(#theta_{23});sin^{2}(#theta_{23});#Delta m_{23}^{2} (eV^{2})",
662 nBins_sin2th23, sin2th23_min, sin2th23_max, nBins_delm23, delm23_no_min, delm23_no_max);
664 tree->Draw(
"delm2_23:sin2th_23>>h2d_sin",
"delm2_23 > 0",
"COLZ");
665 normalizeHist(h2d_sin);
666 h2d_sin->Draw(
"COLZ");
668 h2d_sin->SetStats(0);
669 h2d_sin->GetXaxis()->SetTitle(
"sin^{2}(#theta_{23})");
670 h2d_sin->GetYaxis()->SetTitle(
"#Delta m_{23}^{2} (eV^{2})");
671 h2d_sin->GetZaxis()->SetTitle(
"Normalized Entries");
675 drawAsimovMarkerWithLegend(asimovSin2th23, asimovDelm23,
nullptr);
677 c4->SaveAs((outputDir +
"th23_vs_delm23_no.png").c_str());
679 if (hasUmbrellaWeight){
680 tree->Draw(
"delm2_23:sin2th_23>>h2d_sin",
"(delm2_23 > 0) * umbrella_weight",
"COLZ");
681 normalizeHist(h2d_sin);
682 h2d_sin->Draw(
"COLZ");
683 drawAsimovMarkerWithLegend(asimovSin2th23, asimovDelm23,
nullptr);
685 c4->SaveAs((outputDir +
"th23_vs_delm23_no_weighted.png").c_str());
689 TCanvas *c5 =
new TCanvas(
"c5",
"Delta m23 IO vs sin^{2}(#theta_{23})", 900, 700);
690 c5->SetRightMargin(0.15);
692 TH2F *h2d_sin_IO =
new TH2F(
"h2d_sin_IO",
"#Delta m_{23}^{2} vs sin^{2}(#theta_{23});sin^{2}(#theta_{23});#Delta m_{23}^{2} (eV^{2})",
693 nBins_sin2th23, sin2th23_min, sin2th23_max,
694 nBins_delm23, delm23_io_min, delm23_io_max);
696 tree->Draw(
"delm2_23:sin2th_23>>h2d_sin_IO",
"delm2_23 < 0",
"COLZ");
697 normalizeHist(h2d_sin_IO);
698 h2d_sin_IO->Draw(
"COLZ");
700 h2d_sin_IO->SetStats(0);
701 h2d_sin_IO->GetXaxis()->SetTitle(
"sin^{2}(#theta_{23})");
702 h2d_sin_IO->GetYaxis()->SetTitle(
"#Delta m_{23}^{2} (eV^{2})");
703 h2d_sin_IO->GetZaxis()->SetTitle(
"Normalized Entries");
706 drawAsimovMarkerWithLegend(asimovSin2th23, asimovDelm23,
nullptr);
708 c5->SaveAs((outputDir +
"th23_vs_delm23_io.png").c_str());
710 if (hasUmbrellaWeight){
711 tree->Draw(
"delm2_23:sin2th_23>>h2d_sin_IO",
"(delm2_23 < 0)*umbrella_weight",
"COLZ");
712 normalizeHist(h2d_sin_IO);
713 h2d_sin_IO->Draw(
"COLZ");
714 drawAsimovMarkerWithLegend(asimovSin2th23, asimovDelm23,
nullptr);
716 c5->SaveAs((outputDir +
"th23_vs_delm23_io_weighted.png").c_str());
720 TCanvas *c6 =
new TCanvas(
"c6",
"Delta_cp vs sin^{2}(#theta_{23})", 900, 700);
721 c6->SetRightMargin(0.15);
723 TH2F *h2d_delta_cp =
new TH2F(
"h2d_delta_cp",
"#delta_{CP} vs sin^{2}(#theta_{23});#delta_{CP};sin^{2}(#theta_{23})",
724 nBins_dcp, -3.1415, 3.1415,
725 nBins_sin2th23, sin2th23_min, sin2th23_max);
727 tree->Draw(
"sin2th_23:delta_cp>>h2d_delta_cp",
"",
"COLZ");
728 normalizeHist(h2d_delta_cp);
729 h2d_delta_cp->Draw(
"COLZ");
731 h2d_delta_cp->SetStats(0);
732 h2d_delta_cp->GetYaxis()->SetTitle(
"sin^{2}(#theta_{23})");
733 h2d_delta_cp->GetXaxis()->SetTitle(
"#delta_{CP}");
734 h2d_delta_cp->GetZaxis()->SetTitle(
"Normalized Entries");
737 drawAsimovMarkerWithLegend(asimovDcp, asimovSin2th23,
nullptr);
739 c6->SaveAs((outputDir +
"th23_vs_delta_cp.png").c_str());
741 if (hasUmbrellaWeight){
742 tree->Draw(
"sin2th_23:delta_cp>>h2d_delta_cp",
"umbrella_weight",
"COLZ");
743 normalizeHist(h2d_delta_cp);
744 h2d_delta_cp->Draw(
"COLZ");
745 drawAsimovMarkerWithLegend(asimovDcp, asimovSin2th23,
nullptr);
747 c6->SaveAs((outputDir +
"th23_vs_delta_cp_weighted.png").c_str());
751 TCanvas *cth13 =
new TCanvas(
"cth13",
"Delta_cp vs sin^{2}(#theta_{13})", 900, 700);
752 cth13->SetRightMargin(0.15);
754 TH2F *h2d_delta_cp_13 =
new TH2F(
"h2d_delta_cp_13",
"#delta_{CP} vs sin^{2}(#theta_{13});#delta_{CP};sin^{2}(#theta_{13})",
755 nBins_dcp, -3.1415, 3.1415,
756 nBins_sin2th13, sin2th13_min, sin2th13_max);
758 tree->Draw(
"sin2th_13:delta_cp>>h2d_delta_cp_13",
"",
"COLZ");
759 normalizeHist(h2d_delta_cp_13);
760 h2d_delta_cp_13->Draw(
"COLZ");
762 h2d_delta_cp_13->SetStats(0);
763 h2d_delta_cp_13->GetYaxis()->SetTitle(
"sin^{2}(#theta_{13})");
764 h2d_delta_cp_13->GetXaxis()->SetTitle(
"#delta_{CP}");
765 h2d_delta_cp_13->GetZaxis()->SetTitle(
"Normalized Entries");
768 drawAsimovMarkerWithLegend(asimovDcp, asimovSin2th13,
nullptr);
770 cth13->SaveAs((outputDir +
"th13_vs_delta_cp.png").c_str());
772 if (hasUmbrellaWeight){
773 tree->Draw(
"sin2th_13:delta_cp>>h2d_delta_cp_13",
"umbrella_weight",
"COLZ");
774 normalizeHist(h2d_delta_cp_13);
775 h2d_delta_cp_13->Draw(
"COLZ");
776 drawAsimovMarkerWithLegend(asimovDcp, asimovSin2th13,
nullptr);
778 cth13->SaveAs((outputDir +
"th13_vs_delta_cp_weighted.png").c_str());
782 TCanvas *c7 =
new TCanvas(
"c7",
"1D Histograms", 3200, 1200);
787 TH1F *h1d_delta_cp_unweighted =
new TH1F(
"h1d_delta_cp_unweighted",
"#delta_{CP};#delta_{CP};Entries", nBins_dcp, -3.1415, 3.1415);
788 tree->Draw(
"delta_cp>>h1d_delta_cp_unweighted",
"",
"");
789 normalizeHist(h1d_delta_cp_unweighted);
790 h1d_delta_cp_unweighted->SetMinimum(0);
791 h1d_delta_cp_unweighted->SetStats(0);
792 h1d_delta_cp_unweighted->Draw(
"HIST");
793 h1d_delta_cp_unweighted->Draw(
"E SAME");
794 drawAsimovLineWithLegend(asimovDcp);
797 TH1F *h1d_delm23_all_unweighted =
new TH1F(
"h1d_delm23_all_unweighted",
"#Delta m_{23}^{2} (full range);#Delta m_{23}^{2} (eV^{2});Normalized Entries", nBins_delm23, delm23_io_min, delm23_no_max);
798 tree->Draw(
"delm2_23>>h1d_delm23_all_unweighted",
"",
"");
799 normalizeHist(h1d_delm23_all_unweighted);
800 h1d_delm23_all_unweighted->SetStats(0);
801 h1d_delm23_all_unweighted->Draw(
"HIST");
802 h1d_delm23_all_unweighted->Draw(
"E SAME");
803 drawAsimovLineWithLegend(asimovDelm23);
806 TH1F *h1d_delm23_unweighted = (TH1F*)h1d_delm23_all_unweighted->Clone(
"h1d_delm23_IO_unweighted");
807 h1d_delm23_unweighted->SetTitle(
"#Delta m_{23}^{2} (IO)");
808 h1d_delm23_unweighted->SetStats(0);
809 h1d_delm23_unweighted->GetXaxis()->SetRangeUser(delm23_io_min, delm23_io_max);
810 h1d_delm23_unweighted->Draw(
"HIST");
811 h1d_delm23_unweighted->Draw(
"E SAME");
812 drawAsimovLineWithLegend(asimovDelm23);
815 TH1F *h1d_delm23_NO_unweighted = (TH1F*)h1d_delm23_all_unweighted->Clone(
"h1d_delm23_NO_unweighted");
816 h1d_delm23_unweighted->SetTitle(
"#Delta m_{23}^{2} (NO)");
817 h1d_delm23_NO_unweighted->SetStats(0);
818 h1d_delm23_NO_unweighted->GetXaxis()->SetRangeUser(delm23_no_min, delm23_no_max);
819 h1d_delm23_NO_unweighted->Draw(
"HIST");
820 h1d_delm23_NO_unweighted->Draw(
"E SAME");
821 drawAsimovLineWithLegend(asimovDelm23);
824 TH1F *h1d_sinth23_unweighted =
new TH1F(
"h1d_sinth23_unweighted",
"sin^{2}(#theta_{23});sin^{2}(#theta_{23});Entries", nBins_sin2th23, sin2th23_min, sin2th23_max);
825 tree->Draw(
"sin2th_23>>h1d_sinth23_unweighted",
"",
"");
826 normalizeHist(h1d_sinth23_unweighted);
827 h1d_sinth23_unweighted->SetStats(0);
828 h1d_sinth23_unweighted->Draw(
"HIST");
829 h1d_sinth23_unweighted->Draw(
"E SAME");
830 drawAsimovLineWithLegend(asimovSin2th23);
833 TH1F *h1d_sinth13_unweighted =
new TH1F(
"h1d_sinth13_unweighted",
"sin^{2}(#theta_{13});sin^{2}(#theta_{13});Entries", nBins_sin2th13, sin2th13_min, sin2th13_max);
834 tree->Draw(
"sin2th_13>>h1d_sinth13_unweighted",
"",
"");
835 normalizeHist(h1d_sinth13_unweighted);
836 h1d_sinth13_unweighted->SetStats(0);
837 h1d_sinth13_unweighted->Draw(
"HIST");
838 h1d_sinth13_unweighted->Draw(
"E SAME");
839 drawAsimovLineWithLegend(asimovSin2th13);
842 TH1F *h1d_sinth12_unweighted =
new TH1F(
"h1d_sinth12_unweighted",
"sin^{2}(#theta_{12});sin^{2}(#theta_{12});Entries", nBins_sin2th12, sin2th12_min, sin2th12_max);
843 tree->Draw(
"sin2th_12>>h1d_sinth12_unweighted",
"",
"");
844 normalizeHist(h1d_sinth12_unweighted);
845 h1d_sinth12_unweighted->SetStats(0);
846 h1d_sinth12_unweighted->Draw(
"HIST");
847 h1d_sinth12_unweighted->Draw(
"E SAME");
848 drawAsimovLineWithLegend(asimovSin2th12);
851 TH1F *h1d_delm12_unweighted =
new TH1F(
"h1d_delm12_unweighted",
"#Delta m_{12}^{2};#Delta m_{12}^{2} (eV^{2});Entries", nBins_delm12, delm12_min, delm12_max);
852 tree->Draw(
"delm2_12>>h1d_delm12_unweighted",
"",
"");
853 normalizeHist(h1d_delm12_unweighted);
854 h1d_delm12_unweighted->SetStats(0);
855 h1d_delm12_unweighted->Draw(
"HIST");
856 h1d_delm12_unweighted->Draw(
"E SAME");
857 drawAsimovLineWithLegend(asimovDelm12);
860 c7->SaveAs((outputDir +
"1D_histograms_unweighted.png").c_str());
863 TCanvas *c7_weighted =
new TCanvas(
"c7_weighted",
"1D Histograms Weighted", 3200, 1200);
864 c7_weighted->Divide(4, 2);
868 TH1F *h1d_delta_cp =
new TH1F(
"h1d_delta_cp",
"#delta_{CP};#delta_{CP};Weighted Entries", nBins_dcp, -3.1415, 3.1415);
869 if (hasUmbrellaWeight) {
870 tree->Draw(
"delta_cp>>h1d_delta_cp",
"umbrella_weight",
"");
872 tree->Draw(
"delta_cp>>h1d_delta_cp",
"",
"");
873 std::cout <<
"WARNING:::::No umbrella weights found, plotting unweighted delta_cp histogram." << std::endl;
875 normalizeHist(h1d_delta_cp);
876 h1d_delta_cp->SetStats(0);
877 h1d_delta_cp->Sumw2();
878 h1d_delta_cp->Draw(
"HIST");
879 h1d_delta_cp->Draw(
"E SAME");
884 double sigma1 = 0.6827;
885 double sigma3 = 0.9973;
886 double sigma5 = 0.99994;
897 double maxEntries = 0;
898 for (
int j = 1; j <= h1d_delta_cp->GetNbinsX(); j++) {
899 if (h1d_delta_cp->GetBinContent(j) > maxEntries) {
900 maxEntries = h1d_delta_cp->GetBinContent(j);
905 std::cout <<
"HPD bin: " << hpdBin <<
" with " << maxEntries <<
" entries" << std::endl;
908 TH1F *h1d_copy = (TH1F*)h1d_delta_cp->Clone(
"h1d_copy");
911 std::vector<bool> included(h1d_delta_cp->GetNbinsX() + 1,
false);
912 included[hpdBin] =
true;
915 auto findContiguousRegions = [&](
int gapTolerance = 2) {
916 std::vector<std::pair<int, int>> regions;
921 for (
int k = 1; k <= h1d_delta_cp->GetNbinsX(); k++) {
927 }
else if (start != -1) {
929 if (gapCount > gapTolerance) {
931 regions.push_back({start, k - gapCount});
940 regions.push_back({start, h1d_delta_cp->GetNbinsX()});
947 double totalEntries = h1d_delta_cp->Integral();
948 double sumEntries = h1d_delta_cp->GetBinContent(hpdBin);
953 std::vector<std::pair<double, double>> sigma1_regions;
954 std::vector<std::pair<double, double>> sigma3_regions;
955 std::vector<std::pair<double, double>> sigma5_regions;
957 for (
int i = 0; i < h1d_delta_cp->GetNbinsX(); i++) {
960 double maxBinEntries = 0;
961 for (
int j = 1; j <= h1d_delta_cp->GetNbinsX(); j++) {
962 if (!included[j] && h1d_copy->GetBinContent(j) > maxBinEntries) {
963 maxBinEntries = h1d_copy->GetBinContent(j);
968 if (maxBin == 0)
break;
970 sumEntries += maxBinEntries;
971 included[maxBin] =
true;
972 double frac = sumEntries / totalEntries;
974 std::cout <<
"Added bin " << maxBin <<
" with " << maxBinEntries <<
" entries. Fraction: " << frac << std::endl;
976 if (frac >= sigma1 && level1 == 0) {
977 level1 = maxBinEntries;
978 std::cout <<
"1 sigma level: " << level1 << std::endl;
980 auto regions = findContiguousRegions(2);
981 std::cout <<
"1 sigma regions (" << regions.size() <<
" mode(s)):" << std::endl;
982 for (
const auto& region : regions) {
983 double lower = h1d_delta_cp->GetBinLowEdge(region.first);
984 double upper = h1d_delta_cp->GetBinLowEdge(region.second + 1);
985 sigma1_regions.push_back({lower, upper});
986 std::cout <<
" [" << lower <<
", " << upper <<
"]" << std::endl;
989 if (frac >= sigma3 && level3 == 0) {
990 level3 = maxBinEntries;
991 std::cout <<
"3 sigma level: " << level3 << std::endl;
993 auto regions = findContiguousRegions(2);
994 std::cout <<
"3 sigma regions (" << regions.size() <<
" mode(s)):" << std::endl;
995 for (
const auto& region : regions) {
996 double lower = h1d_delta_cp->GetBinLowEdge(region.first);
997 double upper = h1d_delta_cp->GetBinLowEdge(region.second + 1);
998 sigma3_regions.push_back({lower, upper});
999 std::cout <<
" [" << lower <<
", " << upper <<
"]" << std::endl;
1002 if (frac >= sigma5 && level5 == 0) {
1003 level5 = maxBinEntries;
1004 std::cout <<
"5 sigma level: " << level5 << std::endl;
1006 auto regions = findContiguousRegions(2);
1007 std::cout <<
"5 sigma regions (" << regions.size() <<
" mode(s)):" << std::endl;
1008 for (
const auto& region : regions) {
1009 double lower = h1d_delta_cp->GetBinLowEdge(region.first);
1010 double upper = h1d_delta_cp->GetBinLowEdge(region.second + 1);
1011 sigma5_regions.push_back({lower, upper});
1012 std::cout <<
" [" << lower <<
", " << upper <<
"]" << std::endl;
1018 double ymax = h1d_delta_cp->GetMaximum();
1021 for (
const auto& region : sigma1_regions) {
1022 TLine *line_lower =
new TLine(region.first, 0, region.first, ymax);
1023 line_lower->SetLineColor(kOrange+1);
1024 line_lower->SetLineStyle(2);
1025 line_lower->SetLineWidth(2);
1026 line_lower->Draw(
"same");
1028 TLine *line_upper =
new TLine(region.second, 0, region.second, ymax);
1029 line_upper->SetLineColor(kOrange+1);
1030 line_upper->SetLineStyle(2);
1031 line_upper->SetLineWidth(2);
1032 line_upper->Draw(
"same");
1036 for (
const auto& region : sigma3_regions) {
1037 TLine *line_lower =
new TLine(region.first, 0, region.first, ymax);
1038 line_lower->SetLineColor(kAzure+2);
1039 line_lower->SetLineStyle(2);
1040 line_lower->SetLineWidth(2);
1041 line_lower->Draw(
"same");
1043 TLine *line_upper =
new TLine(region.second, 0, region.second, ymax);
1044 line_upper->SetLineColor(kAzure+2);
1045 line_upper->SetLineStyle(2);
1046 line_upper->SetLineWidth(2);
1047 line_upper->Draw(
"same");
1051 for (
const auto& region : sigma5_regions) {
1052 TLine *line_lower =
new TLine(region.first, 0, region.first, ymax);
1053 line_lower->SetLineColor(kMagenta+2);
1054 line_lower->SetLineStyle(2);
1055 line_lower->SetLineWidth(2);
1056 line_lower->Draw(
"same");
1058 TLine *line_upper =
new TLine(region.second, 0, region.second, ymax);
1059 line_upper->SetLineColor(kMagenta+2);
1060 line_upper->SetLineStyle(2);
1061 line_upper->SetLineWidth(2);
1062 line_upper->Draw(
"same");
1065 TLegend *legRef =
nullptr;
1066 if (hasReferenceDcp && hRefDcpShape) {
1067 std::cout <<
"Overlaying reference delta_cp shape on weighted histogram" << std::endl;
1068 TH1D *hRefOverlay = (TH1D*)hRefDcpShape->Clone(
"hRefDcpShape_overlay_linear");
1069 hRefOverlay->SetDirectory(0);
1070 double refIntegral = hRefOverlay->Integral();
1071 if (refIntegral > 0) {
1072 hRefOverlay->Scale(h1d_delta_cp->Integral() / refIntegral);
1074 hRefOverlay->SetLineColor(kMagenta + 2);
1075 hRefOverlay->SetLineWidth(3);
1076 hRefOverlay->SetLineStyle(1);
1077 hRefOverlay->SetFillStyle(0);
1078 hRefOverlay->Draw(
"HIST SAME");
1080 legRef =
new TLegend(0.15, 0.74, 0.48, 0.88);
1081 legRef->SetBorderSize(0);
1082 legRef->SetFillStyle(0);
1083 legRef->AddEntry(h1d_delta_cp,
"Umbrella weighted",
"l");
1084 legRef->AddEntry(hRefOverlay,
"Reference dcp (shape, area-normalized)",
"l");
1087 drawAsimovLineWithLegend(asimovDcp, hasReferenceDcp ? legRef :
nullptr);
1090 if (hasReferenceLLH_Dcp && hRefLLH_Dcp) {
1091 std::cout <<
"Overlaying LLH-scan reference dcp histogram on weighted histogram (resampled to umbrella bins)" << std::endl;
1093 TH1D *hLLHResamp =
new TH1D(
"hRefLLH_dcp_resamp",
"", h1d_delta_cp->GetNbinsX(), h1d_delta_cp->GetXaxis()->GetXmin(), h1d_delta_cp->GetXaxis()->GetXmax());
1094 hLLHResamp->SetDirectory(0);
1095 for (
int i = 1; i <= hLLHResamp->GetNbinsX(); ++i) {
1096 double xlow = hLLHResamp->GetBinLowEdge(i);
1097 double xhigh = hLLHResamp->GetBinLowEdge(i+1);
1099 int nOrig = hRefLLH_Dcp->GetNbinsX();
1100 for (
int k = 1; k <= nOrig; ++k) {
1101 double origLow = hRefLLH_Dcp->GetXaxis()->GetBinLowEdge(k);
1102 double origHigh = origLow + hRefLLH_Dcp->GetBinWidth(k);
1103 double overlap = std::max(0.0, std::min(origHigh, xhigh) - std::max(origLow, xlow));
1104 if (overlap > 0.0) {
1105 double origWidth = hRefLLH_Dcp->GetBinWidth(k);
1106 double contrib = hRefLLH_Dcp->GetBinContent(k) * (overlap / origWidth);
1110 hLLHResamp->SetBinContent(i, val);
1113 double llhInt = hLLHResamp->Integral();
1114 if (llhInt > 0) hLLHResamp->Scale(h1d_delta_cp->Integral() / llhInt);
1115 hLLHResamp->SetLineColor(kBlack);
1116 hLLHResamp->SetLineWidth(3);
1117 hLLHResamp->SetLineStyle(2);
1118 hLLHResamp->SetFillStyle(0);
1119 hLLHResamp->Draw(
"HIST SAME");
1121 TLegend *legLLH =
new TLegend(0.15, 0.60, 0.50, 0.74);
1122 legLLH->SetBorderSize(0);
1123 legLLH->SetFillStyle(0);
1124 legLLH->AddEntry(h1d_delta_cp,
"Umbrella weighted",
"l");
1125 legLLH->AddEntry(hLLHResamp,
"LLH scan (resampled)",
"l");
1130 TH1F *h1d_delm23_all =
new TH1F(
"h1d_delm23_all",
"#Delta m_{23}^{2} (full range);#Delta m_{23}^{2} (eV^{2});Normalized Entries", nBins_delm23, delm23_io_min, delm23_no_max);
1131 if (hasUmbrellaWeight) {
1132 tree->Draw(
"delm2_23>>h1d_delm23_all",
"umbrella_weight",
"");
1133 std::cout <<
"Applying umbrella weights to delm23 histogram" << std::endl;
1135 tree->Draw(
"delm2_23>>h1d_delm23_all",
"",
"");
1136 std::cout <<
"WARNING:::::No umbrella weights found, plotting unweighted #Delta m_{23}^{2} histogram." << std::endl;
1138 normalizeHist(h1d_delm23_all);
1139 h1d_delm23_all->SetStats(0);
1140 h1d_delm23_all->Draw(
"HIST");
1141 h1d_delm23_all->Draw(
"E SAME");
1143 TLegend *legRefDelm23All =
nullptr;
1144 if (hasReferenceDelm23 && hRefDelm23Shape) {
1145 TH1D *hRefDelm23AllOverlay = (TH1D*)hRefDelm23Shape->Clone(
"hRefDelm23All_overlay_linear");
1146 hRefDelm23AllOverlay->SetDirectory(0);
1147 double refIntegral = hRefDelm23AllOverlay->Integral();
1148 if (refIntegral > 0) {
1149 hRefDelm23AllOverlay->Scale(h1d_delm23_all->Integral() / refIntegral);
1151 hRefDelm23AllOverlay->SetLineColor(kMagenta + 2);
1152 hRefDelm23AllOverlay->SetLineWidth(3);
1153 hRefDelm23AllOverlay->SetLineStyle(1);
1154 hRefDelm23AllOverlay->SetFillStyle(0);
1155 hRefDelm23AllOverlay->Draw(
"HIST SAME");
1157 legRefDelm23All =
new TLegend(0.50, 0.74, 0.88, 0.88);
1158 legRefDelm23All->SetBorderSize(0);
1159 legRefDelm23All->SetFillStyle(0);
1160 legRefDelm23All->AddEntry(h1d_delm23_all,
"Umbrella weighted",
"l");
1161 legRefDelm23All->AddEntry(hRefDelm23AllOverlay,
"Reference #Delta m_{23}^{2} (full range)",
"l");
1162 legRefDelm23All->Draw();
1164 drawAsimovLineWithLegend(asimovDelm23, hasReferenceDelm23 ? legRefDelm23All :
nullptr);
1167 TH1F *h1d_delm23 = (TH1F*)h1d_delm23_all->Clone(
"h1d_delm23_IO");
1168 h1d_delm23->SetStats(0);
1169 h1d_delm23->Sumw2();
1170 h1d_delm23->GetXaxis()->SetRangeUser(delm23_io_min, delm23_io_max);
1171 h1d_delm23->Draw(
"HIST");
1172 h1d_delm23->Draw(
"E SAME");
1174 TLegend *legRefDelm23IO =
nullptr;
1175 if (hasReferenceDelm23 && hRefDelm23Shape) {
1176 TH1D *hRefDelm23IOOverlay = (TH1D*)hRefDelm23Shape->Clone(
"hRefDelm23IO_overlay_linear");
1177 hRefDelm23IOOverlay->SetDirectory(0);
1178 hRefDelm23IOOverlay->GetXaxis()->SetRangeUser(delm23_io_min, delm23_io_max);
1179 hRefDelm23IOOverlay->SetLineColor(kMagenta + 2);
1180 hRefDelm23IOOverlay->SetLineWidth(3);
1181 hRefDelm23IOOverlay->SetLineStyle(1);
1182 hRefDelm23IOOverlay->SetFillStyle(0);
1183 hRefDelm23IOOverlay->Draw(
"HIST SAME");
1185 legRefDelm23IO =
new TLegend(0.50, 0.74, 0.88, 0.88);
1186 legRefDelm23IO->SetBorderSize(0);
1187 legRefDelm23IO->SetFillStyle(0);
1188 legRefDelm23IO->AddEntry(h1d_delm23,
"Umbrella weighted",
"l");
1189 legRefDelm23IO->AddEntry(hRefDelm23IOOverlay,
"Reference #Delta m_{23}^{2} (IO)",
"l");
1190 legRefDelm23IO->Draw();
1192 drawAsimovLineWithLegend(asimovDelm23, hasReferenceDelm23 ? legRefDelm23IO :
nullptr);
1195 TH1F *h1d_delm23_NO = (TH1F*)h1d_delm23_all->Clone(
"h1d_delm23_NO");
1196 h1d_delm23_NO->SetStats(0);
1197 h1d_delm23_NO->Sumw2();
1198 h1d_delm23_NO->GetXaxis()->SetRangeUser(delm23_no_min, delm23_no_max);
1199 h1d_delm23_NO->Draw(
"HIST");
1200 h1d_delm23_NO->Draw(
"E SAME");
1202 TLegend *legRefDelm23NO =
nullptr;
1203 if (hasReferenceDelm23 && hRefDelm23Shape) {
1204 std::cout <<
"Drawing reference delm23 shape for NO" << std::endl;
1205 TH1D *hRefDelm23NOOverlay = (TH1D*)hRefDelm23Shape->Clone(
"hRefDelm23NO_overlay_linear");
1206 hRefDelm23NOOverlay->SetDirectory(0);
1207 hRefDelm23NOOverlay->GetXaxis()->SetRangeUser(delm23_no_min, delm23_no_max);
1208 hRefDelm23NOOverlay->SetLineColor(kMagenta + 2);
1209 hRefDelm23NOOverlay->SetLineWidth(3);
1210 hRefDelm23NOOverlay->SetLineStyle(1);
1211 hRefDelm23NOOverlay->SetFillStyle(0);
1212 hRefDelm23NOOverlay->Draw(
"HIST SAME");
1214 legRefDelm23NO =
new TLegend(0.50, 0.74, 0.88, 0.88);
1215 legRefDelm23NO->SetBorderSize(0);
1216 legRefDelm23NO->SetFillStyle(0);
1217 legRefDelm23NO->AddEntry(h1d_delm23_NO,
"Umbrella weighted",
"l");
1218 legRefDelm23NO->AddEntry(hRefDelm23NOOverlay,
"Reference #Delta m_{23}^{2} (NO)",
"l");
1219 legRefDelm23NO->Draw();
1221 drawAsimovLineWithLegend(asimovDelm23, hasReferenceDelm23 ? legRefDelm23NO :
nullptr);
1225 if (h1d_delm23_all) {
1226 int binIO_low = h1d_delm23_all->GetXaxis()->FindBin(delm23_io_min);
1227 int binIO_high = h1d_delm23_all->GetXaxis()->FindBin(delm23_io_max);
1228 int binNO_low = h1d_delm23_all->GetXaxis()->FindBin(delm23_no_min);
1229 int binNO_high = h1d_delm23_all->GetXaxis()->FindBin(delm23_no_max);
1231 double fracIO = h1d_delm23_all->Integral(binIO_low, binIO_high);
1232 double fracNO = h1d_delm23_all->Integral(binNO_low, binNO_high);
1235 double ratioNOtoIO = fracNO / fracIO;
1236 std::cout <<
"Mass ordering preference (NO/IO) = " << ratioNOtoIO
1237 <<
" (NO frac=" << fracNO <<
", IO frac=" << fracIO <<
")" << std::endl;
1239 std::cout <<
"Mass ordering preference: IO fraction is zero; cannot compute ratio. "
1240 <<
"NO_frac=" << fracNO <<
" IO_frac=" << fracIO << std::endl;
1243 std::cout <<
"Mass ordering preference: h1d_delm23_all is null; cannot compute." << std::endl;
1247 TH1F *h1d_sinth23 =
new TH1F(
"h1d_sinth23",
"sin^{2}(#theta_{23});sin^{2}(#theta_{23});Weighted Entries", nBins_sin2th23, sin2th23_min, sin2th23_max);
1248 if (hasUmbrellaWeight) {
1249 tree->Draw(
"sin2th_23>>h1d_sinth23",
"umbrella_weight",
"");
1251 tree->Draw(
"sin2th_23>>h1d_sinth23",
"",
"");
1252 std::cout <<
"WARNING:::::No umbrella weights found, plotting unweighted sin^2(theta23) histogram." << std::endl;
1254 normalizeHist(h1d_sinth23);
1255 h1d_sinth23->SetStats(0);
1256 h1d_sinth23->Sumw2();
1257 h1d_sinth23->Draw(
"HIST");
1258 h1d_sinth23->Draw(
"E SAME");
1260 TLegend *legRefSin =
nullptr;
1261 if (hasReferenceSin2Th23 && hRefSin2Th23Shape) {
1262 TH1D *hRefSinOverlay = (TH1D*)hRefSin2Th23Shape->Clone(
"hRefSin2Th23_overlay_linear");
1263 hRefSinOverlay->SetDirectory(0);
1264 double refIntegral = hRefSinOverlay->Integral();
1265 if (refIntegral > 0) {
1266 hRefSinOverlay->Scale(h1d_sinth23->Integral() / refIntegral);
1268 hRefSinOverlay->SetLineColor(kMagenta + 2);
1269 hRefSinOverlay->SetLineWidth(3);
1270 hRefSinOverlay->SetLineStyle(1);
1271 hRefSinOverlay->SetFillStyle(0);
1272 hRefSinOverlay->Draw(
"HIST SAME");
1274 legRefSin =
new TLegend(0.50, 0.74, 0.88, 0.88);
1275 legRefSin->SetBorderSize(0);
1276 legRefSin->SetFillStyle(0);
1277 legRefSin->AddEntry(h1d_sinth23,
"Umbrella weighted",
"l");
1278 legRefSin->AddEntry(hRefSinOverlay,
"Reference sin^{2}(#theta_{23})",
"l");
1281 drawAsimovLineWithLegend(asimovSin2th23, hasReferenceSin2Th23 ? legRefSin :
nullptr);
1284 TH1F *h1d_sinth13 =
new TH1F(
"h1d_sinth13",
"sin^{2}(#theta_{13});sin^{2}(#theta_{13});Weighted Entries", nBins_sin2th13, sin2th13_min, sin2th13_max);
1285 if (hasUmbrellaWeight) {
1286 tree->Draw(
"sin2th_13>>h1d_sinth13",
"umbrella_weight",
"");
1288 tree->Draw(
"sin2th_13>>h1d_sinth13",
"",
"");
1289 std::cout <<
"WARNING:::::No umbrella weights found, plotting unweighted sin^2(theta13) histogram." << std::endl;
1291 normalizeHist(h1d_sinth13);
1292 h1d_sinth13->SetStats(0);
1293 h1d_sinth13->Sumw2();
1294 h1d_sinth13->Draw(
"HIST");
1295 h1d_sinth13->Draw(
"E SAME");
1296 drawAsimovLineWithLegend(asimovSin2th13);
1299 TH1F *h1d_sinth12 =
new TH1F(
"h1d_sinth12",
"sin^{2}(#theta_{12});sin^{2}(#theta_{12});Weighted Entries", nBins_sin2th12, sin2th12_min, sin2th12_max);
1300 if (hasUmbrellaWeight) {
1301 tree->Draw(
"sin2th_12>>h1d_sinth12",
"umbrella_weight",
"");
1303 tree->Draw(
"sin2th_12>>h1d_sinth12",
"",
"");
1304 std::cout <<
"WARNING:::::No umbrella weights found, plotting unweighted sin^2(theta12) histogram." << std::endl;
1306 normalizeHist(h1d_sinth12);
1307 h1d_sinth12->SetStats(0);
1308 h1d_sinth12->Sumw2();
1309 h1d_sinth12->Draw(
"HIST");
1310 h1d_sinth12->Draw(
"E SAME");
1311 drawAsimovLineWithLegend(asimovSin2th12);
1314 TH1F *h1d_delm12 =
new TH1F(
"h1d_delm12",
"#Delta m_{12}^{2};#Delta m_{12}^{2} (eV^{2});Weighted Entries", nBins_delm12, delm12_min, delm12_max);
1315 if (hasUmbrellaWeight) {
1316 tree->Draw(
"delm2_12>>h1d_delm12",
"umbrella_weight",
"");
1318 tree->Draw(
"delm2_12>>h1d_delm12",
"",
"");
1319 std::cout <<
"WARNING:::::No umbrella weights found, plotting unweighted #Delta m_{12}^{2} histogram." << std::endl;
1321 normalizeHist(h1d_delm12);
1322 h1d_delm12->SetStats(0);
1323 h1d_delm12->Sumw2();
1324 h1d_delm12->Draw(
"HIST");
1325 h1d_delm12->Draw(
"E SAME");
1326 drawAsimovLineWithLegend(asimovDelm12);
1328 c7_weighted->Update();
1329 c7_weighted->SaveAs((outputDir +
"1D_histograms_weighted.png").c_str());
1332 TCanvas *c8 =
new TCanvas(
"c8",
"Delta CP Log Scale", 900, 700);
1334 TH1F *h1d_delta_cp_log = (TH1F*)h1d_delta_cp->Clone(
"h1d_delta_cp_log");
1335 h1d_delta_cp_log->SetTitle(
"#delta_{CP} (Log Scale);#delta_{CP};Weighted Entries");
1336 h1d_delta_cp_log->Draw(
"HIST");
1337 h1d_delta_cp_log->Draw(
"E SAME");
1340 double ymax_log = h1d_delta_cp_log->GetMaximum();
1341 double ymin_log = h1d_delta_cp_log->GetMinimum();
1342 if (ymin_log <= 0) ymin_log = 0.1;
1345 for (
const auto& region : sigma1_regions) {
1346 TLine *line_lower =
new TLine(region.first, ymin_log, region.first, ymax_log);
1347 line_lower->SetLineColor(kRed);
1348 line_lower->SetLineStyle(2);
1349 line_lower->SetLineWidth(2);
1350 line_lower->Draw(
"same");
1352 TLine *line_upper =
new TLine(region.second, ymin_log, region.second, ymax_log);
1353 line_upper->SetLineColor(kRed);
1354 line_upper->SetLineStyle(2);
1355 line_upper->SetLineWidth(2);
1356 line_upper->Draw(
"same");
1360 for (
const auto& region : sigma3_regions) {
1361 TLine *line_lower =
new TLine(region.first, ymin_log, region.first, ymax_log);
1362 line_lower->SetLineColor(kAzure+2);
1363 line_lower->SetLineStyle(2);
1364 line_lower->SetLineWidth(2);
1365 line_lower->Draw(
"same");
1367 TLine *line_upper =
new TLine(region.second, ymin_log, region.second, ymax_log);
1368 line_upper->SetLineColor(kAzure+2);
1369 line_upper->SetLineStyle(2);
1370 line_upper->SetLineWidth(2);
1371 line_upper->Draw(
"same");
1375 for (
const auto& region : sigma5_regions) {
1376 TLine *line_lower =
new TLine(region.first, ymin_log, region.first, ymax_log);
1377 line_lower->SetLineColor(kMagenta+2);
1378 line_lower->SetLineStyle(2);
1379 line_lower->SetLineWidth(2);
1380 line_lower->Draw(
"same");
1382 TLine *line_upper =
new TLine(region.second, ymin_log, region.second, ymax_log);
1383 line_upper->SetLineColor(kMagenta+2);
1384 line_upper->SetLineStyle(2);
1385 line_upper->SetLineWidth(2);
1386 line_upper->Draw(
"same");
1389 TLegend *legRefLog =
nullptr;
1390 if (hasReferenceDcp && hRefDcpShape) {
1391 TH1D *hRefOverlayLog = (TH1D*)hRefDcpShape->Clone(
"hRefDcpShape_overlay_log");
1392 hRefOverlayLog->SetDirectory(0);
1393 double refIntegral = hRefOverlayLog->Integral();
1394 if (refIntegral > 0) {
1395 hRefOverlayLog->Scale(h1d_delta_cp_log->Integral() / refIntegral);
1397 hRefOverlayLog->SetLineColor(kMagenta + 2);
1398 hRefOverlayLog->SetLineWidth(3);
1399 hRefOverlayLog->SetLineStyle(1);
1400 hRefOverlayLog->SetFillStyle(0);
1401 hRefOverlayLog->Draw(
"HIST SAME");
1403 legRefLog =
new TLegend(0.50, 0.74, 0.88, 0.88);
1404 legRefLog->SetBorderSize(0);
1405 legRefLog->SetFillStyle(0);
1406 legRefLog->AddEntry(h1d_delta_cp_log,
"Umbrella weighted",
"l");
1407 legRefLog->AddEntry(hRefOverlayLog,
"Reference dcp (shape, area-normalized)",
"l");
1410 if (hasReferenceLLH_Dcp && hRefLLH_Dcp) {
1412 TH1D *hLLHResampLog =
new TH1D(
"hRefLLH_dcp_resamp_log",
"", h1d_delta_cp_log->GetNbinsX(), h1d_delta_cp_log->GetXaxis()->GetXmin(), h1d_delta_cp_log->GetXaxis()->GetXmax());
1413 hLLHResampLog->SetDirectory(0);
1414 for (
int i = 1; i <= hLLHResampLog->GetNbinsX(); ++i) {
1415 double xlow = hLLHResampLog->GetBinLowEdge(i);
1416 double xhigh = hLLHResampLog->GetBinLowEdge(i+1);
1418 int nOrig = hRefLLH_Dcp->GetNbinsX();
1419 for (
int k = 1; k <= nOrig; ++k) {
1420 double origLow = hRefLLH_Dcp->GetXaxis()->GetBinLowEdge(k);
1421 double origHigh = origLow + hRefLLH_Dcp->GetBinWidth(k);
1422 double overlap = std::max(0.0, std::min(origHigh, xhigh) - std::max(origLow, xlow));
1423 if (overlap > 0.0) {
1424 double origWidth = hRefLLH_Dcp->GetBinWidth(k);
1425 double contrib = hRefLLH_Dcp->GetBinContent(k) * (overlap / origWidth);
1429 hLLHResampLog->SetBinContent(i, val);
1431 double llhI = hLLHResampLog->Integral();
1432 if (llhI > 0) hLLHResampLog->Scale(h1d_delta_cp_log->Integral() / llhI);
1433 hLLHResampLog->SetLineColor(kBlue + 2);
1434 hLLHResampLog->SetLineWidth(3);
1435 hLLHResampLog->SetLineStyle(2);
1436 hLLHResampLog->SetFillStyle(0);
1437 hLLHResampLog->Draw(
"HIST SAME");
1438 TLegend *legLLHLog =
new TLegend(0.50, 0.60, 0.88, 0.74);
1439 legLLHLog->SetBorderSize(0);
1440 legLLHLog->SetFillStyle(0);
1441 legLLHLog->AddEntry(h1d_delta_cp_log,
"Umbrella weighted",
"l");
1442 legLLHLog->AddEntry(hLLHResampLog,
"LLH scan (resampled & area-normalized)",
"l");
1445 drawAsimovLineWithLegend(asimovDcp, hasReferenceDcp ? legRefLog :
nullptr);
1448 c8->SaveAs((outputDir +
"delta_cp_log_scale_weighted.png").c_str());
1451 TCanvas *c9 =
new TCanvas(
"c9",
"Delta CP Log Scale Marginalized by Ordering", 1800, 700);
1454 std::string ioSelection = hasUmbrellaWeight ?
"(delm2_23 < 0) * umbrella_weight" :
"(delm2_23 < 0)";
1455 std::string noSelection = hasUmbrellaWeight ?
"(delm2_23 > 0) * umbrella_weight" :
"(delm2_23 > 0)";
1460 TH1F *h1d_delta_cp_io_log =
new TH1F(
"h1d_delta_cp_io_log",
"#delta_{CP} marginalized over IO;#delta_{CP};Normalized Entries", nBins_dcp, -3.1415, 3.1415);
1461 tree->Draw(
"delta_cp>>h1d_delta_cp_io_log", ioSelection.c_str(),
"");
1462 normalizeHist(h1d_delta_cp_io_log);
1463 h1d_delta_cp_io_log->SetStats(0);
1464 double ioMinPositive = 1.0;
1465 bool ioFoundPositive =
false;
1466 for (
int b = 1; b <= h1d_delta_cp_io_log->GetNbinsX(); ++b) {
1467 double y = h1d_delta_cp_io_log->GetBinContent(b);
1469 if (!ioFoundPositive || y < ioMinPositive) {
1472 ioFoundPositive =
true;
1475 h1d_delta_cp_io_log->SetMinimum(ioFoundPositive ? 0.5 * ioMinPositive : 1e-8);
1476 h1d_delta_cp_io_log->Draw(
"HIST");
1477 h1d_delta_cp_io_log->Draw(
"E SAME");
1478 drawAsimovLineWithLegend(asimovDcp);
1479 if (hasReferenceLLH_Dcp_IO && hRefLLH_Dcp_IO) {
1480 TH1D *hLLHIO =
new TH1D(
"hRefLLH_dcp_io_resamp",
"", h1d_delta_cp_io_log->GetNbinsX(), h1d_delta_cp_io_log->GetXaxis()->GetXmin(), h1d_delta_cp_io_log->GetXaxis()->GetXmax());
1481 hLLHIO->SetDirectory(0);
1482 for (
int i = 1; i <= hLLHIO->GetNbinsX(); ++i) {
1483 double xlow = hLLHIO->GetBinLowEdge(i);
1484 double xhigh = hLLHIO->GetBinLowEdge(i+1);
1486 int nOrig = hRefLLH_Dcp_IO->GetNbinsX();
1487 for (
int k = 1; k <= nOrig; ++k) {
1488 double origLow = hRefLLH_Dcp_IO->GetXaxis()->GetBinLowEdge(k);
1489 double origHigh = origLow + hRefLLH_Dcp_IO->GetBinWidth(k);
1490 double overlap = std::max(0.0, std::min(origHigh, xhigh) - std::max(origLow, xlow));
1491 if (overlap > 0.0) {
1492 double origWidth = hRefLLH_Dcp_IO->GetBinWidth(k);
1493 double contrib = hRefLLH_Dcp_IO->GetBinContent(k) * (overlap / origWidth);
1497 hLLHIO->SetBinContent(i, val);
1499 double li = hLLHIO->Integral();
1500 if (li > 0) hLLHIO->Scale(h1d_delta_cp_io_log->Integral() / li);
1501 hLLHIO->SetLineColor(kBlue + 2);
1502 hLLHIO->SetLineWidth(2);
1503 hLLHIO->SetLineStyle(2);
1504 hLLHIO->Draw(
"HIST SAME");
1505 TLegend *legLLHIO =
new TLegend(0.50, 0.60, 0.88, 0.74);
1506 legLLHIO->SetBorderSize(0);
1507 legLLHIO->SetFillStyle(0);
1508 legLLHIO->AddEntry(h1d_delta_cp_io_log,
"Umbrella weighted (IO)",
"l");
1509 legLLHIO->AddEntry(hLLHIO,
"LLH scan IO (resampled & area-normalized)",
"l");
1516 TH1F *h1d_delta_cp_no_log =
new TH1F(
"h1d_delta_cp_no_log",
"#delta_{CP} marginalized over NO;#delta_{CP};Normalized Entries", nBins_dcp, -3.1415, 3.1415);
1517 tree->Draw(
"delta_cp>>h1d_delta_cp_no_log", noSelection.c_str(),
"");
1518 normalizeHist(h1d_delta_cp_no_log);
1519 h1d_delta_cp_no_log->SetStats(0);
1520 double noMinPositive = 1.0;
1521 bool noFoundPositive =
false;
1522 for (
int b = 1; b <= h1d_delta_cp_no_log->GetNbinsX(); ++b) {
1523 double y = h1d_delta_cp_no_log->GetBinContent(b);
1525 if (!noFoundPositive || y < noMinPositive) {
1528 noFoundPositive =
true;
1531 h1d_delta_cp_no_log->SetMinimum(noFoundPositive ? 0.5 * noMinPositive : 1e-8);
1532 h1d_delta_cp_no_log->Draw(
"HIST");
1533 h1d_delta_cp_no_log->Draw(
"E SAME");
1534 drawAsimovLineWithLegend(asimovDcp);
1535 if (hasReferenceLLH_Dcp_NO && hRefLLH_Dcp_NO) {
1536 TH1D *hLLHNO =
new TH1D(
"hRefLLH_dcp_no_resamp",
"", h1d_delta_cp_no_log->GetNbinsX(), h1d_delta_cp_no_log->GetXaxis()->GetXmin(), h1d_delta_cp_no_log->GetXaxis()->GetXmax());
1537 hLLHNO->SetDirectory(0);
1538 for (
int i = 1; i <= hLLHNO->GetNbinsX(); ++i) {
1539 double xlow = hLLHNO->GetBinLowEdge(i);
1540 double xhigh = hLLHNO->GetBinLowEdge(i+1);
1542 int nOrig = hRefLLH_Dcp_NO->GetNbinsX();
1543 for (
int k = 1; k <= nOrig; ++k) {
1544 double origLow = hRefLLH_Dcp_NO->GetXaxis()->GetBinLowEdge(k);
1545 double origHigh = origLow + hRefLLH_Dcp_NO->GetBinWidth(k);
1546 double overlap = std::max(0.0, std::min(origHigh, xhigh) - std::max(origLow, xlow));
1547 if (overlap > 0.0) {
1548 double origWidth = hRefLLH_Dcp_NO->GetBinWidth(k);
1549 double contrib = hRefLLH_Dcp_NO->GetBinContent(k) * (overlap / origWidth);
1553 hLLHNO->SetBinContent(i, val);
1555 double ln = hLLHNO->Integral();
1556 if (ln > 0) hLLHNO->Scale(h1d_delta_cp_no_log->Integral() / ln);
1557 hLLHNO->SetLineColor(kBlue + 2);
1558 hLLHNO->SetLineWidth(2);
1559 hLLHNO->SetLineStyle(2);
1560 hLLHNO->Draw(
"HIST SAME");
1561 TLegend *legLLHNO =
new TLegend(0.50, 0.60, 0.88, 0.74);
1562 legLLHNO->SetBorderSize(0);
1563 legLLHNO->SetFillStyle(0);
1564 legLLHNO->AddEntry(h1d_delta_cp_no_log,
"Umbrella weighted (NO)",
"l");
1565 legLLHNO->AddEntry(hLLHNO,
"LLH scan NO (resampled & area-normalized)",
"l");
1570 c9->SaveAs((outputDir +
"delta_cp_log_scale_marginalized_io_no.png").c_str());
1573 const double jarlskogMin = -0.06;
1574 const double jarlskogMax = 0.06;
1575 const int nBinsJarlskog = 160;
1577 TCanvas *c10 =
new TCanvas(
"c10",
"Jarlskog Invariant", 900, 700);
1578 TH1F *h1d_jarlskog_unweighted =
new TH1F(
"h1d_jarlskog_unweighted",
"Jarlskog invariant;Jarlskog invariant;Entries",
1579 nBinsJarlskog, jarlskogMin, jarlskogMax);
1580 tree->Draw(
"TMath::Sqrt(TMath::Max(0.,sin2th_12)*TMath::Max(0.,1.-sin2th_12)*TMath::Max(0.,sin2th_23)*TMath::Max(0.,1.-sin2th_23))*TMath::Max(0.,1.-sin2th_13)*TMath::Sqrt(TMath::Max(0.,sin2th_13))*TMath::Sin(delta_cp)>>h1d_jarlskog_unweighted",
1582 normalizeHist(h1d_jarlskog_unweighted);
1583 h1d_jarlskog_unweighted->SetStats(0);
1584 h1d_jarlskog_unweighted->Draw(
"HIST");
1585 h1d_jarlskog_unweighted->Draw(
"E SAME");
1586 drawAsimovLineWithLegend(asimovJarlskog);
1588 auto computeOneSidedBounds = [&](TH1 *hist,
double targets[3],
double outBounds[3]) {
1591 for (
int i = 0; i < 3; ++i) outBounds[i] = std::numeric_limits<double>::quiet_NaN();
1593 double total = hist->Integral();
1594 if (total <= 0)
return;
1595 int nBins = hist->GetNbinsX();
1597 double leftSum = 0.0;
1598 double rightSum = 0.0;
1599 for (
int b = 1; b <= nBins; ++b) {
1600 double center = hist->GetBinCenter(b);
1601 double c = hist->GetBinContent(b);
1602 if (center < 0) leftSum += c;
else rightSum += c;
1604 bool integrateLeftToRight = (leftSum >= rightSum);
1606 for (
int t = 0; t < 3; ++t) {
1607 double target = targets[t];
1609 if (integrateLeftToRight) {
1610 for (
int b = 1; b <= nBins; ++b) {
1611 cum += hist->GetBinContent(b);
1612 if (cum / total >= target) {
1614 outBounds[t] = hist->GetBinLowEdge(b+1);
1619 if (!std::isfinite(outBounds[t])) outBounds[t] = hist->GetXaxis()->GetXmax();
1621 for (
int b = nBins; b >= 1; --b) {
1622 cum += hist->GetBinContent(b);
1623 if (cum / total >= target) {
1625 outBounds[t] = hist->GetBinLowEdge(b);
1629 if (!std::isfinite(outBounds[t])) outBounds[t] = hist->GetXaxis()->GetXmin();
1633 double hist_ymax = hist->GetMaximum();
1635 int colors[3] = {kOrange+1, kAzure+2, kMagenta+2};
1636 for (
int t = 0; t < 3; ++t) {
1637 if (!std::isfinite(outBounds[t]))
continue;
1638 TLine *line =
nullptr;
1639 if (integrateLeftToRight) {
1641 line =
new TLine(outBounds[t], 0, outBounds[t], hist_ymax);
1644 line =
new TLine(outBounds[t], 0, outBounds[t], hist_ymax);
1646 line->SetLineColor(colors[t]);
1647 line->SetLineStyle(2);
1648 line->SetLineWidth(2);
1654 c10->SaveAs((outputDir +
"jarlskog_unweighted.png").c_str());
1656 TCanvas *c10_log =
new TCanvas(
"c10_log",
"Jarlskog Invariant Log Scale", 900, 700);
1658 TH1F *h1d_jarlskog_unweighted_log = (TH1F*)h1d_jarlskog_unweighted->Clone(
"h1d_jarlskog_unweighted_log");
1659 h1d_jarlskog_unweighted_log->SetTitle(
"Jarlskog invariant (Log Scale);Jarlskog invariant;Entries");
1660 h1d_jarlskog_unweighted_log->Draw(
"HIST");
1661 h1d_jarlskog_unweighted_log->Draw(
"E SAME");
1662 drawAsimovLineWithLegend(asimovJarlskog);
1665 c10_log->SaveAs((outputDir +
"jarlskog_unweighted_log.png").c_str());
1667 TCanvas *c10_weighted =
new TCanvas(
"c10_weighted",
"Jarlskog Invariant Weighted", 900, 700);
1668 TH1F *h1d_jarlskog_weighted =
new TH1F(
"h1d_jarlskog_weighted",
"Jarlskog invariant;Jarlskog invariant;Weighted Entries",
1669 nBinsJarlskog, jarlskogMin, jarlskogMax);
1670 if (hasUmbrellaWeight) {
1671 tree->Draw(
"TMath::Sqrt(TMath::Max(0.,sin2th_12)*TMath::Max(0.,1.-sin2th_12)*TMath::Max(0.,sin2th_23)*TMath::Max(0.,1.-sin2th_23))*TMath::Max(0.,1.-sin2th_13)*TMath::Sqrt(TMath::Max(0.,sin2th_13))*TMath::Sin(delta_cp)>>h1d_jarlskog_weighted",
1672 "umbrella_weight",
"");
1674 tree->Draw(
"TMath::Sqrt(TMath::Max(0.,sin2th_12)*TMath::Max(0.,1.-sin2th_12)*TMath::Max(0.,sin2th_23)*TMath::Max(0.,1.-sin2th_23))*TMath::Max(0.,1.-sin2th_13)*TMath::Sqrt(TMath::Max(0.,sin2th_13))*TMath::Sin(delta_cp)>>h1d_jarlskog_weighted",
1676 std::cout <<
"WARNING:::::No umbrella weights found, plotting unweighted Jarlskog histogram." << std::endl;
1678 normalizeHist(h1d_jarlskog_weighted);
1679 h1d_jarlskog_weighted->SetStats(0);
1680 h1d_jarlskog_weighted->Sumw2();
1681 h1d_jarlskog_weighted->Draw(
"HIST");
1682 h1d_jarlskog_weighted->Draw(
"E SAME");
1683 drawAsimovLineWithLegend(asimovJarlskog);
1685 double targets[3] = {sigma1, sigma3, sigma5};
1687 computeOneSidedBounds(h1d_jarlskog_weighted, targets, bounds);
1689 double ymax_w = h1d_jarlskog_weighted->GetMaximum();
1690 TLine *legLine1 =
nullptr;
1691 TLine *legLine3 =
nullptr;
1692 TLine *legLine5 =
nullptr;
1693 if (std::isfinite(bounds[0])) legLine1 =
new TLine(bounds[0], 0, bounds[0], ymax_w);
1694 if (std::isfinite(bounds[1])) legLine3 =
new TLine(bounds[1], 0, bounds[1], ymax_w);
1695 if (std::isfinite(bounds[2])) legLine5 =
new TLine(bounds[2], 0, bounds[2], ymax_w);
1696 if (legLine1) { legLine1->SetLineColor(kOrange+1); legLine1->SetLineStyle(2); legLine1->SetLineWidth(2); }
1697 if (legLine3) { legLine3->SetLineColor(kAzure+2); legLine3->SetLineStyle(2); legLine3->SetLineWidth(2); }
1698 if (legLine5) { legLine5->SetLineColor(kMagenta+2); legLine5->SetLineStyle(2); legLine5->SetLineWidth(2); }
1699 TLegend *legCI =
new TLegend(0.15, 0.60, 0.50, 0.74);
1700 legCI->SetBorderSize(0);
1701 legCI->SetFillStyle(0);
1702 if (legLine1) legCI->AddEntry(legLine1,
"1 #sigma (one-sided)",
"l");
1703 if (legLine3) legCI->AddEntry(legLine3,
"3 #sigma (one-sided)",
"l");
1704 if (legLine5) legCI->AddEntry(legLine5,
"5 #sigma (one-sided)",
"l");
1706 c10_weighted->Update();
1707 c10_weighted->SaveAs((outputDir +
"jarlskog_weighted.png").c_str());
1709 TCanvas *c10_weighted_log =
new TCanvas(
"c10_weighted_log",
"Jarlskog Invariant Weighted Log Scale", 900, 700);
1710 c10_weighted_log->SetLogy();
1711 TH1F *h1d_jarlskog_weighted_log = (TH1F*)h1d_jarlskog_weighted->Clone(
"h1d_jarlskog_weighted_log");
1712 h1d_jarlskog_weighted_log->SetTitle(
"Jarlskog invariant (Log Scale);Jarlskog invariant;Weighted Entries");
1713 h1d_jarlskog_weighted_log->Draw(
"HIST");
1714 h1d_jarlskog_weighted_log->Draw(
"E SAME");
1715 drawAsimovLineWithLegend(asimovJarlskog);
1717 for (
int t = 0; t < 3; ++t) {
1718 if (!std::isfinite(bounds[t]))
continue;
1719 double hist_ymax = h1d_jarlskog_weighted_log->GetMaximum();
1720 int colors_log[3] = {kOrange+1, kAzure+2, kMagenta+2};
1721 TLine *line =
new TLine(bounds[t], 0, bounds[t], hist_ymax);
1722 line->SetLineColor(colors_log[t]);
1723 line->SetLineStyle(2);
1724 line->SetLineWidth(2);
1728 TLegend *legCI_log =
new TLegend(0.15, 0.60, 0.50, 0.74);
1729 legCI_log->SetBorderSize(0);
1730 legCI_log->SetFillStyle(0);
1731 if (legLine1) legCI_log->AddEntry(legLine1,
"1 #sigma (one-sided)",
"l");
1732 if (legLine3) legCI_log->AddEntry(legLine3,
"3 #sigma (one-sided)",
"l");
1733 if (legLine5) legCI_log->AddEntry(legLine5,
"5 #sigma (one-sided)",
"l");
1735 c10_weighted_log->Update();
1736 c10_weighted_log->SaveAs((outputDir +
"jarlskog_weighted_log.png").c_str());
1738 struct TriangleVar {
1748 std::vector<TriangleVar> triangleVars = {
1749 {
"delta_cp",
"#delta_{CP}",
"delta_cp", nBins_dcp, -3.1415, 3.1415, asimovDcp},
1750 {
"sin2th_23",
"sin^{2}(#theta_{23})",
"sin2th_23", nBins_sin2th23, sin2th23_min, sin2th23_max, asimovSin2th23},
1751 {
"sin2th_13",
"sin^{2}(#theta_{13})",
"sin2th_13", nBins_sin2th13, sin2th13_min, sin2th13_max, asimovSin2th13},
1752 {
"sin2th_12",
"sin^{2}(#theta_{12})",
"sin2th_12", nBins_sin2th12, sin2th12_min, sin2th12_max, asimovSin2th12},
1753 {
"delm2_23",
"#Delta m_{23}^{2} (eV^{2})",
"delm2_23", nBins_delm23, delm23_io_min, delm23_no_max, asimovDelm23},
1754 {
"delm2_12",
"#Delta m_{12}^{2} (eV^{2})",
"delm2_12", nBins_delm12, delm12_min, delm12_max, asimovDelm12}
1757 auto drawAsimovLineNoLegend = [&](
double xValue) {
1758 if (!isAsimovChain || !std::isfinite(xValue) || !gPad)
return;
1760 const double yMin = gPad->GetUymin();
1761 const double yMax = gPad->GetUymax();
1762 TLine *asimovLine =
new TLine(xValue, yMin, xValue, yMax);
1763 asimovLine->SetLineColor(kBlack);
1764 asimovLine->SetLineStyle(3);
1765 asimovLine->SetLineWidth(2);
1766 asimovLine->Draw(
"SAME");
1769 auto drawAsimovMarkerNoLegend = [&](
double xValue,
double yValue) {
1770 if (!isAsimovChain || !std::isfinite(xValue) || !std::isfinite(yValue) || !gPad)
return;
1772 const double xMin = gPad->GetUxmin();
1773 const double xMax = gPad->GetUxmax();
1774 const double yMin = gPad->GetUymin();
1775 const double yMax = gPad->GetUymax();
1776 const double dx = 0.012 * (xMax - xMin);
1777 const double dy = 0.012 * (yMax - yMin);
1779 TLine *l1 =
new TLine(xValue - dx, yValue - dy, xValue + dx, yValue + dy);
1780 l1->SetLineColor(kRed);
1781 l1->SetLineWidth(2);
1784 TLine *l2 =
new TLine(xValue - dx, yValue + dy, xValue + dx, yValue - dy);
1785 l2->SetLineColor(kRed);
1786 l2->SetLineWidth(2);
1790 auto drawTrianglePlot = [&](
const std::string &weightExpr,
const std::string &suffix,
int mo = 0) {
1792 std::cout <<
"Drawing triangle plot for IO" << std::endl;
1793 triangleVars[4].min = delm23_no_min;
1794 triangleVars[4].max = delm23_no_max;
1795 }
else if (mo == -1) {
1796 std::cout <<
"Drawing triangle plot for NO" << std::endl;
1797 triangleVars[4].min = delm23_io_min;
1798 triangleVars[4].max = delm23_io_max;
1800 std::cout <<
"Drawing triangle plot for both MO" << std::endl;
1803 const int nVars =
static_cast<int>(triangleVars.size());
1804 TCanvas *cTri =
new TCanvas((
"c_triangle" + suffix).c_str(),
"Triangle Plot", 1400, 1400);
1805 cTri->SetFillStyle(0);
1809 const double TPm[4] = {.07, .07, .05, .05};
1810 const double Pm[2] = {.2, .1};
1812 const double TPw = 1.0 - TPm[0] - TPm[2];
1813 const double a_x = (Pm[0] * TPw) / (1.0 * nVars + Pm[0] * (1.0 - 1.0 * nVars));
1814 const double b_x = (TPw - a_x) / (1.0 * nVars);
1816 std::vector<double> X_Min(nVars), X_Max(nVars);
1818 X_Max[0] = X_Min[0] + a_x + b_x;
1819 for (
int i = 1; i < nVars; ++i) {
1820 X_Min[i] = X_Max[i - 1];
1821 X_Max[i] = X_Min[i] + b_x;
1824 const double TPh = 1.0 - TPm[1] - TPm[3];
1825 const double a_y = (Pm[1] * TPh) / (1.0 * nVars + Pm[1] * (1.0 - 1.0 * nVars));
1826 const double b_y = (TPh - a_y) / (1.0 * nVars);
1828 std::vector<double> Y_Min(nVars), Y_Max(nVars);
1829 Y_Min[nVars - 1] = TPm[1];
1830 Y_Max[nVars - 1] = Y_Min[nVars - 1] + a_y + b_y;
1831 for (
int i = nVars - 2; i >= 0; --i) {
1832 Y_Min[i] = Y_Max[i + 1];
1833 Y_Max[i] = Y_Min[i] + b_y;
1836 for (
int row = 0; row < nVars; ++row) {
1837 for (
int col = 0; col <= row; ++col) {
1838 const double x1 = X_Min[col];
1839 const double x2 = X_Max[col];
1840 const double y1 = Y_Min[row];
1841 const double y2 = Y_Max[row];
1843 TPad *pad =
new TPad(Form(
"tri_pad_%s_%d_%d", suffix.c_str(), row, col),
"", x1, y1, x2, y2);
1844 pad->SetFillStyle(0);
1845 pad->SetRightMargin(0.02);
1846 pad->SetTopMargin(0.02);
1847 pad->SetLeftMargin(col == 0 ? 0.26 : 0.06);
1848 pad->SetBottomMargin(row == nVars - 1 ? 0.18 : 0.06);
1852 const TriangleVar &xVar = triangleVars[col];
1853 const TriangleVar &yVar = triangleVars[row];
1856 TH1F *h1 =
new TH1F(Form(
"h_tri_1d_%s_%s", suffix.c_str(), xVar.name.c_str()),
1857 "", xVar.bins, xVar.min, xVar.max);
1858 std::string drawExpr = xVar.branch +
">>" + h1->GetName();
1859 tree->Draw(drawExpr.c_str(), weightExpr.c_str(),
"goff");
1862 h1->GetXaxis()->SetTitle(row == nVars - 1 ? xVar.title.c_str() :
"");
1863 h1->GetYaxis()->SetTitle(col == 0 ?
"Entries" :
"");
1864 h1->GetXaxis()->SetLabelSize(row == nVars - 1 ? 0.07 : 0.0);
1865 h1->GetYaxis()->SetLabelSize(col == 0 ? 0.07 : 0.0);
1866 h1->GetXaxis()->SetTitleSize(row == nVars - 1 ? 0.08 : 0.0);
1867 h1->GetYaxis()->SetTitleSize(col == 0 ? 0.08 : 0.0);
1870 drawAsimovLineNoLegend(xVar.asimov);
1872 TH2F *h2 =
new TH2F(Form(
"h_tri_2d_%s_%s_%s", suffix.c_str(), yVar.name.c_str(), xVar.name.c_str()),
1873 "", xVar.bins, xVar.min, xVar.max, yVar.bins, yVar.min, yVar.max);
1874 std::string drawExpr = yVar.branch +
":" + xVar.branch +
">>" + h2->GetName();
1875 tree->Draw(drawExpr.c_str(), weightExpr.c_str(),
"goff");
1878 h2->GetXaxis()->SetTitle(row == nVars - 1 ? xVar.title.c_str() :
"");
1879 h2->GetYaxis()->SetTitle(col == 0 ? yVar.title.c_str() :
"");
1880 h2->GetXaxis()->SetLabelSize(row == nVars - 1 ? 0.07 : 0.0);
1881 h2->GetYaxis()->SetLabelSize(col == 0 ? 0.07 : 0.0);
1882 h2->GetXaxis()->SetTitleSize(row == nVars - 1 ? 0.08 : 0.0);
1883 h2->GetYaxis()->SetTitleSize(col == 0 ? 0.08 : 0.0);
1885 drawAsimovMarkerNoLegend(xVar.asimov, yVar.asimov);
1893 cTri->SaveAs((outputDir +
"triangle" + suffix +
".png").c_str());
1896 drawTrianglePlot(
"",
"_unweighted", 0);
1897 if (hasUmbrellaWeight) {
1898 drawTrianglePlot(
"umbrella_weight",
"_weighted", 0);
1900 std::cout <<
"WARNING:::::No umbrella weights found, skipping weighted triangle plot." << std::endl;
1903 drawTrianglePlot(
"(delm2_23 < 0)",
"_io_unweighted",-1);
1904 drawTrianglePlot(
"(delm2_23 > 0)",
"_no_unweighted",1);
1905 if (hasUmbrellaWeight) {
1906 drawTrianglePlot(
"(delm2_23 < 0) * umbrella_weight",
"_io_weighted",-1);
1907 drawTrianglePlot(
"(delm2_23 > 0) * umbrella_weight",
"_no_weighted",1);
1909 std::cout <<
"WARNING:::::No umbrella weights found, skipping weighted triangle plots marginalized by ordering." << std::endl;
TFile * Open(const std::string &Name, const std::string &Type, const std::string &File, const int Line)
Opens a ROOT file with the given name and mode.