MUSIC unknown
Analysis for the MUSIC active-target ionization chamber
Loading...
Searching...
No Matches
main_compute_regions.cpp
Go to the documentation of this file.
1// compute-regions: fit each reaction strip's (a,n) and (a,a') regions from the
2// scatter cache and save them as cuts, exactly where hand-drawn ones go.
3//
4// A read-only pass over StripSumScatter_cache.root: it never fills, never
5// touches the cache, and needs no DISPLAY. strip-sum-scatter then loads the
6// saved cuts like any drawn ones. Re-run it after any refill.
7#include "Constants.hpp"
8#include "InitUtils.hpp"
9#include "Paths.hpp"
10#include "RegionCuts.hpp"
11#include "StripSumScatter.hpp"
12#include <TFile.h>
13#include <TH2F.h>
14#include <TNamed.h>
15#include <TROOT.h>
16#include <iostream>
17
18int main() {
19 InitUtils::SetROOTPreferences(PlotSaveFormat::kPNG,
20 Paths::ResultsDir() + "/plots",
21 Paths::ResultsDir() + "/root_files");
22 gROOT->SetBatch(kTRUE);
23 const StripSumScatterConfig &C = Constants::cfg.STRIP_SUM_SCATTER_CONFIG;
24
25 // Same resolution as StripSumScatter::TryLoadCache: the bare name lives
26 // under the dataset's root_files directory.
27 TString cache =
28 IO::GetRootFilesBaseDir() + "/" + StripSumScatter::CacheName();
29 TFile f(cache, "READ");
30 if (f.IsZombie()) {
31 std::cerr << "compute-regions: no scatter cache at " << cache
32 << "; run strip-sum-scatter first" << std::endl;
33 return 1;
34 }
35 if (TNamed *fp = static_cast<TNamed *>(f.Get("fingerprint"))) {
36 std::cout << "compute-regions: cache " << cache << std::endl;
37 std::cout << " fingerprint " << fp->GetTitle() << std::endl;
38 }
39
40 const Bool_t band =
42 if (band)
43 std::cout << "compute-regions: beam component per strip; (a,n) region = "
44 "the band "
46 << " conditional sigma above the ridge, (a,a') the beam's "
47 << C.AA_REGION_NSIGMA << " sigma ellipse; reac "
49 << std::endl;
50 else
51 std::cout << "compute-regions: bivariate Gaussian mixture per strip; "
52 "(a,n) region at "
53 << C.AN_REGION_NSIGMA << " sigma, (a,a') at "
54 << C.AA_REGION_NSIGMA << " sigma; reac " << C.REACTION_STRIP_MIN
55 << ".." << C.REACTION_STRIP_MAX << std::endl;
56
57 Int_t nOk = 0, nTried = 0;
58 for (Int_t reac = C.REACTION_STRIP_MIN; reac <= C.REACTION_STRIP_MAX;
59 reac++) {
60 TH2F *h = static_cast<TH2F *>(f.Get(Form("scatter_r%d", reac)));
61 if (!h)
62 continue;
63 nTried++;
64 // Same window the scatter is displayed in.
65 Double_t y_lo = C.Y_DISPLAY_MIN, y_hi = C.Y_DISPLAY_MAX;
66 std::map<Int_t, std::pair<Double_t, Double_t>>::const_iterator it =
67 C.Y_DISPLAY_RANGE.find(reac);
68 if (it != C.Y_DISPLAY_RANGE.end()) {
69 y_lo = it->second.first;
70 y_hi = it->second.second;
71 }
72 RegionFit fit =
74 C.X_DISPLAY_MAX, y_lo, y_hi)
76 C.X_DISPLAY_MAX, y_lo, y_hi);
77 if (!fit.ok) {
78 std::cout << " [region] reac " << reac << ": no region -- " << fit.why
79 << std::endl;
80 continue;
81 }
82 TCutG *an = band ? RegionCutFinder::RidgeBandCut(
83 "region_an", fit.beam, C.AN_RIDGE_NSIGMA_LO,
85 C.X_DISPLAY_MAX, y_lo, y_hi)
86 : RegionCutFinder::EllipseCut("region_an", fit.reac,
88 TCutG *aa =
90 const Double_t nAn = RegionCutFinder::CountInside(h, an, fit);
91 const Double_t nAa = RegionCutFinder::CountInside(h, aa, fit);
92 if (band) {
93 // The band's count is geometric by construction; no attributed count
94 // is stored, so cross-section takes what lies inside the region.
95 fit.n_reac = nAn;
96 std::cout << Form(" [region] reac %2d: beam (%.3f, %.3f) s(%.3f, %.3f) "
97 "rho %+.2f | (a,n) band %.1f..%.1f sigma above the "
98 "ridge: %.0f in region; (a,a') in region %.0f",
99 reac, fit.beam.mx, fit.beam.my, fit.beam.sx,
100 fit.beam.sy, fit.beam.rho, C.AN_RIDGE_NSIGMA_LO,
101 C.AN_RIDGE_NSIGMA_HI, nAn, nAa)
102 << std::endl;
103 } else {
104 // Two counts: what the fit attributes to the reaction, and what lies
105 // inside the drawn region. They agree where the island is well off the
106 // ridge and diverge where the region also covers beam tail.
107 std::cout
108 << Form(" [region] reac %2d: beam (%.3f, %.3f) s(%.3f, %.3f) "
109 "rho %+.2f | (a,n) (%.3f, %.3f) s(%.3f, %.3f) rho %+.2f "
110 "| attributed %.0f, in region %.0f; (a,a') in region %.0f",
111 reac, fit.beam.mx, fit.beam.my, fit.beam.sx, fit.beam.sy,
112 fit.beam.rho, fit.reac.mx, fit.reac.my, fit.reac.sx,
113 fit.reac.sy, fit.reac.rho, fit.n_reac, nAn, nAa)
114 << std::endl;
115 }
116 RegionCutStore::Save(reac, an, aa, band ? -1.0 : fit.n_reac);
117 RegionCutStore::SaveFit(reac, fit);
118 RegionCutFinder::SaveFigures(h, reac, fit, an, aa, "compute_regions");
119 delete an;
120 delete aa;
121 nOk++;
122 }
123 f.Close();
124 std::cout << "compute-regions: regions for " << nOk << " of " << nTried
125 << " reaction strips" << std::endl;
126 return nOk > 0 ? 0 : 1;
127}
The dataset configuration, and how it is layered.
The reaction search: strip-sum scatters, beam gating and tagging.
static TString ResultsDir()
Absolute path to the directory receiving generated output.
Definition Paths.cpp:24
static TString CacheName()
Filename of the scatter cache for this configuration.
int main()
const DatasetConfig & cfg
The active dataset's configuration, flat block.
RegionFit FitMixture(TH2F *scatter, Int_t reac, Double_t x_lo, Double_t x_hi, Double_t y_lo, Double_t y_hi)
Fit the two-component mixture to one strip's scatter.
TCutG * EllipseCut(const char *name, const Gauss2D &g, Double_t nsigma, Int_t npts=64)
Closed polygon of a component's Mahalanobis contour.
TCutG * RidgeBandCut(const char *name, const Gauss2D &beam, Double_t nsig_lo, Double_t nsig_hi, Double_t x_lo, Double_t x_hi, Double_t y_lo, Double_t y_hi)
Closed polygon of a band above the beam ridge.
void SaveFigures(TH2F *scatter, Int_t reac, const RegionFit &fit, TCutG *an, TCutG *aa, const TString &subdir)
Save the diagnostic figures for a strip's regions.
RegionFit FitBeam(TH2F *scatter, Int_t reac, Double_t x_lo, Double_t x_hi, Double_t y_lo, Double_t y_hi)
Fit the beam component alone, with no reaction component.
Double_t CountInside(TH2F *scatter, TCutG *cut, const RegionFit &fit)
Count scatter events inside a cut.
void Save(Int_t reac, TCutG *cut_an, TCutG *cut_aa, Double_t n_an_assigned=-1.0)
Write a strip's two region cuts.
void SaveFit(Int_t reac, const RegionFit &fit)
Store the fitted components beside the (a,n) cut.
Double_t mx
Mean in x.
Double_t sx
Width in x.
Double_t rho
x-y correlation, in [-1, 1].
Double_t sy
Width in y.
Double_t my
Mean in y.
Result of fitting the two-component mixture to one strip's scatter.
Double_t n_reac
TString why
Why the fit failed; set only when ok is false.
Bool_t ok
Whether the fit succeeded. Check this first.
Gauss2D reac
The reaction population above the ridge.
Gauss2D beam
The beam-like population, pinned from its own core.
Everything governing the reaction search in the strip-sum scatters.
Definition Constants.hpp:53
Double_t X_DISPLAY_MIN
Display-only windows for the strip-sum scatters (a.u.): the histograms are built over the fixed Scatt...
AnRegionMode AN_REGION_MODE
Double_t AN_REGION_NSIGMA
compute-regions: the (a,n) region is the reaction component's AN_REGION_NSIGMA Mahalanobis ellipse fr...
std::map< Int_t, std::pair< Double_t, Double_t > > Y_DISPLAY_RANGE
Per-reaction-strip y-axis display windows, overriding Y_DISPLAY_MIN/MAX for individual strips (displa...