GamR  0.0.0
GammaROOT
Loading...
Searching...
No Matches
Matrix.hh
Go to the documentation of this file.
1#ifndef GAMRSORT_MATRIX_HH
2#define GAMRSORT_MATRIX_HH
3
4#include "Sorter.hh"
5
6#include <regex>
7#include <stdexcept>
8#include <string>
9#include <unordered_map>
10#include <unordered_set>
11#include <vector>
12#include <set>
13
14#include <TTreeReader.h>
15#include <TTreeReaderValue.h>
16
17#include <toolkit/Gate.hh>
18#include <tree/Reader.hh>
19
20namespace GamR {
21namespace Sort {
22namespace Type {
23
24class Matrix {
25public:
26 enum Axis {
27 kCoincidence, // YAxis = DetJ[MeasY]
28 kSum, // YAxis = DetJ[MeasY] + DetI[MeasY]
29 kDiff, // YAxis = DetJ[MeasY] - DetI[MeasY]
30 kProduct, // YAxis = DetJ[MeasY] * DetI[MeasY]
31 kRatio // YAxis = DetJ[MeasY] / DetI[MeasY]
32 };
33
34private:
35 // Typedefs
36 using GroupID_t = size_t;
37 using MeasID_t = size_t;
38 using DetID_t = Int_t; // -1 for wildcard, else could have used a UShort_t
39
40 // Gates
41 // AND across the vector OR within map
42 using Gates_t = std::vector<std::unordered_map<
43 GroupID_t, std::unordered_map<DetID_t, std::unordered_map<MeasID_t,
44 GamR::TK::GateMap>>>>; // woah...
45
46public:
47 // Member variables
48 std::shared_ptr<TH2D> ptrMatrix;
49
50 Gates_t fGates;
51 // std::unordered_set<size_t> gatespassed;
52 std::unordered_map<GroupID_t, size_t> fInNumAndGates;
53 std::vector<std::pair<GroupID_t, MeasID_t>> fReaderMeasurements;
54
55 // Configuration
56 const std::string fPrefix;
57 const GroupID_t fGroupI, fGroupJ;
58 const MeasID_t fMeasX, fMeasY;
60 const size_t GatedSort;
62
63private:
64 // Helper functions
65
66 inline const Bool_t
67 SkipEvent(const GamR::Tree::Reader &myreader, std::map<std::pair<GroupID_t, DetID_t>, Bool_t> &skipdet) const
68 {
69 // All gates must be passed otherwise the gate is skipped and vici
70 // versa
71 std::set<size_t> gatespassed; // the gate groups that passed
72 for (auto &d : skipdet) {
73 d.second = kFALSE;
74 } // assume detectors don't gate
75 // the following detector groups are involved in gates
76 for (const auto &gid_n : fInNumAndGates) {
77 const GroupID_t &itrGroup = gid_n.first;
78 // if a detector group doesn't have enough unique detectors
79 // to pass all of the detectors we should pass immediately
80
81 // if (myreader[itrGroup].NumFired() < gid_n.second) { return kTRUE; } //
82 // not enough data
83
84 // however counting how many unique detectors we need is a bit tricky
85 // skip this optimisation for now
86
87 // across all the gate groups
88 for (size_t idxGate = 0; idxGate < fGates.size(); ++idxGate) {
89 // if there are no gates relevant for this detector group
90 if (!fGates[idxGate].count(itrGroup)) {
91 continue;
92 } else if (gatespassed.count(idxGate)) {
93 continue;
94 } // no point this gate passed
95 else if (gatespassed.size() == fGates.size()) {
96 return kFALSE;
97 } // we're actually done
98
99 // does a detector pass this group?
100 Bool_t pass = kFALSE;
101 // go through all the detectors but break out early if we pass
102 for (size_t idxDet0 = 0; !pass && (idxDet0 < myreader[itrGroup].NumFired()); ++idxDet0) {
103 const DetID_t &itrDet = myreader[itrGroup].ID[idxDet0];
104
105 // If there is gate specific for this detector id check it first
106 if (fGates.at(idxGate).at(itrGroup).count(itrDet)) {
107 for (const auto &m_g : fGates.at(idxGate).at(itrGroup).at(itrDet)) {
108 const MeasID_t &itrMeas = m_g.first;
109 const auto &itrGateMap = m_g.second;
110 if (itrGateMap.PassAny(myreader[itrGroup][itrMeas][idxDet0])) {
111 skipdet[{itrGroup, itrDet}] = kTRUE;
112 pass = kTRUE;
113 gatespassed.insert(idxGate);
114 break;
115 }
116 }
117 }
118 // Otherwise, check if this detector passes the wildcard gate
119 if (!pass && fGates.at(idxGate).at(itrGroup).count(-1)) {
120 for (const auto &m_g : fGates.at(idxGate).at(itrGroup).at(-1)) {
121 const MeasID_t &itrMeas = m_g.first;
122 const auto &itrGateMap = m_g.second;
123 if (itrGateMap.PassAny(myreader[itrGroup][itrMeas][idxDet0])) {
124 skipdet[{itrGroup, itrDet}] = kTRUE;
125 pass = kTRUE;
126 gatespassed.insert(idxGate);
127 break;
128 }
129 }
130 }
131 } // endfor detector
132 } // endfor gates
133 } // endfor detector group
134 if (gatespassed.size() == fGates.size()) {
135 return kFALSE;
136 }
137 return kTRUE;
138 }
139
140 inline const Double_t GetValue(const Matrix::Axis &Axis, const size_t &MeasN,
141 const GamR::Tree::Reader::DetGroup &Group1, const size_t &Det1,
142 const GamR::Tree::Reader::DetGroup &Group2, const size_t &Det2) const
143 {
145 return Group1[MeasN][Det1];
146 } else if (Axis == Matrix::Axis::kSum) {
147 return Group1[MeasN][Det1] + Group2[MeasN][Det2];
148 } else if (Axis == Matrix::Axis::kDiff) {
149 return Group1[MeasN][Det1] - Group2[MeasN][Det2];
150 } else if (Axis == Matrix::Axis::kProduct) {
151 return Group1[MeasN][Det1] * Group2[MeasN][Det2];
152 } else if (Axis == Matrix::Axis::kRatio) {
153 return Group1[MeasN][Det1] / Group2[MeasN][Det2];
154 } else {
155 return -1;
156 }
157 }
158
159 inline const Double_t GetX(const GamR::Tree::Reader &myR, const size_t &Det1, const size_t &Det2) const
160 {
161 return GetValue(XAxis, fMeasX, myR[fGroupI], Det1, myR[fGroupJ], Det2);
162 }
163 inline const Double_t GetY(const GamR::Tree::Reader &myR, const size_t &Det1, const size_t &Det2) const
164 {
165 // note switched order on Y axis
166 return GetValue(YAxis, fMeasY, myR[fGroupJ], Det2, myR[fGroupI], Det1);
167 }
168
169public: // Public Interface
170 Matrix(Sorter *parent, std::string prefix, size_t g1, size_t g2, size_t m1, size_t m2,
171 std::vector<std::string> gates, Matrix::Axis x = Matrix::Axis::kCoincidence,
173 : fGates(gates.size()), fPrefix(prefix), fGroupI(g1), fGroupJ(g2), fMeasX(m1), fMeasY(m2), XAxis(x), YAxis(y),
174 GatedSort(gates.size()), p(parent)
175 {
176
177 // Going to need to read at least these
178 fReaderMeasurements.push_back({fGroupI, fMeasX});
179 fReaderMeasurements.push_back({fGroupI, fMeasY});
180 fReaderMeasurements.push_back({fGroupJ, fMeasX});
181 fReaderMeasurements.push_back({fGroupJ, fMeasY});
182
183 // Need to get the shared matrix
184 std::stringstream ssname;
185 ssname << fPrefix << "_";
186 ssname << "g" << fGroupI << "m" << fMeasX;
187 ssname << "g" << fGroupJ << "m" << fMeasY;
188 ptrMatrix = p->GetMatrix(ssname.str());
189
190 // Extract gates if defined
191 std::cout << std::endl;
192 if (!GatedSort) {
193 std::cout << "No gates defined.";
194 } else {
195 std::cout << "Gates" << std::endl;
196 static const std::regex gateregex("^\\s*([0-9]+).([0-9]+).([0-9*]+) ([0-9]+) ([0-9]+)\\s*$");
197 static std::smatch gatematches;
198
199 std::unordered_map<GroupID_t, std::unordered_set<MeasID_t>> trackmeasurements;
200 for (size_t idxGate = 0; idxGate < gates.size(); ++idxGate) {
201 std::stringstream ss(gates[idxGate]);
202 // extract the gates defined for this gate group
203 std::string gate;
204 size_t n = 0; // sub (OR) gate number
205 std::unordered_set<GroupID_t> groupsingate;
206 while (!ss.eof() && std::getline(ss, gate, '|')) {
207 ++n;
208 std::stringstream key;
209 Bool_t matched = std::regex_match(gate, gatematches, gateregex);
210 // if (!matched) { throw some error }
211 GroupID_t groupid = std::stoi(gatematches[1]);
212 MeasID_t measid = std::stoi(gatematches[2]);
213 DetID_t detid = !gatematches[3].compare("*") ? -1 : std::stoi(gatematches[3]);
214 key << "g" << groupid << "m" << measid << "d";
215 if (detid < 0) {
216 key << "X";
217 } else {
218 key << detid;
219 }
220 fGates[idxGate][groupid][detid][measid].SetName(key.str().c_str());
221 key << "G" << n;
222 fGates[idxGate][groupid][detid][measid][key.str()].SetGate(std::stod(gatematches[4]),
223 std::stod(gatematches[5]));
224 std::cout << "(Group: " << groupid << " Meas: " << measid << " Det: " << gatematches[3];
225 std::cout << " LO: " << gatematches[4] << " HI: " << gatematches[5] << ") ";
226 if (trackmeasurements[groupid].empty() || trackmeasurements[groupid].count(measid)) {
227 groupsingate.emplace(groupid);
228 }
229 trackmeasurements[groupid].emplace(measid);
230 fReaderMeasurements.push_back({groupid, measid});
231 // being lazy and writing to disk each time
232 p->WriteObject(&fGates[idxGate][groupid][detid][measid], ("gates/" + ssname.str()).c_str(), "", kTRUE);
233 } // endwhile each sub (OR) gate
234 for (auto &group : groupsingate) {
235 ++fInNumAndGates[group];
236 }
237 if (idxGate < gates.size() - 1) {
238 std::cout << std::endl << "AND" << std::endl;
239 }
240 TNamed gatestr(("gatestr" + std::to_string(idxGate)).c_str(), gates[idxGate].c_str());
241 p->WriteObject(&gatestr, ("gates/" + ssname.str()).c_str(), "", kTRUE);
242 } // endfor each gate (AND) group
243 for (auto &g_n : fInNumAndGates) {
244 std::cout << std::endl << "Group " << g_n.first << " min required => " << g_n.second;
245 }
246 } // end if GatedSort
247 std::cout << std::endl;
248
249 } // end Sort::Type::Matrix::Matrix(...)
250
251 void operator()(TTreeReader &R)
252 {
253 const auto myR = GamR::Tree::Reader(R, fReaderMeasurements);
254 std::map<std::pair<GroupID_t, DetID_t>, Bool_t> mSkipDetector;
255
256 while (R.Next() && !p->Done()) {
257 p->Tick();
258 // not enough data for a matrix -> insta pass
259 if (myR[fGroupI].NumFired() + myR[fGroupJ].NumFired() < 2) {
260 continue;
261 }
262 if (GatedSort && SkipEvent(myR, mSkipDetector)) {
263 continue;
264 }
265
266 for (size_t idxDet1 = 0; idxDet1 < myR[fGroupI].NumFired(); ++idxDet1) {
267 const auto &DetID1 = myR[fGroupI].ID[idxDet1];
268 if (mSkipDetector[{fGroupI, DetID1}]) {
269 continue;
270 }
271 for (size_t idxDet2 = 0; idxDet2 < myR[fGroupJ].NumFired(); ++idxDet2) {
272 const auto &DetID2 = myR[fGroupJ].ID[idxDet2];
273 if (mSkipDetector[{fGroupJ, DetID2}]) {
274 continue;
275 } else if (DetID1 == DetID2) {
276 continue;
277 } else {
278 ptrMatrix->Fill(GetX(myR, idxDet1, idxDet2), GetY(myR, idxDet1, idxDet2));
279 }
280 }
281 }
282 }
283 } // end Sort::Type::Matrix::operator(...)
284};
285
286} // namespace Type
287} // namespace Sort
288} // namespace GamR
289
290#endif
void ss(std::vector< int > indexes, TCanvas *canvas, Option_t *option)
std::unordered_map< GroupID_t, size_t > fInNumAndGates
Definition Matrix.hh:52
Matrix(Sorter *parent, std::string prefix, size_t g1, size_t g2, size_t m1, size_t m2, std::vector< std::string > gates, Matrix::Axis x=Matrix::Axis::kCoincidence, Matrix::Axis y=Matrix::Axis::kCoincidence)
Definition Matrix.hh:170
const GroupID_t fGroupI
Definition Matrix.hh:57
const MeasID_t fMeasY
Definition Matrix.hh:58
const GroupID_t fGroupJ
Definition Matrix.hh:57
const std::string fPrefix
Definition Matrix.hh:56
std::vector< std::pair< GroupID_t, MeasID_t > > fReaderMeasurements
Definition Matrix.hh:53
const MeasID_t fMeasX
Definition Matrix.hh:58
const size_t GatedSort
Definition Matrix.hh:60
std::shared_ptr< TH2D > ptrMatrix
Definition Matrix.hh:48
void operator()(TTreeReader &R)
Definition Matrix.hh:251
Definition Gain.cc:19