MUSIC unknown
Analysis for the MUSIC active-target ionization chamber
Loading...
Searching...
No Matches
StripSumScatter.hpp
Go to the documentation of this file.
1#ifndef STRIP_SUM_SCATTER_HPP
2#define STRIP_SUM_SCATTER_HPP
3
4#include "BeamFit2D.hpp"
5#include "Constants.hpp"
6#include "EventsSummary.hpp"
7#include "FileSet.hpp"
8#include "IOUtils.hpp"
9#include "InitUtils.hpp"
10#include "Normalization.hpp"
11#include "PlottingUtils.hpp"
12#include "RemixSim.hpp"
13#include <Rtypes.h>
14#include <TApplication.h>
15#include <TCanvas.h>
16#include <TChain.h>
17#include <TCutG.h>
18#include <TEllipse.h>
19#include <TFile.h>
20#include <TGraph.h>
21#include <TGraphErrors.h>
22#include <TH1F.h>
23#include <TH2F.h>
24#include <TKey.h>
25#include <TLegend.h>
26#include <TMath.h>
27#include <TNamed.h>
28#include <TROOT.h>
29#include <TString.h>
30#include <TSystem.h>
31#include <TTree.h>
32#include <algorithm>
33#include <functional>
34#include <iostream>
35#include <limits>
36#include <map>
37#include <mutex>
38#include <queue>
39#include <stdexcept>
40#include <string>
41#include <thread>
42#include <vector>
43
53
55struct GateSpec {
56 Int_t sx;
57 Int_t sy;
58};
59
74const Double_t kXMin = 0.0;
75const Double_t kXMax = 40.0;
76const Double_t kYMin = 0.0;
77const Double_t kYMax =
78 20.0;
79} // namespace ScatterBuildRange
80
95
103struct TraceEvt {
104 Float_t total[18];
105 Float_t total_adc[18];
112 Float_t long_au[18];
113 Float_t short_au[18];
115
116 UInt_t reac_mask;
117 Bool_t beam_flat;
118 Int_t both_mult;
123 ULong64_t seed_ts;
124};
125
135 std::vector<BeamFit2D> series_gates;
136 Bool_t ok;
138 SingleRunFitResult() : ok(kFALSE) {}
139};
140
147 std::vector<TH2F *> scatters;
148 std::vector<TraceEvt> reservoir;
149 Long64_t gated;
150 Long64_t seen;
155 Long64_t normed;
163 std::vector<Long64_t> normed_at;
165 std::vector<Long64_t> tagged;
168};
169
171struct SimPop {
172 TString file;
173 TString label;
174};
175
189public:
194
200 void Run();
201
207 static TString CacheName();
208
223 static void PlaneXY(const Double_t *total, Int_t reac, Double_t &x,
224 Double_t &y);
229 static Int_t YLoOf(Int_t reac);
232 static Int_t YHiOf(Int_t reac);
241
244 static Double_t JumpSigma(Int_t strip);
247 static Double_t StripSigma(Int_t strip);
250 static void SetJumpSigma(const Double_t *sigma);
253 static void SetStripSigma(const Double_t *sigma);
256 static Double_t JumpMin(Int_t reac);
258
259private:
260 static Double_t s_jumpSigma[18];
261 static Double_t s_stripSigma[18];
262 std::map<Int_t, TH2F *> m_scatter;
263 std::vector<TraceEvt> m_reservoir;
264 // Normalization counts, merged over every run and persisted in the cache so
265 // a cross section can be taken from it without a second pass over the data.
266 Long64_t m_nSeen;
267 Long64_t m_nNormed;
268 std::vector<Long64_t> m_normedAt;
269 std::vector<Long64_t> m_tagged;
270 Double_t m_yLo[64];
271 Double_t m_yHi[64];
272
273 const TString kSimCacheName = "StripSumScatter_simcache.root";
274
275 static Int_t ReacIndex(Int_t reac);
276
277 Bool_t TryLoadCache(const TString &cacheName, const TString &fingerprint);
278 void WriteCache(const TString &cacheName, const TString &fingerprint);
279
280 // Fresh, empty scatters for the configured plane and build range.
281 void AllocateScatters();
282 // Fill the scatters from the reservoir alone. The reservoir keeps every
283 // tagged event, so a plane or axes change needs only this and not a
284 // 25-minute pass over the events files.
285 void ReprojectFromReservoir();
286 void FillScatters(const std::vector<Int_t> &runOrder,
287 std::map<Int_t, TChain *> &chains);
288
289 void PlotScatters();
290
291 // Diagnostic (PLOT_PARITY_REJECTED_GRID): grid #DeltaE of events that pass
292 // the cheap pre-tag cuts and are then rejected by the parity cut. Saves both
293 // an a.u. view (decoded grid) and an ADC view (raw trigger channel), each on
294 // a log-y axis. Reads the Grid branch directly (a self-contained pass), so it
295 // works regardless of whether the scatter cache has already been filled.
296 void PlotParityRejectedGrid(const std::vector<Int_t> &run_order,
297 std::map<Int_t, TChain *> &chains);
298
299 void InteractiveOverlay(Int_t reac);
300
301 static void EnableEventBranches(TChain *chain);
302 static Bool_t AllStripsFired(const EnergyView &ev);
303 static Bool_t IsPureBeam(const EnergyView &ev, const BeamEllipses &be);
304 // Sigma-clipped width of each strip-to-strip difference and of each strip's
305 // deposit over a capped sample of `chain`, after the cheap pre-tag cuts.
306 // False when too few events survive to measure them.
307 static Bool_t MeasureBeamNoise(TChain *chain, Double_t *jump_sigma,
308 Double_t *strip_sigma);
309 // Strips 1..reac-1 within BEAM_UPSTREAM_NSIGMA of the beam, or the
310 // requirement is off. Shared by the tag and its per-strip denominator.
311 static Bool_t BeamUpstreamOf(const EnergyView &ev, Int_t reac);
312 static Bool_t IsPileup(const EnergyView &ev);
313 static Bool_t IsNoise(const EnergyView &ev);
314 static Bool_t IsOffbeam(const EnergyView &ev);
315 static Bool_t IsParityAsymmetric(const EnergyView &ev);
316 static Double_t SumRange(const Double_t *total, Int_t lo, Int_t hi);
317 static std::vector<GateSpec> ActiveGates();
318
319 static Bool_t PassesGate(const BeamFit2D &gate, const EnergyView &ev,
320 Int_t sx, Int_t sy);
321
322 static BeamFit2D FindBeamGate(TChain *chain, Int_t sx, Int_t sy,
323 const std::vector<GateSpec> &prior_specs,
324 const std::vector<BeamFit2D> &prior_gates,
325 const TString &tag, const TString &subdir);
326
327 static void DrawTraceSet(const std::vector<TGraph *> &traces, Int_t color);
328 void DrawAltDecodeRegionTraces(Int_t reac, TCutG *cutAn, TCutG *cutAa);
329 static TGraph *TraceFromTotal(const Float_t *total);
330 static void DrawRegionTraces(const TString &save_name, const TString &subdir,
331 const std::vector<TGraph *> &beam,
332 const std::vector<TGraph *> &aa,
333 const std::vector<TGraph *> &an, Double_t y_min,
334 Double_t y_max, const char *y_title);
335
336 static void DrawRegionMeanTraces(const TString &save_name,
337 const TString &subdir,
338 const std::vector<TGraph *> &beam,
339 const std::vector<TGraph *> &aa,
340 const std::vector<TGraph *> &an,
341 Double_t y_min, Double_t y_max,
342 const char *y_title);
343
344 static void TraceYRange(const std::vector<TGraph *> &beam,
345 const std::vector<TGraph *> &aa,
346 const std::vector<TGraph *> &an, Double_t &y_min,
347 Double_t &y_max);
348 static SingleRunFitResult
349 FitRunGates(Int_t run, TChain *chain,
350 const std::vector<GateSpec> &activeGates);
351 static SingleRunFillResult FillRunScatters(
352 Int_t run, TChain *chain, const std::vector<GateSpec> &activeGates,
353 const std::vector<BeamFit2D> &runGates, const BeamEllipses &runBeam);
354 static TCutG *PromptCut(TCanvas *c, const char *name, const char *label);
355 static void SaveRegionCuts(Int_t reac, TCutG *cut_an, TCutG *cut_aa);
356 static TCutG *LoadRegionCut(const char *name, Int_t reac);
357
358 static void SmoothTrace(const Double_t *in, Double_t *out, Int_t width);
359
360 // Savitzky-Golay smoothing: 3rd-degree polynomial, half-window of 2
361 // (5-point convolution). Uses standard SG coefficients [-3,12,17,12,-3]/35.
362 // At edges, the window shrinks and coefficients are renormalised.
363 static void SavitzkyGolay(const Double_t *in, Double_t *out);
364
365 // CFD-style trigger finder: locate the first strip whose beam-subtracted
366 // signal (td[s]-1) exceeds both a fraction of the trace peak and a multiple
367 // of the beam sigma. Returns the strip index, or -1 if no trigger fires.
368 static Int_t FindTrigger(const Double_t *td, const Double_t *base,
369 Double_t beam_sigma);
370
371 // Build a TGraph from Savitzky-Golay-smoothed per-strip totals. Input is
372 // the raw normed array; smoothing is applied internally before graph build.
373 static TGraph *SmoothedTraceFromTotal(const Float_t *total);
374
375 void ClusterVarHists(Int_t reac, TCutG *cut_aa, TCutG *cut_an,
376 const TString &subdir);
377
378 static TString
379 SimFingerprint(const std::vector<RemixSim::SimFileSpec> &specs);
380 static TString BuildFingerprint(const std::vector<Int_t> &run_order,
381 std::map<Int_t, TChain *> &chains);
382 static void YBounds(Double_t *y_lo, Double_t *y_hi);
383 static TString PrettyLabel(const TString &tag);
384
385public:
397 static Bool_t PassesReaction(const EnergyView &ev, Int_t reac);
398
399private:
400 static Bool_t SimBeamGains(Double_t *gain);
401 static void SimTotal(const Float_t *left, const Float_t *right,
402 const Double_t *gain, Double_t *total);
403 static TGraph *SimPopScatter(const TString &file, Int_t reac,
404 const Double_t *gain, Long64_t max_points);
405 static std::vector<TGraph *>
406 SimPopTraces(const TString &file, const Double_t *gain, Long64_t max_traces);
407 void SimTraceOverlay();
408 static Bool_t LoadSimCache(const TString &fp,
409 std::map<Int_t, std::vector<TGraph *>> &by_strip);
410 static void
411 WriteSimCache(const TString &fp,
412 const std::map<Int_t, std::vector<TGraph *>> &by_strip);
413 void SimOverlay();
414};
415
416#endif
The dataset configuration, and how it is layered.
static TString CacheName()
Filename of the scatter cache for this configuration.
static Int_t YLoOf(Int_t reac)
First strip of the post-trigger window summed onto y.
static void SetStripSigma(const Double_t *sigma)
Install the per-strip sigmas.
static Int_t YHiOf(Int_t reac)
Last strip of the post-trigger window, inclusive.
static Bool_t PassesReaction(const EnergyView &ev, Int_t reac)
Whether an event is tagged as a reaction at a given strip.
static Double_t JumpMin(Int_t reac)
Minimum jump for a tag: REAC_JUMP_NSIGMA * JumpSigma(reac).
static Double_t StripSigma(Int_t strip)
Sigma of a strip's own deposit.
void Run()
Build or load the scatters, tag reactions, and draw everything.
static Double_t JumpSigma(Int_t strip)
Sigma of the strip-to-strip difference total[s] - total[s-1].
StripSumScatter()
Construct with empty scatters and no cache loaded.
~StripSumScatter()
Frees the scatters and the reservoir.
static void PlaneXY(const Double_t *total, Int_t reac, Double_t &x, Double_t &y)
Where an event sits in the scatter plane for a given reaction strip.
static void SetJumpSigma(const Double_t *sigma)
Install the jump sigmas.
The fixed window every strip-sum scatter is built over.
const Double_t kXMin
Lower x bound of the build window.
const Double_t kXMax
Upper x bound; x sums 16 strips.
const Double_t kYMin
Lower y bound.
const Double_t kYMax
Upper y bound; y sums the post-trigger strips only.
The classification ellipses defining a pure-beam event.
BeamFit2D s15_s16
Alternative exit ellipse.
BeamFit2D s0_s1
Entrance ellipse on strips 0 and 1.
Bool_t ok
Whether the fits succeeded.
Bool_t use_s15_s16
Which exit ellipse is in force.
BeamFit2D s16_s17
Exit ellipse on strips 16 and 17.
BeamFit2D s1_s2
Alternative entrance ellipse, per PURE_BEAM_GATE.
A fitted 2-D Gaussian beam spot.
Definition BeamFit2D.hpp:16
A view over one event's energies, decoding raw ADC into calibrated units.
A pair of strips whose sums form one classification plane.
Int_t sx
Strip whose sum forms the x axis.
Int_t sy
Strip whose sum forms the y axis.
One simulated population to overlay on the data.
TString label
Legend label.
TString file
Simulation ROOT file.
One run's filled scatters, reservoir and normalisation counts.
std::vector< Long64_t > normed_at
Per-strip denominator: beam particles that reached that strip under exactly the conditions a reaction...
Long64_t seen
Events examined.
Long64_t normed
Events surviving every cut applied before reaction tagging: the beam gates, the pileup,...
SingleRunFillResult()
Construct with zeroed counters.
Long64_t gated
Events passing the beam gates.
std::vector< Long64_t > tagged
Events tagged at each reaction strip, indexed the same way.
std::vector< TH2F * > scatters
Private clones, one per reaction strip.
std::vector< TraceEvt > reservoir
Tagged events from this run.
One run's fitted beam gates.
std::vector< BeamFit2D > series_gates
One gate per active GateSpec.
SingleRunFitResult()
Construct unfitted.
Bool_t ok
Whether the fits succeeded.
BeamEllipses pure_beam
Entrance and exit ellipses.
One tagged event, kept in the reservoir.
Float_t total[18]
Calibrated per-strip totals.
Int_t both_mult
Split strips (1-16) with both ends above threshold.
Float_t total_adc[18]
Raw, un-normalised ADC sum per strip.
Float_t long_au[18]
Long end of each split strip.
ULong64_t seed_ts
Timestamp of the grid hit that seeded the event, from the events tree.
Bool_t beam_flat
Whether the trace looked flat, i.e. beam-like.
Float_t short_au[18]
Short end.
UInt_t reac_mask
Bit per reaction strip this event was tagged at.