MUSIC unknown
Analysis for the MUSIC active-target ionization chamber
Loading...
Searching...
No Matches
Normalization.cpp
Go to the documentation of this file.
1#include "Normalization.hpp"
2#include <TFile.h>
3#include <TMath.h>
4#include <iostream>
5
6Bool_t EnergyView::Attach(TTree *t) {
7 tree_ = t;
8 if (!t->GetBranch("LeftdE") || !t->GetBranch("Strip0dE"))
9 std::cerr << "EnergyView: events tree has no LeftdE/Strip0dE branches; it "
10 "predates the per-end layout and must be rebuilt through the "
11 "pipeline"
12 << std::endl;
13 t->SetBranchAddress("LeftdE", leftdE_adc);
14 t->SetBranchAddress("RightdE", rightdE_adc);
15 t->SetBranchAddress("Strip0dE", &strip0_adc);
16 t->SetBranchAddress("Strip17dE", &strip17_adc);
17 t->SetBranchAddress("Hits", hits_adc);
18 t->SetBranchAddress("Cathode", &cathode_adc);
19 t->SetBranchAddress("Grid", &grid_adc);
20 // Materialize the first tree so GetCurrentFile() resolves for a TChain (null
21 // until a tree is loaded); this makes is_normed correct after Attach.
22 t->LoadTree(0);
23 LoadGains();
24 loaded_tree_ = t->GetTreeNumber();
25 return is_normed;
26}
27
29 for (Int_t k = 0; k < 16; k++) {
30 gain_left[k] = 0.0f;
31 gain_right[k] = 0.0f;
32 offset_left[k] = 0.0f;
33 offset_right[k] = 0.0f;
34 }
35 for (Int_t s = 0; s < 18; s++) {
36 strip_factor[s] = 1.0f;
37 strip_offset[s] = 0.0f;
38 }
39 gain_strip0 = 0.0f;
40 gain_strip17 = 0.0f;
41 gain_cathode = 0.0f;
42 gain_grid = 0.0f;
43 is_normed = kFALSE;
44 if (!tree_)
45 return;
46 TFile *f = tree_->GetCurrentFile();
47 if (!f)
48 return;
49 TTree *cal = static_cast<TTree *>(f->Get("calibration"));
50 if (!cal || cal->GetEntries() < 1)
51 return;
52 Float_t gl[16] = {0}, gr[16] = {0}, g0 = 0.0f, g17 = 0.0f, gc = 0.0f,
53 gg = 0.0f;
54 Float_t ol[16] = {0}, orr[16] = {0};
55 Float_t sf[18] = {0}, so[18] = {0};
56 cal->SetBranchAddress("GainLeft", gl);
57 cal->SetBranchAddress("GainRight", gr);
58 cal->SetBranchAddress("GainStrip0", &g0);
59 cal->SetBranchAddress("GainStrip17", &g17);
60 cal->SetBranchAddress("GainCathode", &gc);
61 // Absent on files calibrated before the grid had an anchor.
62 if (cal->GetBranch("GainGrid"))
63 cal->SetBranchAddress("GainGrid", &gg);
64 // Per-end offsets are absent on files calibrated before they were
65 // measured; absent -> 0 (no offset).
66 Bool_t has_off = cal->GetBranch("OffsetLeft") != nullptr;
67 if (has_off) {
68 cal->SetBranchAddress("OffsetLeft", ol);
69 cal->SetBranchAddress("OffsetRight", orr);
70 }
71 // StripFactor is optional (added after the initial gain write, filled in by
72 // FindStripCentroidAlignment on the second); absent -> default 1.0 (identity)
73 Bool_t has_factor = cal->GetBranch("StripFactor") != nullptr;
74 if (has_factor)
75 cal->SetBranchAddress("StripFactor", sf);
76 Bool_t has_offset = cal->GetBranch("StripOffset") != nullptr;
77 if (has_offset)
78 cal->SetBranchAddress("StripOffset", so);
79 cal->GetEntry(0);
80 for (Int_t k = 0; k < 16; k++) {
81 gain_left[k] = gl[k];
82 gain_right[k] = gr[k];
83 offset_left[k] = has_off ? ol[k] : 0.0f;
84 offset_right[k] = has_off ? orr[k] : 0.0f;
85 }
86 if (has_factor)
87 for (Int_t s = 0; s < 18; s++)
88 strip_factor[s] = sf[s];
89 if (has_offset)
90 for (Int_t s = 0; s < 18; s++)
91 strip_offset[s] = so[s];
92 gain_strip0 = g0;
93 gain_strip17 = g17;
94 gain_cathode = gc;
95 gain_grid = gg;
96 is_normed = kTRUE;
97}
98
100 // A TChain advances the tree number when GetEntry crosses into a new file,
101 // so reload its gains; plain TTrees report -1 forever and never re-fire.
102 if (tree_) {
103 Int_t tn = tree_->GetTreeNumber();
104 if (tn != loaded_tree_) {
105 LoadGains();
106 loaded_tree_ = tn;
107 }
108 }
109 if (is_normed) {
110 // An end that fired carries its offset; one that did not reads 0 and
111 // stays 0. Clamped at 0 so a reading below the offset is not negative.
112 for (Int_t k = 0; k < 16; k++) {
113 left[k] = leftdE_adc[k] > 0
114 ? Double_t(gain_left[k]) *
115 TMath::Max(0.0, Double_t(leftdE_adc[k]) -
116 Double_t(offset_left[k]))
117 : 0.0;
118 right[k] = rightdE_adc[k] > 0
119 ? Double_t(gain_right[k]) *
120 TMath::Max(0.0, Double_t(rightdE_adc[k]) -
121 Double_t(offset_right[k]))
122 : 0.0;
123 }
124 strip0 = Double_t(gain_strip0) * Double_t(strip0_adc);
125 strip17 = Double_t(gain_strip17) * Double_t(strip17_adc);
126 // The -1 "no cathode" sentinel: uncalibrated/absent -> 0 a.u.
127 cathode = (cathode_adc > 0) ? Double_t(gain_cathode) * Double_t(cathode_adc)
128 : 0.0;
129 // The grid over its modal beam peak (1.0 for a beam event); files
130 // calibrated before it had an anchor fall back to a full-scale fraction.
131 grid = gain_grid > 0.0f ? Double_t(gain_grid) * Double_t(grid_adc)
132 : Double_t(grid_adc) / 16384.0;
133 } else {
134 for (Int_t k = 0; k < 16; k++) {
135 left[k] = Double_t(leftdE_adc[k]);
136 right[k] = Double_t(rightdE_adc[k]);
137 }
138 strip0 = Double_t(strip0_adc);
139 strip17 = Double_t(strip17_adc);
140 cathode = Double_t(cathode_adc);
141 grid = Double_t(grid_adc);
142 }
143 // Long end only: L on odd strips, R on even. Zeroing the short end keeps
144 // Total() the plain sum of the ends.
146 for (Int_t s = 1; s <= 16; s++) {
147 if ((s % 2) != 0)
148 right[s - 1] = 0.0;
149 else
150 left[s - 1] = 0.0;
151 }
152 }
153 // The factor on every end, the offset on the fired long end only:
154 // unfired ends stay 0; on CoMPASS offset on nothing outnumbered the beam.
155 if (is_normed) {
156 for (Int_t s = 1; s <= 16; s++) {
157 left[s - 1] *= Double_t(strip_factor[s]);
158 right[s - 1] *= Double_t(strip_factor[s]);
159 Double_t &long_end = ((s % 2) != 0) ? left[s - 1] : right[s - 1];
160 if (long_end > 0.0)
161 long_end += Double_t(strip_offset[s]);
162 }
163 if (strip0 > 0.0)
164 strip0 = strip0 * Double_t(strip_factor[0]) + Double_t(strip_offset[0]);
165 if (strip17 > 0.0)
166 strip17 =
167 strip17 * Double_t(strip_factor[17]) + Double_t(strip_offset[17]);
168 }
169}
Bool_t ActiveIgnoreShortStrips()
Whether the decode keeps the long end only: the active epoch's setting; with none active,...
Float_t gain_strip0
Strip 0 gain.
UShort_t rightdE_adc[16]
Right end of strips 1-16, index strip - 1.
TTree * tree_
Events tree or chain bound by Attach(). Not owned.
Float_t offset_left[16]
ADC subtracted from an end before its gain, only when that end fired: a short end's energy carries a ...
Float_t offset_right[16]
Double_t strip17
Strip 17.
void Decode()
Decode the currently loaded entry into the value members.
Float_t gain_grid
Grid gain: the reciprocal of its modal beam peak, so the grid reads 1.0 for a beam event.
Short_t cathode_adc
Raw cathode ADC value.
void LoadGains()
Load the calibration gains for the current file.
Float_t strip_offset[18]
Per-strip additive alignment in calibrated units, indexed by strip 0-17.
Int_t loaded_tree_
Tree number whose gains are loaded; -1 for none.
Bool_t Attach(TTree *t)
Bind to an events tree and set up the branch addresses.
Double_t left[16]
Left end of strips 1-16, index strip - 1.
Float_t strip_factor[18]
Per-strip multiplicative alignment, indexed by strip 0-17 and applied to every end of the strip after...
Bool_t is_normed
Whether a calibration tree was found.
Float_t gain_right[16]
Right-end gain of strips 1-16.
UShort_t leftdE_adc[16]
Left end of strips 1-16, index strip - 1.
UShort_t strip17_adc
Strip 17, unsegmented.
Float_t gain_left[16]
Left-end gain of strips 1-16, index strip - 1.
Double_t strip0
Strip 0.
UShort_t strip0_adc
Strip 0, unsegmented.
Double_t right[16]
Right end of strips 1-16, index strip - 1.
Short_t grid_adc
Raw Frisch grid ADC value.
Float_t gain_cathode
Cathode gain.
UShort_t hits_adc[36]
Raw per-slot hit ADC values.
Float_t gain_strip17
Strip 17 gain.
Double_t grid
Grid energy.
Double_t cathode
Cathode energy.