29 int nBins_sin2th23 = 100;
30 int nBins_sin2th13 = 100;
31 int nBins_sin2th12 = 100;
32 int nBins_delm23 = 3000;
33 int nBins_delm12 = 100;
36 double sin2th23_min = 0.45;
37 double sin2th23_max = 0.57;
38 double sin2th13_min = 0.015;
39 double sin2th13_max = 0.03;
40 double sin2th12_min = 0.24;
41 double sin2th12_max = 0.36;
42 double delm23_no_min = 0.00245;
43 double delm23_no_max = 0.0026;
44 double delm23_io_min = -delm23_no_max;
45 double delm23_io_max = -delm23_no_min;
46 double delm12_min = 6.5e-5;
47 double delm12_max = 8.5e-5;
49 auto normalizeHist = [&](TH1 *h) {
51 double integral = h->Integral();
52 if (integral > 0.0) h->Scale(1.0 / integral);
55 auto printHistStats = [&](
const std::string &label, TH1 *h) {
57 std::cout <<
"[DEBUG] " << label <<
" : histogram is null" << std::endl;
60 std::cout << std::fixed << std::setprecision(6)
61 <<
"[DEBUG] " << label
62 <<
" entries=" << h->GetEntries()
63 <<
" effEntries=" << h->GetEffectiveEntries()
64 <<
" integral=" << h->Integral()
65 <<
" mean=" << h->GetMean()
66 <<
" rms=" << h->GetRMS()
78 bool use_reference_chain =
false;
79 bool use_reference_LLH_scan =
true;
81 double asimovSin2th12 = std::numeric_limits<double>::quiet_NaN();
82 double asimovSin2th23 = std::numeric_limits<double>::quiet_NaN();
83 double asimovSin2th13 = std::numeric_limits<double>::quiet_NaN();
84 double asimovDelm12 = std::numeric_limits<double>::quiet_NaN();
85 double asimovDelm23 = std::numeric_limits<double>::quiet_NaN();
86 double asimovDcp = std::numeric_limits<double>::quiet_NaN();
87 double asimovBaseline = std::numeric_limits<double>::quiet_NaN();
88 double asimovElectronDensity = std::numeric_limits<double>::quiet_NaN();
91 std::string referenceFile =
"";
92 std::string referenceTreeName =
"";
94 if(use_reference_chain) {
95 referenceFile =
"/home/driley/projects/def-blairt2k/driley/T2K_outputs/umbrella_testing/fixing_params/allfixed/all_oscParams_fixed_hadded.root";
96 referenceTreeName =
"posteriors";
100 std::string referenceLLHScanFile =
"";
101 std::string referenceLLHScanDcpHistName =
"";
102 std::string referenceLLHScanDcp_NO_histName =
"";
103 std::string referenceLLHScanDcp_IO_histName =
"";
105 if(use_reference_LLH_scan) {
106 referenceLLHScanFile =
"/home/driley/Projects-T2K-MaCh3/umbrella_t2k/mcm_utils/target_1D_histos.root";
107 referenceLLHScanDcpHistName =
"dcp";
108 referenceLLHScanDcp_NO_histName =
"dcp_NO";
109 referenceLLHScanDcp_IO_histName =
"dcp_IO";
113 if (!f || f->IsZombie()) {
114 std::cerr <<
"Error: Cannot open file!" << std::endl;
119 TTree *tree = (TTree*)f->Get(
"posteriors");
121 std::cerr <<
"Error: Cannot find tree!" << std::endl;
127 bool isAsimovChain =
false;
129 auto calculateJarlskog = [&](
double sin2th12,
double sin2th23,
double sin2th13,
double dcp) {
130 if (!std::isfinite(sin2th12) || !std::isfinite(sin2th23) || !std::isfinite(sin2th13) || !std::isfinite(dcp)) {
131 return std::numeric_limits<double>::quiet_NaN();
133 return std::sqrt(std::max(0.0, sin2th12) * std::max(0.0, 1.0 - sin2th12) *
134 std::max(0.0, sin2th23) * std::max(0.0, 1.0 - sin2th23)) *
135 std::max(0.0, 1.0 - sin2th13) * std::sqrt(std::max(0.0, sin2th13)) *
139 const double asimovJarlskog = calculateJarlskog(asimovSin2th12, asimovSin2th23, asimovSin2th13, asimovDcp);
141 auto drawAsimovLineWithLegend = [&](
double xValue, TLegend *existingLegend =
nullptr) {
142 if (!isAsimovChain || !std::isfinite(xValue) || !gPad)
return;
144 const double yMin = gPad->GetUymin();
145 const double yMax = gPad->GetUymax();
146 TLine *asimovLine =
new TLine(xValue, yMin, xValue, yMax);
147 asimovLine->SetLineColor(kBlack);
148 asimovLine->SetLineStyle(3);
149 asimovLine->SetLineWidth(2);
150 asimovLine->Draw(
"SAME");
152 if (existingLegend) {
153 existingLegend->AddEntry(asimovLine,
"Asimov point",
"l");
154 existingLegend->Draw();
156 TLegend *asimovLegend =
new TLegend(0.14, 0.83, 0.34, 0.91);
157 asimovLegend->SetBorderSize(0);
158 asimovLegend->SetFillStyle(0);
159 asimovLegend->AddEntry(asimovLine,
"Asimov point",
"l");
160 asimovLegend->Draw();
164 auto drawAsimovMarkerWithLegend = [&](
double xValue,
double yValue, TLegend *existingLegend =
nullptr) {
165 if (!isAsimovChain || !std::isfinite(xValue) || !std::isfinite(yValue) || !gPad)
return;
168 const double xMin = gPad->GetUxmin();
169 const double xMax = gPad->GetUxmax();
170 const double yMin = gPad->GetUymin();
171 const double yMax = gPad->GetUymax();
172 const double dx = 0.012 * (xMax - xMin);
173 const double dy = 0.012 * (yMax - yMin);
175 TLine *l1 =
new TLine(xValue - dx, yValue - dy, xValue + dx, yValue + dy);
176 l1->SetLineColor(kRed);
180 TLine *l2 =
new TLine(xValue - dx, yValue + dy, xValue + dx, yValue - dy);
181 l2->SetLineColor(kRed);
185 if (existingLegend) {
186 existingLegend->AddEntry(l1,
"Asimov point",
"l");
187 existingLegend->Draw();
189 TLegend *lm =
new TLegend(0.14, 0.83, 0.34, 0.91);
190 lm->SetBorderSize(0);
192 lm->AddEntry(l1,
"Asimov point",
"l");
199 bool hasReferenceDcp =
false;
200 bool hasReferenceSin2Th23 =
false;
201 bool hasReferenceDelm23 =
false;
202 TH1D *hRefDcpShape =
nullptr;
203 TH1D *hRefSin2Th23Shape =
nullptr;
204 TH1D *hRefDelm23Shape =
nullptr;
206 if (!fRef || fRef->IsZombie()) {
207 std::cerr <<
"Warning: Cannot open reference file: " << referenceFile << std::endl;
209 TTree *refTree = (TTree*)fRef->Get(referenceTreeName.c_str());
211 std::cerr <<
"Warning: Cannot find reference tree: " << referenceTreeName << std::endl;
212 }
else if (!refTree->GetBranch(
"dcp") && !refTree->GetBranch(
"delta_cp")) {
213 std::cerr <<
"Warning: dcp branch not found in reference tree." << std::endl;
214 }
else if (refTree->GetBranch(
"delta_cp")) {
215 hRefDcpShape =
new TH1D(
"hRefDcpShape",
"", nBins_dcp, -3.1415, 3.1415);
216 refTree->Draw(
"delta_cp>>hRefDcpShape",
"",
"goff");
217 hRefDcpShape->SetDirectory(0);
218 hasReferenceDcp =
true;
219 std::cout <<
"Loaded reference dcp histogram from " << referenceTreeName << std::endl;
221 hRefDcpShape =
new TH1D(
"hRefDcpShape",
"", nBins_dcp, -3.1415, 3.1415);
222 refTree->Draw(
"dcp>>hRefDcpShape",
"",
"goff");
223 hRefDcpShape->SetDirectory(0);
224 hasReferenceDcp =
true;
225 std::cout <<
"Loaded reference dcp histogram from " << referenceTreeName << std::endl;
228 if (!refTree->GetBranch(
"theta23") && !refTree->GetBranch(
"sin2th_23")) {
229 std::cerr <<
"Warning: theta23 branch not found in reference tree." << std::endl;
230 }
else if (refTree->GetBranch(
"sin2th_23")) {
231 hRefSin2Th23Shape =
new TH1D(
"hRefSin2Th23Shape",
"", nBins_sin2th23, sin2th23_min, sin2th23_max);
232 refTree->Draw(
"sin2th_23>>hRefSin2Th23Shape",
"",
"goff");
233 hRefSin2Th23Shape->SetDirectory(0);
234 hasReferenceSin2Th23 =
true;
235 std::cout <<
"Loaded reference sin^{2}(theta23) histogram from " << referenceTreeName << std::endl;
238 hRefSin2Th23Shape =
new TH1D(
"hRefSin2Th23Shape",
"", nBins_sin2th23, sin2th23_min, sin2th23_max);
239 refTree->Draw(
"theta23>>hRefSin2Th23Shape",
"",
"goff");
240 hRefSin2Th23Shape->SetDirectory(0);
241 hasReferenceSin2Th23 =
true;
242 std::cout <<
"Loaded reference sin^{2}(theta23) histogram from " << referenceTreeName << std::endl;
245 if (!refTree->GetBranch(
"dm23") && !refTree->GetBranch(
"delm2_23")) {
246 std::cerr <<
"Warning: dm23 branch not found in reference tree." << std::endl;
247 }
else if (refTree->GetBranch(
"delm2_23")) {
248 hRefDelm23Shape =
new TH1D(
"hRefDelm23Shape",
"", nBins_delm23, delm23_io_min, delm23_no_max);
249 refTree->Draw(
"delm2_23>>hRefDelm23Shape",
"",
"goff");
250 TH1D *hRefDelm23IO_dbg =
new TH1D(
"hRefDelm23IO_dbg",
"", nBins_delm23, delm23_io_min, delm23_io_max);
251 TH1D *hRefDelm23NO_dbg =
new TH1D(
"hRefDelm23NO_dbg",
"", nBins_delm23, delm23_no_min, delm23_no_max);
252 refTree->Draw(
"delm2_23>>hRefDelm23IO_dbg",
"delm2_23 < 0",
"goff");
253 refTree->Draw(
"delm2_23>>hRefDelm23NO_dbg",
"delm2_23 > 0",
"goff");
254 printHistStats(
"Reference delm23 IO (raw)", hRefDelm23IO_dbg);
255 printHistStats(
"Reference delm23 NO (raw)", hRefDelm23NO_dbg);
256 hRefDelm23Shape->SetDirectory(0);
257 normalizeHist(hRefDelm23Shape);
258 hasReferenceDelm23 =
true;
259 std::cout <<
"Loaded reference delm23 histogram from " << referenceTreeName << std::endl;
261 hRefDelm23Shape =
new TH1D(
"hRefDelm23Shape",
"", nBins_delm23, delm23_io_min, delm23_no_max);
262 refTree->Draw(
"dm23>>hRefDelm23Shape",
"",
"goff");
263 TH1D *hRefDm23IO_dbg =
new TH1D(
"hRefDm23IO_dbg",
"", nBins_delm23, delm23_io_min, delm23_io_max);
264 TH1D *hRefDm23NO_dbg =
new TH1D(
"hRefDm23NO_dbg",
"", nBins_delm23, delm23_no_min, delm23_no_max);
265 refTree->Draw(
"dm23>>hRefDm23IO_dbg",
"dm23 < 0",
"goff");
266 refTree->Draw(
"dm23>>hRefDm23NO_dbg",
"dm23 > 0",
"goff");
267 printHistStats(
"Reference dm23 IO (raw)", hRefDm23IO_dbg);
268 printHistStats(
"Reference dm23 NO (raw)", hRefDm23NO_dbg);
269 hRefDelm23Shape->SetDirectory(0);
270 normalizeHist(hRefDelm23Shape);
271 hasReferenceDelm23 =
true;
272 std::cout <<
"Loaded reference dm23 histograms from " << referenceTreeName << std::endl;
280 bool hasReferenceLLH_Dcp =
false;
281 bool hasReferenceLLH_Dcp_NO =
false;
282 bool hasReferenceLLH_Dcp_IO =
false;
283 TH1D *hRefLLH_Dcp =
nullptr;
284 TH1D *hRefLLH_Dcp_NO =
nullptr;
285 TH1D *hRefLLH_Dcp_IO =
nullptr;
287 if (use_reference_LLH_scan && !referenceLLHScanFile.empty()) {
288 TFile *fLLH =
TFile::Open(referenceLLHScanFile.c_str());
289 if (!fLLH || fLLH->IsZombie()) {
290 std::cerr <<
"Warning: Cannot open reference LLH-scan file: " << referenceLLHScanFile << std::endl;
293 auto loadAndNormalize1D = [&](
const std::string &name, TH1D *&outHist,
bool &outFlag) {
294 TObject *obj = fLLH->Get(name.c_str());
296 std::cerr <<
"Warning: LLH-scan histogram '" << name <<
"' not found in " << referenceLLHScanFile << std::endl;
299 TH1 *htmp =
dynamic_cast<TH1*
>(obj);
301 std::cerr <<
"Warning: Object '" << name <<
"' is not a histogram." << std::endl;
304 outHist = (TH1D*)htmp->Clone((std::string(
"hRefLLH_") + name +
"_clone").c_str());
305 outHist->SetDirectory(0);
307 double I = outHist->Integral();
308 if (I > 0) outHist->Scale(1.0 / I);
310 printHistStats(std::string(
"Reference LLH ") + name, outHist);
313 if (!referenceLLHScanDcpHistName.empty()) loadAndNormalize1D(referenceLLHScanDcpHistName, hRefLLH_Dcp, hasReferenceLLH_Dcp);
314 if (!referenceLLHScanDcp_NO_histName.empty()) loadAndNormalize1D(referenceLLHScanDcp_NO_histName, hRefLLH_Dcp_NO, hasReferenceLLH_Dcp_NO);
315 if (!referenceLLHScanDcp_IO_histName.empty()) loadAndNormalize1D(referenceLLHScanDcp_IO_histName, hRefLLH_Dcp_IO, hasReferenceLLH_Dcp_IO);
321 bool hasUmbrellaWeight =
false;
323 if (!tree->GetBranch(
"umbrella_weight")) {
324 std::cerr <<
"Warning: umbrella_weight branch not found, plotting as unweighted umbrella" << std::endl;
326 hasUmbrellaWeight =
true;
331 std::cout <<
"[DEBUG] Chain entries total=" << tree->GetEntries() << std::endl;
332 TH1D *hChainDelm23IO_dbg =
new TH1D(
"hChainDelm23IO_dbg",
"", nBins_delm23, delm23_io_min, delm23_io_max);
333 TH1D *hChainDelm23NO_dbg =
new TH1D(
"hChainDelm23NO_dbg",
"", nBins_delm23, delm23_no_min, delm23_no_max);
334 tree->Draw(
"delm2_23>>hChainDelm23IO_dbg",
"delm2_23 < 0",
"goff");
335 tree->Draw(
"delm2_23>>hChainDelm23NO_dbg",
"delm2_23 > 0",
"goff");
336 printHistStats(
"Chain delm23 IO (raw)", hChainDelm23IO_dbg);
337 printHistStats(
"Chain delm23 NO (raw)", hChainDelm23NO_dbg);
339 if (hasUmbrellaWeight) {
340 TH1D *hChainDelm23IO_w_dbg =
new TH1D(
"hChainDelm23IO_w_dbg",
"", nBins_delm23, delm23_io_min, delm23_io_max);
341 TH1D *hChainDelm23NO_w_dbg =
new TH1D(
"hChainDelm23NO_w_dbg",
"", nBins_delm23, delm23_no_min, delm23_no_max);
342 tree->Draw(
"delm2_23>>hChainDelm23IO_w_dbg",
"(delm2_23 < 0) * umbrella_weight",
"goff");
343 tree->Draw(
"delm2_23>>hChainDelm23NO_w_dbg",
"(delm2_23 > 0) * umbrella_weight",
"goff");
344 printHistStats(
"Chain delm23 IO (weighted)", hChainDelm23IO_w_dbg);
345 printHistStats(
"Chain delm23 NO (weighted)", hChainDelm23NO_w_dbg);
349 TCanvas *c1 =
new TCanvas(
"c1",
"Delta CP vs Delta m23", 900, 700);
350 c1->SetRightMargin(0.15);
352 TH2F *h2d =
new TH2F(
"h2d",
"#Delta m_{23}^{2} vs #delta_{CP};#delta_{CP};#Delta m_{23}^{2} (eV^{2})",
353 nBins_dcp, -3.14159, 3.14159,
354 nBins_delm23, delm23_io_min, delm23_no_max);
356 tree->Draw(
"delm2_23:delta_cp>>h2d",
"",
"COLZ");
361 h2d->GetXaxis()->SetTitle(
"#delta_{CP}");
362 h2d->GetYaxis()->SetTitle(
"#Delta m_{23}^{2} (eV^{2})");
363 h2d->GetZaxis()->SetTitle(
"Normalized Entries");
367 drawAsimovMarkerWithLegend(asimovDcp, asimovDelm23,
nullptr);
368 c1->SaveAs((outputDir +
"delm23_vs_dcp.png").c_str());
370 if (hasUmbrellaWeight){
371 tree->Draw(
"delm2_23:delta_cp>>h2d",
"umbrella_weight",
"COLZ");
375 drawAsimovMarkerWithLegend(asimovDcp, asimovDelm23,
nullptr);
376 c1->SaveAs((outputDir +
"delm23_vs_dcp_weighted.png").c_str());
381 TCanvas *c2 =
new TCanvas(
"c2",
"Delta m23 IO and NO", 1800, 700);
386 gPad->SetRightMargin(0.15);
388 TH2F *h2d_IO =
new TH2F(
"h2d_IO",
"Inverted Ordering;#Delta m_{23}^{2} (eV^{2});#delta_{CP}",
389 nBins_delm23, delm23_io_min, delm23_io_max,
390 nBins_dcp, -3.1415, 3.1415);
392 tree->Draw(
"delta_cp:delm2_23>>h2d_IO",
"delm2_23 < 0",
"COLZ");
393 normalizeHist(h2d_IO);
394 h2d_IO->Draw(
"COLZ");
397 h2d_IO->GetXaxis()->SetTitle(
"#Delta m_{23}^{2} (eV^{2})");
398 h2d_IO->GetYaxis()->SetTitle(
"#delta_{CP} / #pi");
399 h2d_IO->GetZaxis()->SetTitle(
"Normalized Entries");
404 gPad->SetRightMargin(0.15);
406 TH2F *h2d_NO =
new TH2F(
"h2d_NO",
"Normal Ordering;#Delta m_{23}^{2} (eV^{2});#delta_{CP}",
407 nBins_delm23, delm23_no_min, delm23_no_max,
408 nBins_dcp, -3.1415, 3.1415);
410 tree->Draw(
"delta_cp:delm2_23>>h2d_NO",
"delm2_23 > 0",
"COLZ");
411 normalizeHist(h2d_NO);
412 h2d_NO->Draw(
"COLZ");
415 h2d_NO->GetXaxis()->SetTitle(
"#Delta m_{23}^{2} (eV^{2})");
416 h2d_NO->GetYaxis()->SetTitle(
"#delta_{CP} / #pi");
417 h2d_NO->GetZaxis()->SetTitle(
"Normalized Entries");
423 drawAsimovMarkerWithLegend(asimovDelm23, asimovDcp,
nullptr);
425 drawAsimovMarkerWithLegend(asimovDelm23, asimovDcp,
nullptr);
427 c2->SaveAs((outputDir +
"delm23_vs_dcp_IO_NO.png").c_str());
429 if (hasUmbrellaWeight){
432 tree->Draw(
"delta_cp:delm2_23>>h2d_IO",
"(delm2_23 < 0) * umbrella_weight",
"COLZ");
433 normalizeHist(h2d_IO);
434 h2d_IO->Draw(
"COLZ");
438 tree->Draw(
"delta_cp:delm2_23>>h2d_NO",
"(delm2_23 > 0) * umbrella_weight",
"COLZ");
439 normalizeHist(h2d_NO);
440 h2d_NO->Draw(
"COLZ");
445 drawAsimovMarkerWithLegend(asimovDelm23, asimovDcp,
nullptr);
447 drawAsimovMarkerWithLegend(asimovDelm23, asimovDcp,
nullptr);
449 c2->SaveAs((outputDir +
"delm23_vs_dcp_IO_NO_weighted.png").c_str());
453 auto calculateHPDLevel = [](TH2F *hist,
double confidenceLevel) ->
double {
454 std::vector<double> binContents;
455 for (
int i = 1; i <= hist->GetNbinsX(); ++i) {
456 for (
int j = 1; j <= hist->GetNbinsY(); ++j) {
457 double content = hist->GetBinContent(i, j);
459 binContents.push_back(content);
464 if (binContents.empty())
return 0.0;
466 std::sort(binContents.rbegin(), binContents.rend());
469 for (
double val : binContents) totalSum += val;
471 double targetSum = confidenceLevel * totalSum;
472 double runningSum = 0;
474 for (
double val : binContents) {
476 if (runningSum >= targetSum) {
480 return binContents.back();
484 auto createWrappedHistogram = [](TH2F *originalHist,
const std::string &name) -> TH2F* {
485 int nBinsX = originalHist->GetNbinsX();
486 int nBinsY = originalHist->GetNbinsY();
488 double xMin = originalHist->GetXaxis()->GetBinLowEdge(1);
489 double xMax = originalHist->GetXaxis()->GetBinUpEdge(nBinsX);
490 double yMin = originalHist->GetYaxis()->GetBinLowEdge(1);
491 double yMax = originalHist->GetYaxis()->GetBinUpEdge(nBinsY);
492 double yRange = yMax - yMin;
495 TH2F *wrapped =
new TH2F(name.c_str(),
"",
497 nBinsY * 3, yMin - yRange, yMax + yRange);
498 wrapped->SetDirectory(0);
501 for (
int i = 1; i <= nBinsX; ++i) {
502 for (
int j = 1; j <= nBinsY; ++j) {
503 double content = originalHist->GetBinContent(i, j);
505 wrapped->SetBinContent(i, j + nBinsY, content);
507 wrapped->SetBinContent(i, j, content);
509 wrapped->SetBinContent(i, j + 2*nBinsY, content);
517 auto computeOneSidedBoundsValues = [&](TH1 *hist,
double targets[3],
double outBounds[3],
bool &integrateLeftToRight) {
518 for (
int i = 0; i < 3; ++i) outBounds[i] = std::numeric_limits<double>::quiet_NaN();
519 integrateLeftToRight =
true;
521 double total = hist->Integral();
522 if (total <= 0)
return;
523 int nBins = hist->GetNbinsX();
524 double leftSum = 0.0;
525 double rightSum = 0.0;
526 for (
int b = 1; b <= nBins; ++b) {
527 double center = hist->GetBinCenter(b);
528 double c = hist->GetBinContent(b);
529 if (center < 0) leftSum += c;
else rightSum += c;
531 integrateLeftToRight = (leftSum >= rightSum);
533 for (
int t = 0; t < 3; ++t) {
534 double target = targets[t];
536 if (integrateLeftToRight) {
537 for (
int b = 1; b <= nBins; ++b) {
538 cum += hist->GetBinContent(b);
539 if (cum / total >= target) {
540 outBounds[t] = hist->GetBinLowEdge(b+1);
544 if (!std::isfinite(outBounds[t])) outBounds[t] = hist->GetXaxis()->GetXmax();
546 for (
int b = nBins; b >= 1; --b) {
547 cum += hist->GetBinContent(b);
548 if (cum / total >= target) {
549 outBounds[t] = hist->GetBinLowEdge(b);
553 if (!std::isfinite(outBounds[t])) outBounds[t] = hist->GetXaxis()->GetXmin();
558 auto drawAbsDelm23Overlay = [&](
const std::string &suffix,
559 const std::string &ioSelection,
560 const std::string &noSelection) {
561 const int nBinsAbsDelm23 = 80;
562 const int nBinsAbsDcp = 60;
565 gStyle->SetPalette(kGreyScale);
566 TColor::InvertPalette();
568 TCanvas *cAbs =
new TCanvas((
"c_abs_" + suffix).c_str(),
"Delta m23 magnitude overlay", 900, 700);
569 cAbs->SetRightMargin(0.15);
570 cAbs->SetLeftMargin(0.12);
571 cAbs->SetBottomMargin(0.12);
573 TH2F *hAbsFrame =
new TH2F((
"hAbsFrame_" + suffix).c_str(),
574 "|#Delta m_{23}^{2}| vs #delta_{CP};|#Delta m_{23}^{2}| (eV^{2});#delta_{CP} / #pi",
575 nBinsAbsDelm23, delm23_no_min, delm23_no_max,
576 nBinsAbsDcp, -3.1415, 3.1415);
577 hAbsFrame->SetStats(0);
580 TH2F *hAbsIO =
new TH2F((
"hAbsIO_" + suffix).c_str(),
"",
581 nBinsAbsDelm23, delm23_no_min, delm23_no_max,
582 nBinsAbsDcp, -3.1415, 3.1415);
583 TH2F *hAbsNO =
new TH2F((
"hAbsNO_" + suffix).c_str(),
"",
584 nBinsAbsDelm23, delm23_no_min, delm23_no_max,
585 nBinsAbsDcp, -3.1415, 3.1415);
587 std::string ioDrawExpr = std::string(
"delta_cp:TMath::Abs(delm2_23)>>") + hAbsIO->GetName();
588 std::string noDrawExpr = std::string(
"delta_cp:TMath::Abs(delm2_23)>>") + hAbsNO->GetName();
589 tree->Draw(ioDrawExpr.c_str(), ioSelection.c_str(),
"goff");
590 tree->Draw(noDrawExpr.c_str(), noSelection.c_str(),
"goff");
592 hAbsIO->SetDirectory(0);
593 hAbsNO->SetDirectory(0);
594 printHistStats(
"Abs delm23 IO", hAbsIO);
595 printHistStats(
"Abs delm23 NO", hAbsNO);
598 double hpdLevel1SigmaNO = calculateHPDLevel(hAbsNO, 0.683);
600 double hpdLevel1SigmaIO = calculateHPDLevel(hAbsIO, 0.683);
603 hAbsNO->SetLineColor(kAzure + 2);
604 hAbsNO->SetLineWidth(1);
605 hAbsNO->Draw(
"COLZ");
607 hAbsIO->SetLineColor(kOrange + 7);
608 hAbsIO->SetLineWidth(1);
609 hAbsIO->Draw(
"COLZ SAME");
612 TH2F *hNO_contour = (TH2F *)hAbsNO->Clone(
"hNO_contour");
613 TH2F *hIO_contour = (TH2F *)hAbsIO->Clone(
"hIO_contour");
614 hNO_contour->SetDirectory(0);
615 hIO_contour->SetDirectory(0);
617 hNO_contour->Smooth(1,
"k5a");
618 hIO_contour->Smooth(1,
"k5a");
620 double noLevels[1] = {hpdLevel1SigmaNO};
621 hNO_contour->SetContour(1, noLevels);
622 hNO_contour->SetLineColor(kAzure + 2);
623 hNO_contour->SetLineWidth(3);
624 hNO_contour->Draw(
"CONT3 SAME");
626 double ioLevels[1] = {hpdLevel1SigmaIO};
627 hIO_contour->SetContour(1, ioLevels);
628 hIO_contour->SetLineColor(kOrange + 7);
629 hIO_contour->SetLineWidth(3);
630 hIO_contour->Draw(
"CONT3 SAME");
632 TLegend *legend =
new TLegend(0.68, 0.73, 0.88, 0.91);
633 legend->SetBorderSize(0);
634 legend->SetFillStyle(0);
635 legend->AddEntry(hAbsNO,
"NO 1#sigma",
"l");
636 legend->AddEntry(hAbsIO,
"IO 1#sigma",
"l");
639 drawAsimovMarkerWithLegend(std::abs(asimovDelm23), asimovDcp, legend);
641 cAbs->SaveAs((outputDir +
"delm23_vs_dcp_abs_IO_NO" + suffix +
".png").c_str());
644 drawAbsDelm23Overlay(
"",
"delm2_23 < 0",
"delm2_23 > 0");
646 if (hasUmbrellaWeight) {
647 drawAbsDelm23Overlay(
"_weighted",
648 "(delm2_23 < 0) * umbrella_weight",
649 "(delm2_23 > 0) * umbrella_weight");
653 gStyle->SetPalette(kBird);
656 TCanvas *c4 =
new TCanvas(
"c4",
"Delta m23 NO vs sin^{2}(#theta_{23})", 900, 700);
657 c4->SetRightMargin(0.15);
659 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})",
660 nBins_sin2th23, sin2th23_min, sin2th23_max, nBins_delm23, delm23_no_min, delm23_no_max);
662 tree->Draw(
"delm2_23:sin2th_23>>h2d_sin",
"delm2_23 > 0",
"COLZ");
663 normalizeHist(h2d_sin);
664 h2d_sin->Draw(
"COLZ");
666 h2d_sin->SetStats(0);
667 h2d_sin->GetXaxis()->SetTitle(
"sin^{2}(#theta_{23})");
668 h2d_sin->GetYaxis()->SetTitle(
"#Delta m_{23}^{2} (eV^{2})");
669 h2d_sin->GetZaxis()->SetTitle(
"Normalized Entries");
673 drawAsimovMarkerWithLegend(asimovSin2th23, asimovDelm23,
nullptr);
675 c4->SaveAs((outputDir +
"th23_vs_delm23_no.png").c_str());
677 if (hasUmbrellaWeight){
678 tree->Draw(
"delm2_23:sin2th_23>>h2d_sin",
"(delm2_23 > 0) * umbrella_weight",
"COLZ");
679 normalizeHist(h2d_sin);
680 h2d_sin->Draw(
"COLZ");
681 drawAsimovMarkerWithLegend(asimovSin2th23, asimovDelm23,
nullptr);
683 c4->SaveAs((outputDir +
"th23_vs_delm23_no_weighted.png").c_str());
687 TCanvas *c5 =
new TCanvas(
"c5",
"Delta m23 IO vs sin^{2}(#theta_{23})", 900, 700);
688 c5->SetRightMargin(0.15);
690 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})",
691 nBins_sin2th23, sin2th23_min, sin2th23_max,
692 nBins_delm23, delm23_io_min, delm23_io_max);
694 tree->Draw(
"delm2_23:sin2th_23>>h2d_sin_IO",
"delm2_23 < 0",
"COLZ");
695 normalizeHist(h2d_sin_IO);
696 h2d_sin_IO->Draw(
"COLZ");
698 h2d_sin_IO->SetStats(0);
699 h2d_sin_IO->GetXaxis()->SetTitle(
"sin^{2}(#theta_{23})");
700 h2d_sin_IO->GetYaxis()->SetTitle(
"#Delta m_{23}^{2} (eV^{2})");
701 h2d_sin_IO->GetZaxis()->SetTitle(
"Normalized Entries");
704 drawAsimovMarkerWithLegend(asimovSin2th23, asimovDelm23,
nullptr);
706 c5->SaveAs((outputDir +
"th23_vs_delm23_io.png").c_str());
708 if (hasUmbrellaWeight){
709 tree->Draw(
"delm2_23:sin2th_23>>h2d_sin_IO",
"(delm2_23 < 0)*umbrella_weight",
"COLZ");
710 normalizeHist(h2d_sin_IO);
711 h2d_sin_IO->Draw(
"COLZ");
712 drawAsimovMarkerWithLegend(asimovSin2th23, asimovDelm23,
nullptr);
714 c5->SaveAs((outputDir +
"th23_vs_delm23_io_weighted.png").c_str());
718 TCanvas *c6 =
new TCanvas(
"c6",
"Delta_cp vs sin^{2}(#theta_{23})", 900, 700);
719 c6->SetRightMargin(0.15);
721 TH2F *h2d_delta_cp =
new TH2F(
"h2d_delta_cp",
"#delta_{CP} vs sin^{2}(#theta_{23});#delta_{CP};sin^{2}(#theta_{23})",
722 nBins_dcp, -3.1415, 3.1415,
723 nBins_sin2th23, sin2th23_min, sin2th23_max);
725 tree->Draw(
"sin2th_23:delta_cp>>h2d_delta_cp",
"",
"COLZ");
726 normalizeHist(h2d_delta_cp);
727 h2d_delta_cp->Draw(
"COLZ");
729 h2d_delta_cp->SetStats(0);
730 h2d_delta_cp->GetYaxis()->SetTitle(
"sin^{2}(#theta_{23})");
731 h2d_delta_cp->GetXaxis()->SetTitle(
"#delta_{CP}");
732 h2d_delta_cp->GetZaxis()->SetTitle(
"Normalized Entries");
735 drawAsimovMarkerWithLegend(asimovDcp, asimovSin2th23,
nullptr);
737 c6->SaveAs((outputDir +
"th23_vs_delta_cp.png").c_str());
739 if (hasUmbrellaWeight){
740 tree->Draw(
"sin2th_23:delta_cp>>h2d_delta_cp",
"umbrella_weight",
"COLZ");
741 normalizeHist(h2d_delta_cp);
742 h2d_delta_cp->Draw(
"COLZ");
743 drawAsimovMarkerWithLegend(asimovDcp, asimovSin2th23,
nullptr);
745 c6->SaveAs((outputDir +
"th23_vs_delta_cp_weighted.png").c_str());
749 TCanvas *cth13 =
new TCanvas(
"cth13",
"Delta_cp vs sin^{2}(#theta_{13})", 900, 700);
750 cth13->SetRightMargin(0.15);
752 TH2F *h2d_delta_cp_13 =
new TH2F(
"h2d_delta_cp_13",
"#delta_{CP} vs sin^{2}(#theta_{13});#delta_{CP};sin^{2}(#theta_{13})",
753 nBins_dcp, -3.1415, 3.1415,
754 nBins_sin2th13, sin2th13_min, sin2th13_max);
756 tree->Draw(
"sin2th_13:delta_cp>>h2d_delta_cp_13",
"",
"COLZ");
757 normalizeHist(h2d_delta_cp_13);
758 h2d_delta_cp_13->Draw(
"COLZ");
760 h2d_delta_cp_13->SetStats(0);
761 h2d_delta_cp_13->GetYaxis()->SetTitle(
"sin^{2}(#theta_{13})");
762 h2d_delta_cp_13->GetXaxis()->SetTitle(
"#delta_{CP}");
763 h2d_delta_cp_13->GetZaxis()->SetTitle(
"Normalized Entries");
766 drawAsimovMarkerWithLegend(asimovDcp, asimovSin2th13,
nullptr);
768 cth13->SaveAs((outputDir +
"th13_vs_delta_cp.png").c_str());
770 if (hasUmbrellaWeight){
771 tree->Draw(
"sin2th_13:delta_cp>>h2d_delta_cp_13",
"umbrella_weight",
"COLZ");
772 normalizeHist(h2d_delta_cp_13);
773 h2d_delta_cp_13->Draw(
"COLZ");
774 drawAsimovMarkerWithLegend(asimovDcp, asimovSin2th13,
nullptr);
776 cth13->SaveAs((outputDir +
"th13_vs_delta_cp_weighted.png").c_str());
780 TCanvas *c7 =
new TCanvas(
"c7",
"1D Histograms", 3200, 1200);
785 TH1F *h1d_delta_cp_unweighted =
new TH1F(
"h1d_delta_cp_unweighted",
"#delta_{CP};#delta_{CP};Entries", nBins_dcp, -3.1415, 3.1415);
786 tree->Draw(
"delta_cp>>h1d_delta_cp_unweighted",
"",
"");
787 normalizeHist(h1d_delta_cp_unweighted);
788 h1d_delta_cp_unweighted->SetMinimum(0);
789 h1d_delta_cp_unweighted->SetStats(0);
790 h1d_delta_cp_unweighted->Draw(
"HIST");
791 h1d_delta_cp_unweighted->Draw(
"E SAME");
792 drawAsimovLineWithLegend(asimovDcp);
795 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);
796 tree->Draw(
"delm2_23>>h1d_delm23_all_unweighted",
"",
"");
797 normalizeHist(h1d_delm23_all_unweighted);
798 h1d_delm23_all_unweighted->SetStats(0);
799 h1d_delm23_all_unweighted->Draw(
"HIST");
800 h1d_delm23_all_unweighted->Draw(
"E SAME");
801 drawAsimovLineWithLegend(asimovDelm23);
804 TH1F *h1d_delm23_unweighted = (TH1F*)h1d_delm23_all_unweighted->Clone(
"h1d_delm23_IO_unweighted");
805 h1d_delm23_unweighted->SetTitle(
"#Delta m_{23}^{2} (IO)");
806 h1d_delm23_unweighted->SetStats(0);
807 h1d_delm23_unweighted->GetXaxis()->SetRangeUser(delm23_io_min, delm23_io_max);
808 h1d_delm23_unweighted->Draw(
"HIST");
809 h1d_delm23_unweighted->Draw(
"E SAME");
810 drawAsimovLineWithLegend(asimovDelm23);
813 TH1F *h1d_delm23_NO_unweighted = (TH1F*)h1d_delm23_all_unweighted->Clone(
"h1d_delm23_NO_unweighted");
814 h1d_delm23_unweighted->SetTitle(
"#Delta m_{23}^{2} (NO)");
815 h1d_delm23_NO_unweighted->SetStats(0);
816 h1d_delm23_NO_unweighted->GetXaxis()->SetRangeUser(delm23_no_min, delm23_no_max);
817 h1d_delm23_NO_unweighted->Draw(
"HIST");
818 h1d_delm23_NO_unweighted->Draw(
"E SAME");
819 drawAsimovLineWithLegend(asimovDelm23);
822 TH1F *h1d_sinth23_unweighted =
new TH1F(
"h1d_sinth23_unweighted",
"sin^{2}(#theta_{23});sin^{2}(#theta_{23});Entries", nBins_sin2th23, sin2th23_min, sin2th23_max);
823 tree->Draw(
"sin2th_23>>h1d_sinth23_unweighted",
"",
"");
824 normalizeHist(h1d_sinth23_unweighted);
825 h1d_sinth23_unweighted->SetStats(0);
826 h1d_sinth23_unweighted->Draw(
"HIST");
827 h1d_sinth23_unweighted->Draw(
"E SAME");
828 drawAsimovLineWithLegend(asimovSin2th23);
831 TH1F *h1d_sinth13_unweighted =
new TH1F(
"h1d_sinth13_unweighted",
"sin^{2}(#theta_{13});sin^{2}(#theta_{13});Entries", nBins_sin2th13, sin2th13_min, sin2th13_max);
832 tree->Draw(
"sin2th_13>>h1d_sinth13_unweighted",
"",
"");
833 normalizeHist(h1d_sinth13_unweighted);
834 h1d_sinth13_unweighted->SetStats(0);
835 h1d_sinth13_unweighted->Draw(
"HIST");
836 h1d_sinth13_unweighted->Draw(
"E SAME");
837 drawAsimovLineWithLegend(asimovSin2th13);
840 TH1F *h1d_sinth12_unweighted =
new TH1F(
"h1d_sinth12_unweighted",
"sin^{2}(#theta_{12});sin^{2}(#theta_{12});Entries", nBins_sin2th12, sin2th12_min, sin2th12_max);
841 tree->Draw(
"sin2th_12>>h1d_sinth12_unweighted",
"",
"");
842 normalizeHist(h1d_sinth12_unweighted);
843 h1d_sinth12_unweighted->SetStats(0);
844 h1d_sinth12_unweighted->Draw(
"HIST");
845 h1d_sinth12_unweighted->Draw(
"E SAME");
846 drawAsimovLineWithLegend(asimovSin2th12);
849 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);
850 tree->Draw(
"delm2_12>>h1d_delm12_unweighted",
"",
"");
851 normalizeHist(h1d_delm12_unweighted);
852 h1d_delm12_unweighted->SetStats(0);
853 h1d_delm12_unweighted->Draw(
"HIST");
854 h1d_delm12_unweighted->Draw(
"E SAME");
855 drawAsimovLineWithLegend(asimovDelm12);
858 c7->SaveAs((outputDir +
"1D_histograms_unweighted.png").c_str());
861 TCanvas *c7_weighted =
new TCanvas(
"c7_weighted",
"1D Histograms Weighted", 3200, 1200);
862 c7_weighted->Divide(4, 2);
866 TH1F *h1d_delta_cp =
new TH1F(
"h1d_delta_cp",
"#delta_{CP};#delta_{CP};Weighted Entries", nBins_dcp, -3.1415, 3.1415);
867 if (hasUmbrellaWeight) {
868 tree->Draw(
"delta_cp>>h1d_delta_cp",
"umbrella_weight",
"");
870 tree->Draw(
"delta_cp>>h1d_delta_cp",
"",
"");
871 std::cout <<
"WARNING:::::No umbrella weights found, plotting unweighted delta_cp histogram." << std::endl;
873 normalizeHist(h1d_delta_cp);
874 h1d_delta_cp->SetStats(0);
875 h1d_delta_cp->Sumw2();
876 h1d_delta_cp->Draw(
"HIST");
877 h1d_delta_cp->Draw(
"E SAME");
882 double sigma1 = 0.6827;
883 double sigma3 = 0.9973;
884 double sigma5 = 0.99994;
895 double maxEntries = 0;
896 for (
int j = 1; j <= h1d_delta_cp->GetNbinsX(); j++) {
897 if (h1d_delta_cp->GetBinContent(j) > maxEntries) {
898 maxEntries = h1d_delta_cp->GetBinContent(j);
903 std::cout <<
"HPD bin: " << hpdBin <<
" with " << maxEntries <<
" entries" << std::endl;
906 TH1F *h1d_copy = (TH1F*)h1d_delta_cp->Clone(
"h1d_copy");
909 std::vector<bool> included(h1d_delta_cp->GetNbinsX() + 1,
false);
910 included[hpdBin] =
true;
913 auto findContiguousRegions = [&](
int gapTolerance = 2) {
914 std::vector<std::pair<int, int>> regions;
919 for (
int k = 1; k <= h1d_delta_cp->GetNbinsX(); k++) {
925 }
else if (start != -1) {
927 if (gapCount > gapTolerance) {
929 regions.push_back({start, k - gapCount});
938 regions.push_back({start, h1d_delta_cp->GetNbinsX()});
945 double totalEntries = h1d_delta_cp->Integral();
946 double sumEntries = h1d_delta_cp->GetBinContent(hpdBin);
951 std::vector<std::pair<double, double>> sigma1_regions;
952 std::vector<std::pair<double, double>> sigma3_regions;
953 std::vector<std::pair<double, double>> sigma5_regions;
955 for (
int i = 0; i < h1d_delta_cp->GetNbinsX(); i++) {
958 double maxBinEntries = 0;
959 for (
int j = 1; j <= h1d_delta_cp->GetNbinsX(); j++) {
960 if (!included[j] && h1d_copy->GetBinContent(j) > maxBinEntries) {
961 maxBinEntries = h1d_copy->GetBinContent(j);
966 if (maxBin == 0)
break;
968 sumEntries += maxBinEntries;
969 included[maxBin] =
true;
970 double frac = sumEntries / totalEntries;
972 std::cout <<
"Added bin " << maxBin <<
" with " << maxBinEntries <<
" entries. Fraction: " << frac << std::endl;
974 if (frac >= sigma1 && level1 == 0) {
975 level1 = maxBinEntries;
976 std::cout <<
"1 sigma level: " << level1 << std::endl;
978 auto regions = findContiguousRegions(2);
979 std::cout <<
"1 sigma regions (" << regions.size() <<
" mode(s)):" << std::endl;
980 for (
const auto& region : regions) {
981 double lower = h1d_delta_cp->GetBinLowEdge(region.first);
982 double upper = h1d_delta_cp->GetBinLowEdge(region.second + 1);
983 sigma1_regions.push_back({lower, upper});
984 std::cout <<
" [" << lower <<
", " << upper <<
"]" << std::endl;
987 if (frac >= sigma3 && level3 == 0) {
988 level3 = maxBinEntries;
989 std::cout <<
"3 sigma level: " << level3 << std::endl;
991 auto regions = findContiguousRegions(2);
992 std::cout <<
"3 sigma regions (" << regions.size() <<
" mode(s)):" << std::endl;
993 for (
const auto& region : regions) {
994 double lower = h1d_delta_cp->GetBinLowEdge(region.first);
995 double upper = h1d_delta_cp->GetBinLowEdge(region.second + 1);
996 sigma3_regions.push_back({lower, upper});
997 std::cout <<
" [" << lower <<
", " << upper <<
"]" << std::endl;
1000 if (frac >= sigma5 && level5 == 0) {
1001 level5 = maxBinEntries;
1002 std::cout <<
"5 sigma level: " << level5 << std::endl;
1004 auto regions = findContiguousRegions(2);
1005 std::cout <<
"5 sigma regions (" << regions.size() <<
" mode(s)):" << std::endl;
1006 for (
const auto& region : regions) {
1007 double lower = h1d_delta_cp->GetBinLowEdge(region.first);
1008 double upper = h1d_delta_cp->GetBinLowEdge(region.second + 1);
1009 sigma5_regions.push_back({lower, upper});
1010 std::cout <<
" [" << lower <<
", " << upper <<
"]" << std::endl;
1016 double ymax = h1d_delta_cp->GetMaximum();
1019 for (
const auto& region : sigma1_regions) {
1020 TLine *line_lower =
new TLine(region.first, 0, region.first, ymax);
1021 line_lower->SetLineColor(kOrange+1);
1022 line_lower->SetLineStyle(2);
1023 line_lower->SetLineWidth(2);
1024 line_lower->Draw(
"same");
1026 TLine *line_upper =
new TLine(region.second, 0, region.second, ymax);
1027 line_upper->SetLineColor(kOrange+1);
1028 line_upper->SetLineStyle(2);
1029 line_upper->SetLineWidth(2);
1030 line_upper->Draw(
"same");
1034 for (
const auto& region : sigma3_regions) {
1035 TLine *line_lower =
new TLine(region.first, 0, region.first, ymax);
1036 line_lower->SetLineColor(kAzure+2);
1037 line_lower->SetLineStyle(2);
1038 line_lower->SetLineWidth(2);
1039 line_lower->Draw(
"same");
1041 TLine *line_upper =
new TLine(region.second, 0, region.second, ymax);
1042 line_upper->SetLineColor(kAzure+2);
1043 line_upper->SetLineStyle(2);
1044 line_upper->SetLineWidth(2);
1045 line_upper->Draw(
"same");
1049 for (
const auto& region : sigma5_regions) {
1050 TLine *line_lower =
new TLine(region.first, 0, region.first, ymax);
1051 line_lower->SetLineColor(kMagenta+2);
1052 line_lower->SetLineStyle(2);
1053 line_lower->SetLineWidth(2);
1054 line_lower->Draw(
"same");
1056 TLine *line_upper =
new TLine(region.second, 0, region.second, ymax);
1057 line_upper->SetLineColor(kMagenta+2);
1058 line_upper->SetLineStyle(2);
1059 line_upper->SetLineWidth(2);
1060 line_upper->Draw(
"same");
1063 TLegend *legRef =
nullptr;
1064 if (hasReferenceDcp && hRefDcpShape) {
1065 std::cout <<
"Overlaying reference delta_cp shape on weighted histogram" << std::endl;
1066 TH1D *hRefOverlay = (TH1D*)hRefDcpShape->Clone(
"hRefDcpShape_overlay_linear");
1067 hRefOverlay->SetDirectory(0);
1068 double refIntegral = hRefOverlay->Integral();
1069 if (refIntegral > 0) {
1070 hRefOverlay->Scale(h1d_delta_cp->Integral() / refIntegral);
1072 hRefOverlay->SetLineColor(kMagenta + 2);
1073 hRefOverlay->SetLineWidth(3);
1074 hRefOverlay->SetLineStyle(1);
1075 hRefOverlay->SetFillStyle(0);
1076 hRefOverlay->Draw(
"HIST SAME");
1078 legRef =
new TLegend(0.15, 0.74, 0.48, 0.88);
1079 legRef->SetBorderSize(0);
1080 legRef->SetFillStyle(0);
1081 legRef->AddEntry(h1d_delta_cp,
"Umbrella weighted",
"l");
1082 legRef->AddEntry(hRefOverlay,
"Reference dcp (shape, area-normalized)",
"l");
1085 drawAsimovLineWithLegend(asimovDcp, hasReferenceDcp ? legRef :
nullptr);
1088 if (hasReferenceLLH_Dcp && hRefLLH_Dcp) {
1089 std::cout <<
"Overlaying LLH-scan reference dcp histogram on weighted histogram (resampled to umbrella bins)" << std::endl;
1091 TH1D *hLLHResamp =
new TH1D(
"hRefLLH_dcp_resamp",
"", h1d_delta_cp->GetNbinsX(), h1d_delta_cp->GetXaxis()->GetXmin(), h1d_delta_cp->GetXaxis()->GetXmax());
1092 hLLHResamp->SetDirectory(0);
1093 for (
int i = 1; i <= hLLHResamp->GetNbinsX(); ++i) {
1094 double xlow = hLLHResamp->GetBinLowEdge(i);
1095 double xhigh = hLLHResamp->GetBinLowEdge(i+1);
1097 int nOrig = hRefLLH_Dcp->GetNbinsX();
1098 for (
int k = 1; k <= nOrig; ++k) {
1099 double origLow = hRefLLH_Dcp->GetXaxis()->GetBinLowEdge(k);
1100 double origHigh = origLow + hRefLLH_Dcp->GetBinWidth(k);
1101 double overlap = std::max(0.0, std::min(origHigh, xhigh) - std::max(origLow, xlow));
1102 if (overlap > 0.0) {
1103 double origWidth = hRefLLH_Dcp->GetBinWidth(k);
1104 double contrib = hRefLLH_Dcp->GetBinContent(k) * (overlap / origWidth);
1108 hLLHResamp->SetBinContent(i, val);
1111 double llhInt = hLLHResamp->Integral();
1112 if (llhInt > 0) hLLHResamp->Scale(h1d_delta_cp->Integral() / llhInt);
1113 hLLHResamp->SetLineColor(kBlack);
1114 hLLHResamp->SetLineWidth(3);
1115 hLLHResamp->SetLineStyle(2);
1116 hLLHResamp->SetFillStyle(0);
1117 hLLHResamp->Draw(
"HIST SAME");
1119 TLegend *legLLH =
new TLegend(0.15, 0.60, 0.50, 0.74);
1120 legLLH->SetBorderSize(0);
1121 legLLH->SetFillStyle(0);
1122 legLLH->AddEntry(h1d_delta_cp,
"Umbrella weighted",
"l");
1123 legLLH->AddEntry(hLLHResamp,
"LLH scan (resampled)",
"l");
1128 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);
1129 if (hasUmbrellaWeight) {
1130 tree->Draw(
"delm2_23>>h1d_delm23_all",
"umbrella_weight",
"");
1131 std::cout <<
"Applying umbrella weights to delm23 histogram" << std::endl;
1133 tree->Draw(
"delm2_23>>h1d_delm23_all",
"",
"");
1134 std::cout <<
"WARNING:::::No umbrella weights found, plotting unweighted #Delta m_{23}^{2} histogram." << std::endl;
1136 normalizeHist(h1d_delm23_all);
1137 h1d_delm23_all->SetStats(0);
1138 h1d_delm23_all->Draw(
"HIST");
1139 h1d_delm23_all->Draw(
"E SAME");
1141 TLegend *legRefDelm23All =
nullptr;
1142 if (hasReferenceDelm23 && hRefDelm23Shape) {
1143 TH1D *hRefDelm23AllOverlay = (TH1D*)hRefDelm23Shape->Clone(
"hRefDelm23All_overlay_linear");
1144 hRefDelm23AllOverlay->SetDirectory(0);
1145 double refIntegral = hRefDelm23AllOverlay->Integral();
1146 if (refIntegral > 0) {
1147 hRefDelm23AllOverlay->Scale(h1d_delm23_all->Integral() / refIntegral);
1149 hRefDelm23AllOverlay->SetLineColor(kMagenta + 2);
1150 hRefDelm23AllOverlay->SetLineWidth(3);
1151 hRefDelm23AllOverlay->SetLineStyle(1);
1152 hRefDelm23AllOverlay->SetFillStyle(0);
1153 hRefDelm23AllOverlay->Draw(
"HIST SAME");
1155 legRefDelm23All =
new TLegend(0.50, 0.74, 0.88, 0.88);
1156 legRefDelm23All->SetBorderSize(0);
1157 legRefDelm23All->SetFillStyle(0);
1158 legRefDelm23All->AddEntry(h1d_delm23_all,
"Umbrella weighted",
"l");
1159 legRefDelm23All->AddEntry(hRefDelm23AllOverlay,
"Reference #Delta m_{23}^{2} (full range)",
"l");
1160 legRefDelm23All->Draw();
1162 drawAsimovLineWithLegend(asimovDelm23, hasReferenceDelm23 ? legRefDelm23All :
nullptr);
1165 TH1F *h1d_delm23 = (TH1F*)h1d_delm23_all->Clone(
"h1d_delm23_IO");
1166 h1d_delm23->SetStats(0);
1167 h1d_delm23->Sumw2();
1168 h1d_delm23->GetXaxis()->SetRangeUser(delm23_io_min, delm23_io_max);
1169 h1d_delm23->Draw(
"HIST");
1170 h1d_delm23->Draw(
"E SAME");
1172 TLegend *legRefDelm23IO =
nullptr;
1173 if (hasReferenceDelm23 && hRefDelm23Shape) {
1174 TH1D *hRefDelm23IOOverlay = (TH1D*)hRefDelm23Shape->Clone(
"hRefDelm23IO_overlay_linear");
1175 hRefDelm23IOOverlay->SetDirectory(0);
1176 hRefDelm23IOOverlay->GetXaxis()->SetRangeUser(delm23_io_min, delm23_io_max);
1177 hRefDelm23IOOverlay->SetLineColor(kMagenta + 2);
1178 hRefDelm23IOOverlay->SetLineWidth(3);
1179 hRefDelm23IOOverlay->SetLineStyle(1);
1180 hRefDelm23IOOverlay->SetFillStyle(0);
1181 hRefDelm23IOOverlay->Draw(
"HIST SAME");
1183 legRefDelm23IO =
new TLegend(0.50, 0.74, 0.88, 0.88);
1184 legRefDelm23IO->SetBorderSize(0);
1185 legRefDelm23IO->SetFillStyle(0);
1186 legRefDelm23IO->AddEntry(h1d_delm23,
"Umbrella weighted",
"l");
1187 legRefDelm23IO->AddEntry(hRefDelm23IOOverlay,
"Reference #Delta m_{23}^{2} (IO)",
"l");
1188 legRefDelm23IO->Draw();
1190 drawAsimovLineWithLegend(asimovDelm23, hasReferenceDelm23 ? legRefDelm23IO :
nullptr);
1193 TH1F *h1d_delm23_NO = (TH1F*)h1d_delm23_all->Clone(
"h1d_delm23_NO");
1194 h1d_delm23_NO->SetStats(0);
1195 h1d_delm23_NO->Sumw2();
1196 h1d_delm23_NO->GetXaxis()->SetRangeUser(delm23_no_min, delm23_no_max);
1197 h1d_delm23_NO->Draw(
"HIST");
1198 h1d_delm23_NO->Draw(
"E SAME");
1200 TLegend *legRefDelm23NO =
nullptr;
1201 if (hasReferenceDelm23 && hRefDelm23Shape) {
1202 std::cout <<
"Drawing reference delm23 shape for NO" << std::endl;
1203 TH1D *hRefDelm23NOOverlay = (TH1D*)hRefDelm23Shape->Clone(
"hRefDelm23NO_overlay_linear");
1204 hRefDelm23NOOverlay->SetDirectory(0);
1205 hRefDelm23NOOverlay->GetXaxis()->SetRangeUser(delm23_no_min, delm23_no_max);
1206 hRefDelm23NOOverlay->SetLineColor(kMagenta + 2);
1207 hRefDelm23NOOverlay->SetLineWidth(3);
1208 hRefDelm23NOOverlay->SetLineStyle(1);
1209 hRefDelm23NOOverlay->SetFillStyle(0);
1210 hRefDelm23NOOverlay->Draw(
"HIST SAME");
1212 legRefDelm23NO =
new TLegend(0.50, 0.74, 0.88, 0.88);
1213 legRefDelm23NO->SetBorderSize(0);
1214 legRefDelm23NO->SetFillStyle(0);
1215 legRefDelm23NO->AddEntry(h1d_delm23_NO,
"Umbrella weighted",
"l");
1216 legRefDelm23NO->AddEntry(hRefDelm23NOOverlay,
"Reference #Delta m_{23}^{2} (NO)",
"l");
1217 legRefDelm23NO->Draw();
1219 drawAsimovLineWithLegend(asimovDelm23, hasReferenceDelm23 ? legRefDelm23NO :
nullptr);
1223 if (h1d_delm23_all) {
1224 int binIO_low = h1d_delm23_all->GetXaxis()->FindBin(delm23_io_min);
1225 int binIO_high = h1d_delm23_all->GetXaxis()->FindBin(delm23_io_max);
1226 int binNO_low = h1d_delm23_all->GetXaxis()->FindBin(delm23_no_min);
1227 int binNO_high = h1d_delm23_all->GetXaxis()->FindBin(delm23_no_max);
1229 double fracIO = h1d_delm23_all->Integral(binIO_low, binIO_high);
1230 double fracNO = h1d_delm23_all->Integral(binNO_low, binNO_high);
1233 double ratioNOtoIO = fracNO / fracIO;
1234 std::cout <<
"Mass ordering preference (NO/IO) = " << ratioNOtoIO
1235 <<
" (NO frac=" << fracNO <<
", IO frac=" << fracIO <<
")" << std::endl;
1237 std::cout <<
"Mass ordering preference: IO fraction is zero; cannot compute ratio. "
1238 <<
"NO_frac=" << fracNO <<
" IO_frac=" << fracIO << std::endl;
1241 std::cout <<
"Mass ordering preference: h1d_delm23_all is null; cannot compute." << std::endl;
1245 TH1F *h1d_sinth23 =
new TH1F(
"h1d_sinth23",
"sin^{2}(#theta_{23});sin^{2}(#theta_{23});Weighted Entries", nBins_sin2th23, sin2th23_min, sin2th23_max);
1246 if (hasUmbrellaWeight) {
1247 tree->Draw(
"sin2th_23>>h1d_sinth23",
"umbrella_weight",
"");
1249 tree->Draw(
"sin2th_23>>h1d_sinth23",
"",
"");
1250 std::cout <<
"WARNING:::::No umbrella weights found, plotting unweighted sin^2(theta23) histogram." << std::endl;
1252 normalizeHist(h1d_sinth23);
1253 h1d_sinth23->SetStats(0);
1254 h1d_sinth23->Sumw2();
1255 h1d_sinth23->Draw(
"HIST");
1256 h1d_sinth23->Draw(
"E SAME");
1258 TLegend *legRefSin =
nullptr;
1259 if (hasReferenceSin2Th23 && hRefSin2Th23Shape) {
1260 TH1D *hRefSinOverlay = (TH1D*)hRefSin2Th23Shape->Clone(
"hRefSin2Th23_overlay_linear");
1261 hRefSinOverlay->SetDirectory(0);
1262 double refIntegral = hRefSinOverlay->Integral();
1263 if (refIntegral > 0) {
1264 hRefSinOverlay->Scale(h1d_sinth23->Integral() / refIntegral);
1266 hRefSinOverlay->SetLineColor(kMagenta + 2);
1267 hRefSinOverlay->SetLineWidth(3);
1268 hRefSinOverlay->SetLineStyle(1);
1269 hRefSinOverlay->SetFillStyle(0);
1270 hRefSinOverlay->Draw(
"HIST SAME");
1272 legRefSin =
new TLegend(0.50, 0.74, 0.88, 0.88);
1273 legRefSin->SetBorderSize(0);
1274 legRefSin->SetFillStyle(0);
1275 legRefSin->AddEntry(h1d_sinth23,
"Umbrella weighted",
"l");
1276 legRefSin->AddEntry(hRefSinOverlay,
"Reference sin^{2}(#theta_{23})",
"l");
1279 drawAsimovLineWithLegend(asimovSin2th23, hasReferenceSin2Th23 ? legRefSin :
nullptr);
1282 TH1F *h1d_sinth13 =
new TH1F(
"h1d_sinth13",
"sin^{2}(#theta_{13});sin^{2}(#theta_{13});Weighted Entries", nBins_sin2th13, sin2th13_min, sin2th13_max);
1283 if (hasUmbrellaWeight) {
1284 tree->Draw(
"sin2th_13>>h1d_sinth13",
"umbrella_weight",
"");
1286 tree->Draw(
"sin2th_13>>h1d_sinth13",
"",
"");
1287 std::cout <<
"WARNING:::::No umbrella weights found, plotting unweighted sin^2(theta13) histogram." << std::endl;
1289 normalizeHist(h1d_sinth13);
1290 h1d_sinth13->SetStats(0);
1291 h1d_sinth13->Sumw2();
1292 h1d_sinth13->Draw(
"HIST");
1293 h1d_sinth13->Draw(
"E SAME");
1294 drawAsimovLineWithLegend(asimovSin2th13);
1297 TH1F *h1d_sinth12 =
new TH1F(
"h1d_sinth12",
"sin^{2}(#theta_{12});sin^{2}(#theta_{12});Weighted Entries", nBins_sin2th12, sin2th12_min, sin2th12_max);
1298 if (hasUmbrellaWeight) {
1299 tree->Draw(
"sin2th_12>>h1d_sinth12",
"umbrella_weight",
"");
1301 tree->Draw(
"sin2th_12>>h1d_sinth12",
"",
"");
1302 std::cout <<
"WARNING:::::No umbrella weights found, plotting unweighted sin^2(theta12) histogram." << std::endl;
1304 normalizeHist(h1d_sinth12);
1305 h1d_sinth12->SetStats(0);
1306 h1d_sinth12->Sumw2();
1307 h1d_sinth12->Draw(
"HIST");
1308 h1d_sinth12->Draw(
"E SAME");
1309 drawAsimovLineWithLegend(asimovSin2th12);
1312 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);
1313 if (hasUmbrellaWeight) {
1314 tree->Draw(
"delm2_12>>h1d_delm12",
"umbrella_weight",
"");
1316 tree->Draw(
"delm2_12>>h1d_delm12",
"",
"");
1317 std::cout <<
"WARNING:::::No umbrella weights found, plotting unweighted #Delta m_{12}^{2} histogram." << std::endl;
1319 normalizeHist(h1d_delm12);
1320 h1d_delm12->SetStats(0);
1321 h1d_delm12->Sumw2();
1322 h1d_delm12->Draw(
"HIST");
1323 h1d_delm12->Draw(
"E SAME");
1324 drawAsimovLineWithLegend(asimovDelm12);
1326 c7_weighted->Update();
1327 c7_weighted->SaveAs((outputDir +
"1D_histograms_weighted.png").c_str());
1330 TCanvas *c8 =
new TCanvas(
"c8",
"Delta CP Log Scale", 900, 700);
1332 TH1F *h1d_delta_cp_log = (TH1F*)h1d_delta_cp->Clone(
"h1d_delta_cp_log");
1333 h1d_delta_cp_log->SetTitle(
"#delta_{CP} (Log Scale);#delta_{CP};Weighted Entries");
1334 h1d_delta_cp_log->Draw(
"HIST");
1335 h1d_delta_cp_log->Draw(
"E SAME");
1338 double ymax_log = h1d_delta_cp_log->GetMaximum();
1339 double ymin_log = h1d_delta_cp_log->GetMinimum();
1340 if (ymin_log <= 0) ymin_log = 0.1;
1343 for (
const auto& region : sigma1_regions) {
1344 TLine *line_lower =
new TLine(region.first, ymin_log, region.first, ymax_log);
1345 line_lower->SetLineColor(kRed);
1346 line_lower->SetLineStyle(2);
1347 line_lower->SetLineWidth(2);
1348 line_lower->Draw(
"same");
1350 TLine *line_upper =
new TLine(region.second, ymin_log, region.second, ymax_log);
1351 line_upper->SetLineColor(kRed);
1352 line_upper->SetLineStyle(2);
1353 line_upper->SetLineWidth(2);
1354 line_upper->Draw(
"same");
1358 for (
const auto& region : sigma3_regions) {
1359 TLine *line_lower =
new TLine(region.first, ymin_log, region.first, ymax_log);
1360 line_lower->SetLineColor(kAzure+2);
1361 line_lower->SetLineStyle(2);
1362 line_lower->SetLineWidth(2);
1363 line_lower->Draw(
"same");
1365 TLine *line_upper =
new TLine(region.second, ymin_log, region.second, ymax_log);
1366 line_upper->SetLineColor(kAzure+2);
1367 line_upper->SetLineStyle(2);
1368 line_upper->SetLineWidth(2);
1369 line_upper->Draw(
"same");
1373 for (
const auto& region : sigma5_regions) {
1374 TLine *line_lower =
new TLine(region.first, ymin_log, region.first, ymax_log);
1375 line_lower->SetLineColor(kMagenta+2);
1376 line_lower->SetLineStyle(2);
1377 line_lower->SetLineWidth(2);
1378 line_lower->Draw(
"same");
1380 TLine *line_upper =
new TLine(region.second, ymin_log, region.second, ymax_log);
1381 line_upper->SetLineColor(kMagenta+2);
1382 line_upper->SetLineStyle(2);
1383 line_upper->SetLineWidth(2);
1384 line_upper->Draw(
"same");
1387 TLegend *legRefLog =
nullptr;
1388 if (hasReferenceDcp && hRefDcpShape) {
1389 TH1D *hRefOverlayLog = (TH1D*)hRefDcpShape->Clone(
"hRefDcpShape_overlay_log");
1390 hRefOverlayLog->SetDirectory(0);
1391 double refIntegral = hRefOverlayLog->Integral();
1392 if (refIntegral > 0) {
1393 hRefOverlayLog->Scale(h1d_delta_cp_log->Integral() / refIntegral);
1395 hRefOverlayLog->SetLineColor(kMagenta + 2);
1396 hRefOverlayLog->SetLineWidth(3);
1397 hRefOverlayLog->SetLineStyle(1);
1398 hRefOverlayLog->SetFillStyle(0);
1399 hRefOverlayLog->Draw(
"HIST SAME");
1401 legRefLog =
new TLegend(0.50, 0.74, 0.88, 0.88);
1402 legRefLog->SetBorderSize(0);
1403 legRefLog->SetFillStyle(0);
1404 legRefLog->AddEntry(h1d_delta_cp_log,
"Umbrella weighted",
"l");
1405 legRefLog->AddEntry(hRefOverlayLog,
"Reference dcp (shape, area-normalized)",
"l");
1408 if (hasReferenceLLH_Dcp && hRefLLH_Dcp) {
1410 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());
1411 hLLHResampLog->SetDirectory(0);
1412 for (
int i = 1; i <= hLLHResampLog->GetNbinsX(); ++i) {
1413 double xlow = hLLHResampLog->GetBinLowEdge(i);
1414 double xhigh = hLLHResampLog->GetBinLowEdge(i+1);
1416 int nOrig = hRefLLH_Dcp->GetNbinsX();
1417 for (
int k = 1; k <= nOrig; ++k) {
1418 double origLow = hRefLLH_Dcp->GetXaxis()->GetBinLowEdge(k);
1419 double origHigh = origLow + hRefLLH_Dcp->GetBinWidth(k);
1420 double overlap = std::max(0.0, std::min(origHigh, xhigh) - std::max(origLow, xlow));
1421 if (overlap > 0.0) {
1422 double origWidth = hRefLLH_Dcp->GetBinWidth(k);
1423 double contrib = hRefLLH_Dcp->GetBinContent(k) * (overlap / origWidth);
1427 hLLHResampLog->SetBinContent(i, val);
1429 double llhI = hLLHResampLog->Integral();
1430 if (llhI > 0) hLLHResampLog->Scale(h1d_delta_cp_log->Integral() / llhI);
1431 hLLHResampLog->SetLineColor(kBlue + 2);
1432 hLLHResampLog->SetLineWidth(3);
1433 hLLHResampLog->SetLineStyle(2);
1434 hLLHResampLog->SetFillStyle(0);
1435 hLLHResampLog->Draw(
"HIST SAME");
1436 TLegend *legLLHLog =
new TLegend(0.50, 0.60, 0.88, 0.74);
1437 legLLHLog->SetBorderSize(0);
1438 legLLHLog->SetFillStyle(0);
1439 legLLHLog->AddEntry(h1d_delta_cp_log,
"Umbrella weighted",
"l");
1440 legLLHLog->AddEntry(hLLHResampLog,
"LLH scan (resampled & area-normalized)",
"l");
1443 drawAsimovLineWithLegend(asimovDcp, hasReferenceDcp ? legRefLog :
nullptr);
1446 c8->SaveAs((outputDir +
"delta_cp_log_scale_weighted.png").c_str());
1449 TCanvas *c9 =
new TCanvas(
"c9",
"Delta CP Log Scale Marginalized by Ordering", 1800, 700);
1452 std::string ioSelection = hasUmbrellaWeight ?
"(delm2_23 < 0) * umbrella_weight" :
"(delm2_23 < 0)";
1453 std::string noSelection = hasUmbrellaWeight ?
"(delm2_23 > 0) * umbrella_weight" :
"(delm2_23 > 0)";
1458 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);
1459 tree->Draw(
"delta_cp>>h1d_delta_cp_io_log", ioSelection.c_str(),
"");
1460 normalizeHist(h1d_delta_cp_io_log);
1461 h1d_delta_cp_io_log->SetStats(0);
1462 double ioMinPositive = 1.0;
1463 bool ioFoundPositive =
false;
1464 for (
int b = 1; b <= h1d_delta_cp_io_log->GetNbinsX(); ++b) {
1465 double y = h1d_delta_cp_io_log->GetBinContent(b);
1467 if (!ioFoundPositive || y < ioMinPositive) {
1470 ioFoundPositive =
true;
1473 h1d_delta_cp_io_log->SetMinimum(ioFoundPositive ? 0.5 * ioMinPositive : 1e-8);
1474 h1d_delta_cp_io_log->Draw(
"HIST");
1475 h1d_delta_cp_io_log->Draw(
"E SAME");
1476 drawAsimovLineWithLegend(asimovDcp);
1477 if (hasReferenceLLH_Dcp_IO && hRefLLH_Dcp_IO) {
1478 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());
1479 hLLHIO->SetDirectory(0);
1480 for (
int i = 1; i <= hLLHIO->GetNbinsX(); ++i) {
1481 double xlow = hLLHIO->GetBinLowEdge(i);
1482 double xhigh = hLLHIO->GetBinLowEdge(i+1);
1484 int nOrig = hRefLLH_Dcp_IO->GetNbinsX();
1485 for (
int k = 1; k <= nOrig; ++k) {
1486 double origLow = hRefLLH_Dcp_IO->GetXaxis()->GetBinLowEdge(k);
1487 double origHigh = origLow + hRefLLH_Dcp_IO->GetBinWidth(k);
1488 double overlap = std::max(0.0, std::min(origHigh, xhigh) - std::max(origLow, xlow));
1489 if (overlap > 0.0) {
1490 double origWidth = hRefLLH_Dcp_IO->GetBinWidth(k);
1491 double contrib = hRefLLH_Dcp_IO->GetBinContent(k) * (overlap / origWidth);
1495 hLLHIO->SetBinContent(i, val);
1497 double li = hLLHIO->Integral();
1498 if (li > 0) hLLHIO->Scale(h1d_delta_cp_io_log->Integral() / li);
1499 hLLHIO->SetLineColor(kBlue + 2);
1500 hLLHIO->SetLineWidth(2);
1501 hLLHIO->SetLineStyle(2);
1502 hLLHIO->Draw(
"HIST SAME");
1503 TLegend *legLLHIO =
new TLegend(0.50, 0.60, 0.88, 0.74);
1504 legLLHIO->SetBorderSize(0);
1505 legLLHIO->SetFillStyle(0);
1506 legLLHIO->AddEntry(h1d_delta_cp_io_log,
"Umbrella weighted (IO)",
"l");
1507 legLLHIO->AddEntry(hLLHIO,
"LLH scan IO (resampled & area-normalized)",
"l");
1514 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);
1515 tree->Draw(
"delta_cp>>h1d_delta_cp_no_log", noSelection.c_str(),
"");
1516 normalizeHist(h1d_delta_cp_no_log);
1517 h1d_delta_cp_no_log->SetStats(0);
1518 double noMinPositive = 1.0;
1519 bool noFoundPositive =
false;
1520 for (
int b = 1; b <= h1d_delta_cp_no_log->GetNbinsX(); ++b) {
1521 double y = h1d_delta_cp_no_log->GetBinContent(b);
1523 if (!noFoundPositive || y < noMinPositive) {
1526 noFoundPositive =
true;
1529 h1d_delta_cp_no_log->SetMinimum(noFoundPositive ? 0.5 * noMinPositive : 1e-8);
1530 h1d_delta_cp_no_log->Draw(
"HIST");
1531 h1d_delta_cp_no_log->Draw(
"E SAME");
1532 drawAsimovLineWithLegend(asimovDcp);
1533 if (hasReferenceLLH_Dcp_NO && hRefLLH_Dcp_NO) {
1534 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());
1535 hLLHNO->SetDirectory(0);
1536 for (
int i = 1; i <= hLLHNO->GetNbinsX(); ++i) {
1537 double xlow = hLLHNO->GetBinLowEdge(i);
1538 double xhigh = hLLHNO->GetBinLowEdge(i+1);
1540 int nOrig = hRefLLH_Dcp_NO->GetNbinsX();
1541 for (
int k = 1; k <= nOrig; ++k) {
1542 double origLow = hRefLLH_Dcp_NO->GetXaxis()->GetBinLowEdge(k);
1543 double origHigh = origLow + hRefLLH_Dcp_NO->GetBinWidth(k);
1544 double overlap = std::max(0.0, std::min(origHigh, xhigh) - std::max(origLow, xlow));
1545 if (overlap > 0.0) {
1546 double origWidth = hRefLLH_Dcp_NO->GetBinWidth(k);
1547 double contrib = hRefLLH_Dcp_NO->GetBinContent(k) * (overlap / origWidth);
1551 hLLHNO->SetBinContent(i, val);
1553 double ln = hLLHNO->Integral();
1554 if (ln > 0) hLLHNO->Scale(h1d_delta_cp_no_log->Integral() / ln);
1555 hLLHNO->SetLineColor(kBlue + 2);
1556 hLLHNO->SetLineWidth(2);
1557 hLLHNO->SetLineStyle(2);
1558 hLLHNO->Draw(
"HIST SAME");
1559 TLegend *legLLHNO =
new TLegend(0.50, 0.60, 0.88, 0.74);
1560 legLLHNO->SetBorderSize(0);
1561 legLLHNO->SetFillStyle(0);
1562 legLLHNO->AddEntry(h1d_delta_cp_no_log,
"Umbrella weighted (NO)",
"l");
1563 legLLHNO->AddEntry(hLLHNO,
"LLH scan NO (resampled & area-normalized)",
"l");
1568 c9->SaveAs((outputDir +
"delta_cp_log_scale_marginalized_io_no.png").c_str());
1571 const double jarlskogMin = -0.06;
1572 const double jarlskogMax = 0.06;
1573 const int nBinsJarlskog = 160;
1575 TCanvas *c10 =
new TCanvas(
"c10",
"Jarlskog Invariant", 900, 700);
1576 TH1F *h1d_jarlskog_unweighted =
new TH1F(
"h1d_jarlskog_unweighted",
"Jarlskog invariant;Jarlskog invariant;Entries",
1577 nBinsJarlskog, jarlskogMin, jarlskogMax);
1578 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",
1580 normalizeHist(h1d_jarlskog_unweighted);
1581 h1d_jarlskog_unweighted->SetStats(0);
1582 h1d_jarlskog_unweighted->Draw(
"HIST");
1583 h1d_jarlskog_unweighted->Draw(
"E SAME");
1584 drawAsimovLineWithLegend(asimovJarlskog);
1586 auto computeOneSidedBounds = [&](TH1 *hist,
double targets[3],
double outBounds[3]) {
1589 for (
int i = 0; i < 3; ++i) outBounds[i] = std::numeric_limits<double>::quiet_NaN();
1591 double total = hist->Integral();
1592 if (total <= 0)
return;
1593 int nBins = hist->GetNbinsX();
1595 double leftSum = 0.0;
1596 double rightSum = 0.0;
1597 for (
int b = 1; b <= nBins; ++b) {
1598 double center = hist->GetBinCenter(b);
1599 double c = hist->GetBinContent(b);
1600 if (center < 0) leftSum += c;
else rightSum += c;
1602 bool integrateLeftToRight = (leftSum >= rightSum);
1604 for (
int t = 0; t < 3; ++t) {
1605 double target = targets[t];
1607 if (integrateLeftToRight) {
1608 for (
int b = 1; b <= nBins; ++b) {
1609 cum += hist->GetBinContent(b);
1610 if (cum / total >= target) {
1612 outBounds[t] = hist->GetBinLowEdge(b+1);
1617 if (!std::isfinite(outBounds[t])) outBounds[t] = hist->GetXaxis()->GetXmax();
1619 for (
int b = nBins; b >= 1; --b) {
1620 cum += hist->GetBinContent(b);
1621 if (cum / total >= target) {
1623 outBounds[t] = hist->GetBinLowEdge(b);
1627 if (!std::isfinite(outBounds[t])) outBounds[t] = hist->GetXaxis()->GetXmin();
1631 double hist_ymax = hist->GetMaximum();
1633 int colors[3] = {kOrange+1, kAzure+2, kMagenta+2};
1634 for (
int t = 0; t < 3; ++t) {
1635 if (!std::isfinite(outBounds[t]))
continue;
1636 TLine *line =
nullptr;
1637 if (integrateLeftToRight) {
1639 line =
new TLine(outBounds[t], 0, outBounds[t], hist_ymax);
1642 line =
new TLine(outBounds[t], 0, outBounds[t], hist_ymax);
1644 line->SetLineColor(colors[t]);
1645 line->SetLineStyle(2);
1646 line->SetLineWidth(2);
1652 c10->SaveAs((outputDir +
"jarlskog_unweighted.png").c_str());
1654 TCanvas *c10_log =
new TCanvas(
"c10_log",
"Jarlskog Invariant Log Scale", 900, 700);
1656 TH1F *h1d_jarlskog_unweighted_log = (TH1F*)h1d_jarlskog_unweighted->Clone(
"h1d_jarlskog_unweighted_log");
1657 h1d_jarlskog_unweighted_log->SetTitle(
"Jarlskog invariant (Log Scale);Jarlskog invariant;Entries");
1658 h1d_jarlskog_unweighted_log->Draw(
"HIST");
1659 h1d_jarlskog_unweighted_log->Draw(
"E SAME");
1660 drawAsimovLineWithLegend(asimovJarlskog);
1663 c10_log->SaveAs((outputDir +
"jarlskog_unweighted_log.png").c_str());
1665 TCanvas *c10_weighted =
new TCanvas(
"c10_weighted",
"Jarlskog Invariant Weighted", 900, 700);
1666 TH1F *h1d_jarlskog_weighted =
new TH1F(
"h1d_jarlskog_weighted",
"Jarlskog invariant;Jarlskog invariant;Weighted Entries",
1667 nBinsJarlskog, jarlskogMin, jarlskogMax);
1668 if (hasUmbrellaWeight) {
1669 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",
1670 "umbrella_weight",
"");
1672 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",
1674 std::cout <<
"WARNING:::::No umbrella weights found, plotting unweighted Jarlskog histogram." << std::endl;
1676 normalizeHist(h1d_jarlskog_weighted);
1677 h1d_jarlskog_weighted->SetStats(0);
1678 h1d_jarlskog_weighted->Sumw2();
1679 h1d_jarlskog_weighted->Draw(
"HIST");
1680 h1d_jarlskog_weighted->Draw(
"E SAME");
1681 drawAsimovLineWithLegend(asimovJarlskog);
1683 double targets[3] = {sigma1, sigma3, sigma5};
1685 computeOneSidedBounds(h1d_jarlskog_weighted, targets, bounds);
1687 double ymax_w = h1d_jarlskog_weighted->GetMaximum();
1688 TLine *legLine1 =
nullptr;
1689 TLine *legLine3 =
nullptr;
1690 TLine *legLine5 =
nullptr;
1691 if (std::isfinite(bounds[0])) legLine1 =
new TLine(bounds[0], 0, bounds[0], ymax_w);
1692 if (std::isfinite(bounds[1])) legLine3 =
new TLine(bounds[1], 0, bounds[1], ymax_w);
1693 if (std::isfinite(bounds[2])) legLine5 =
new TLine(bounds[2], 0, bounds[2], ymax_w);
1694 if (legLine1) { legLine1->SetLineColor(kOrange+1); legLine1->SetLineStyle(2); legLine1->SetLineWidth(2); }
1695 if (legLine3) { legLine3->SetLineColor(kAzure+2); legLine3->SetLineStyle(2); legLine3->SetLineWidth(2); }
1696 if (legLine5) { legLine5->SetLineColor(kMagenta+2); legLine5->SetLineStyle(2); legLine5->SetLineWidth(2); }
1697 TLegend *legCI =
new TLegend(0.15, 0.60, 0.50, 0.74);
1698 legCI->SetBorderSize(0);
1699 legCI->SetFillStyle(0);
1700 if (legLine1) legCI->AddEntry(legLine1,
"1 #sigma (one-sided)",
"l");
1701 if (legLine3) legCI->AddEntry(legLine3,
"3 #sigma (one-sided)",
"l");
1702 if (legLine5) legCI->AddEntry(legLine5,
"5 #sigma (one-sided)",
"l");
1704 c10_weighted->Update();
1705 c10_weighted->SaveAs((outputDir +
"jarlskog_weighted.png").c_str());
1707 TCanvas *c10_weighted_log =
new TCanvas(
"c10_weighted_log",
"Jarlskog Invariant Weighted Log Scale", 900, 700);
1708 c10_weighted_log->SetLogy();
1709 TH1F *h1d_jarlskog_weighted_log = (TH1F*)h1d_jarlskog_weighted->Clone(
"h1d_jarlskog_weighted_log");
1710 h1d_jarlskog_weighted_log->SetTitle(
"Jarlskog invariant (Log Scale);Jarlskog invariant;Weighted Entries");
1711 h1d_jarlskog_weighted_log->Draw(
"HIST");
1712 h1d_jarlskog_weighted_log->Draw(
"E SAME");
1713 drawAsimovLineWithLegend(asimovJarlskog);
1715 for (
int t = 0; t < 3; ++t) {
1716 if (!std::isfinite(bounds[t]))
continue;
1717 double hist_ymax = h1d_jarlskog_weighted_log->GetMaximum();
1718 int colors_log[3] = {kOrange+1, kAzure+2, kMagenta+2};
1719 TLine *line =
new TLine(bounds[t], 0, bounds[t], hist_ymax);
1720 line->SetLineColor(colors_log[t]);
1721 line->SetLineStyle(2);
1722 line->SetLineWidth(2);
1726 TLegend *legCI_log =
new TLegend(0.15, 0.60, 0.50, 0.74);
1727 legCI_log->SetBorderSize(0);
1728 legCI_log->SetFillStyle(0);
1729 if (legLine1) legCI_log->AddEntry(legLine1,
"1 #sigma (one-sided)",
"l");
1730 if (legLine3) legCI_log->AddEntry(legLine3,
"3 #sigma (one-sided)",
"l");
1731 if (legLine5) legCI_log->AddEntry(legLine5,
"5 #sigma (one-sided)",
"l");
1733 c10_weighted_log->Update();
1734 c10_weighted_log->SaveAs((outputDir +
"jarlskog_weighted_log.png").c_str());
1736 struct TriangleVar {
1746 std::vector<TriangleVar> triangleVars = {
1747 {
"delta_cp",
"#delta_{CP}",
"delta_cp", nBins_dcp, -3.1415, 3.1415, asimovDcp},
1748 {
"sin2th_23",
"sin^{2}(#theta_{23})",
"sin2th_23", nBins_sin2th23, sin2th23_min, sin2th23_max, asimovSin2th23},
1749 {
"sin2th_13",
"sin^{2}(#theta_{13})",
"sin2th_13", nBins_sin2th13, sin2th13_min, sin2th13_max, asimovSin2th13},
1750 {
"sin2th_12",
"sin^{2}(#theta_{12})",
"sin2th_12", nBins_sin2th12, sin2th12_min, sin2th12_max, asimovSin2th12},
1751 {
"delm2_23",
"#Delta m_{23}^{2} (eV^{2})",
"delm2_23", nBins_delm23, delm23_io_min, delm23_no_max, asimovDelm23},
1752 {
"delm2_12",
"#Delta m_{12}^{2} (eV^{2})",
"delm2_12", nBins_delm12, delm12_min, delm12_max, asimovDelm12}
1755 auto drawAsimovLineNoLegend = [&](
double xValue) {
1756 if (!isAsimovChain || !std::isfinite(xValue) || !gPad)
return;
1758 const double yMin = gPad->GetUymin();
1759 const double yMax = gPad->GetUymax();
1760 TLine *asimovLine =
new TLine(xValue, yMin, xValue, yMax);
1761 asimovLine->SetLineColor(kBlack);
1762 asimovLine->SetLineStyle(3);
1763 asimovLine->SetLineWidth(2);
1764 asimovLine->Draw(
"SAME");
1767 auto drawAsimovMarkerNoLegend = [&](
double xValue,
double yValue) {
1768 if (!isAsimovChain || !std::isfinite(xValue) || !std::isfinite(yValue) || !gPad)
return;
1770 const double xMin = gPad->GetUxmin();
1771 const double xMax = gPad->GetUxmax();
1772 const double yMin = gPad->GetUymin();
1773 const double yMax = gPad->GetUymax();
1774 const double dx = 0.012 * (xMax - xMin);
1775 const double dy = 0.012 * (yMax - yMin);
1777 TLine *l1 =
new TLine(xValue - dx, yValue - dy, xValue + dx, yValue + dy);
1778 l1->SetLineColor(kRed);
1779 l1->SetLineWidth(2);
1782 TLine *l2 =
new TLine(xValue - dx, yValue + dy, xValue + dx, yValue - dy);
1783 l2->SetLineColor(kRed);
1784 l2->SetLineWidth(2);
1788 auto drawTrianglePlot = [&](
const std::string &weightExpr,
const std::string &suffix,
int mo = 0) {
1790 std::cout <<
"Drawing triangle plot for IO" << std::endl;
1791 triangleVars[4].min = delm23_no_min;
1792 triangleVars[4].max = delm23_no_max;
1793 }
else if (mo == -1) {
1794 std::cout <<
"Drawing triangle plot for NO" << std::endl;
1795 triangleVars[4].min = delm23_io_min;
1796 triangleVars[4].max = delm23_io_max;
1798 std::cout <<
"Drawing triangle plot for both MO" << std::endl;
1801 const int nVars =
static_cast<int>(triangleVars.size());
1802 TCanvas *cTri =
new TCanvas((
"c_triangle" + suffix).c_str(),
"Triangle Plot", 1400, 1400);
1803 cTri->SetFillStyle(0);
1807 const double TPm[4] = {.07, .07, .05, .05};
1808 const double Pm[2] = {.2, .1};
1810 const double TPw = 1.0 - TPm[0] - TPm[2];
1811 const double a_x = (Pm[0] * TPw) / (1.0 * nVars + Pm[0] * (1.0 - 1.0 * nVars));
1812 const double b_x = (TPw - a_x) / (1.0 * nVars);
1814 std::vector<double> X_Min(nVars), X_Max(nVars);
1816 X_Max[0] = X_Min[0] + a_x + b_x;
1817 for (
int i = 1; i < nVars; ++i) {
1818 X_Min[i] = X_Max[i - 1];
1819 X_Max[i] = X_Min[i] + b_x;
1822 const double TPh = 1.0 - TPm[1] - TPm[3];
1823 const double a_y = (Pm[1] * TPh) / (1.0 * nVars + Pm[1] * (1.0 - 1.0 * nVars));
1824 const double b_y = (TPh - a_y) / (1.0 * nVars);
1826 std::vector<double> Y_Min(nVars), Y_Max(nVars);
1827 Y_Min[nVars - 1] = TPm[1];
1828 Y_Max[nVars - 1] = Y_Min[nVars - 1] + a_y + b_y;
1829 for (
int i = nVars - 2; i >= 0; --i) {
1830 Y_Min[i] = Y_Max[i + 1];
1831 Y_Max[i] = Y_Min[i] + b_y;
1834 for (
int row = 0; row < nVars; ++row) {
1835 for (
int col = 0; col <= row; ++col) {
1836 const double x1 = X_Min[col];
1837 const double x2 = X_Max[col];
1838 const double y1 = Y_Min[row];
1839 const double y2 = Y_Max[row];
1841 TPad *pad =
new TPad(Form(
"tri_pad_%s_%d_%d", suffix.c_str(), row, col),
"", x1, y1, x2, y2);
1842 pad->SetFillStyle(0);
1843 pad->SetRightMargin(0.02);
1844 pad->SetTopMargin(0.02);
1845 pad->SetLeftMargin(col == 0 ? 0.26 : 0.06);
1846 pad->SetBottomMargin(row == nVars - 1 ? 0.18 : 0.06);
1850 const TriangleVar &xVar = triangleVars[col];
1851 const TriangleVar &yVar = triangleVars[row];
1854 TH1F *h1 =
new TH1F(Form(
"h_tri_1d_%s_%s", suffix.c_str(), xVar.name.c_str()),
1855 "", xVar.bins, xVar.min, xVar.max);
1856 std::string drawExpr = xVar.branch +
">>" + h1->GetName();
1857 tree->Draw(drawExpr.c_str(), weightExpr.c_str(),
"goff");
1860 h1->GetXaxis()->SetTitle(row == nVars - 1 ? xVar.title.c_str() :
"");
1861 h1->GetYaxis()->SetTitle(col == 0 ?
"Entries" :
"");
1862 h1->GetXaxis()->SetLabelSize(row == nVars - 1 ? 0.07 : 0.0);
1863 h1->GetYaxis()->SetLabelSize(col == 0 ? 0.07 : 0.0);
1864 h1->GetXaxis()->SetTitleSize(row == nVars - 1 ? 0.08 : 0.0);
1865 h1->GetYaxis()->SetTitleSize(col == 0 ? 0.08 : 0.0);
1868 drawAsimovLineNoLegend(xVar.asimov);
1870 TH2F *h2 =
new TH2F(Form(
"h_tri_2d_%s_%s_%s", suffix.c_str(), yVar.name.c_str(), xVar.name.c_str()),
1871 "", xVar.bins, xVar.min, xVar.max, yVar.bins, yVar.min, yVar.max);
1872 std::string drawExpr = yVar.branch +
":" + xVar.branch +
">>" + h2->GetName();
1873 tree->Draw(drawExpr.c_str(), weightExpr.c_str(),
"goff");
1876 h2->GetXaxis()->SetTitle(row == nVars - 1 ? xVar.title.c_str() :
"");
1877 h2->GetYaxis()->SetTitle(col == 0 ? yVar.title.c_str() :
"");
1878 h2->GetXaxis()->SetLabelSize(row == nVars - 1 ? 0.07 : 0.0);
1879 h2->GetYaxis()->SetLabelSize(col == 0 ? 0.07 : 0.0);
1880 h2->GetXaxis()->SetTitleSize(row == nVars - 1 ? 0.08 : 0.0);
1881 h2->GetYaxis()->SetTitleSize(col == 0 ? 0.08 : 0.0);
1883 drawAsimovMarkerNoLegend(xVar.asimov, yVar.asimov);
1891 cTri->SaveAs((outputDir +
"triangle" + suffix +
".png").c_str());
1894 drawTrianglePlot(
"",
"_unweighted", 0);
1895 if (hasUmbrellaWeight) {
1896 drawTrianglePlot(
"umbrella_weight",
"_weighted", 0);
1898 std::cout <<
"WARNING:::::No umbrella weights found, skipping weighted triangle plot." << std::endl;
1901 drawTrianglePlot(
"(delm2_23 < 0)",
"_io_unweighted",-1);
1902 drawTrianglePlot(
"(delm2_23 > 0)",
"_no_unweighted",1);
1903 if (hasUmbrellaWeight) {
1904 drawTrianglePlot(
"(delm2_23 < 0) * umbrella_weight",
"_io_weighted",-1);
1905 drawTrianglePlot(
"(delm2_23 > 0) * umbrella_weight",
"_no_weighted",1);
1907 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.