GRSISort "v4.0.0.5"
An extension of the ROOT analysis Framework
Loading...
Searching...
No Matches
TFragmentMap.cxx
Go to the documentation of this file.
1#include "TFragmentMap.h"
2
3#include <iterator>
4
5bool TFragmentMap::fDebug = false;
6
8 std::vector<std::shared_ptr<ThreadsafeQueue<std::shared_ptr<const TFragment>>>>& goodOutputQueue,
9 std::shared_ptr<ThreadsafeQueue<std::shared_ptr<const TBadFragment>>>& badOutputQueue)
10 : fGoodOutputQueue(goodOutputQueue), fBadOutputQueue(badOutputQueue)
11{
12}
13
14bool TFragmentMap::Add(const std::shared_ptr<TFragment>& frag, const std::vector<Int_t>& charge,
15 const std::vector<Short_t>& integrationLength)
16{
17 if(fDebug) {
18 std::cout << "Adding fragment " << frag << " (address " << frag->GetAddress() << " , # pileups "
19 << frag->GetNumberOfPileups() << ") with " << charge.size() << " charges and "
20 << integrationLength.size() << " k-values:" << std::endl;
21 for(size_t i = 0; i < charge.size() && i < integrationLength.size(); ++i) {
22 std::cout << "\t" << charge[i] << ",\t" << integrationLength[i] << std::endl;
23 }
24 }
25 // a single fragment with just one charge/integration length can be directly put into the queue
26 if(charge.size() == 1 && fMap.count(frag->GetAddress()) == 0) {
27 frag->SetCharge(charge[0]);
28 frag->SetKValue(integrationLength[0]);
29 if(fDebug) {
30 std::cout << "address " << frag->GetAddress() << ": added single fragment " << frag << std::endl;
31 }
32 if(fDebug && integrationLength[0] != 700) {
33 std::cout << "single fragment (address " << hex(frag->GetAddress(), 4) << ") with integration length "
34 << integrationLength[0] << ", # pileups " << frag->GetNumberOfPileups() << std::endl;
35 if(frag->GetNumberOfPileups() > 1) {
36 std::cout << "have fragments:" << std::endl;
37 for(auto& iter : fMap) {
38 std::cout << "\t" << hex(std::get<0>(iter.second)->GetAddress(), 4) << ": "
39 << std::get<0>(iter.second)->GetNumberOfPileups() << std::endl;
40 }
41 }
42 }
43 frag->SetEntryNumber();
44 for(const auto& outputQueue : fGoodOutputQueue) {
45 outputQueue->Push(frag);
46 }
47 return true;
48 }
49 // check if this is the last fragment needed
50 size_t nofFrags = 1;
51 size_t nofCharges = charge.size();
52 // equal_range returns a pair of iterators:
53 // the first points to the first fragment with this address,
54 // the second to the first fragment of the next address
55 // if no fragment with this address exists, both point to the first fragment of the next address
56 auto range = fMap.equal_range(frag->GetAddress());
57 for(auto it = range.first; it != range.second; ++it) {
58 ++nofFrags;
59 nofCharges += std::get<1>((*it).second).size();
60 }
61 // not the last fragment:
62 if(nofCharges != 2 * nofFrags - 1) {
63 // we need to insert this element into the map, and thanks to equal_range we already know where
64 if(fDebug) {
65 std::cout << "address " << frag->GetAddress() << ": inserting fragment " << frag << " with " << charge.size() << " charges" << std::endl;
66 }
67 if(range.first != range.second) {
68 fMap.insert(
69 range.second,
70 std::pair<UInt_t, std::tuple<std::shared_ptr<TFragment>, std::vector<Int_t>, std::vector<Short_t>>>(
71 frag->GetAddress(), std::make_tuple(frag, charge, integrationLength)));
72 } else {
73 fMap.insert(
74 std::pair<UInt_t, std::tuple<std::shared_ptr<TFragment>, std::vector<Int_t>, std::vector<Short_t>>>(
75 frag->GetAddress(), std::make_tuple(frag, charge, integrationLength)));
76 }
77 if(fDebug) {
78 std::cout << "done" << std::endl;
79 }
80 return true;
81 }
82 if(fDebug) {
83 std::cout << "address " << frag->GetAddress() << ": last fragment found, calculating charges for " << nofFrags
84 << " fragments" << std::endl;
85 }
86 // last fragment:
87 // now we can loop over the stored fragments and the current fragment and calculate all charges
88 std::vector<std::shared_ptr<TFragment>> frags; // all fragments
89 std::vector<Long_t> kValues; // all integration lengths
90 std::vector<Float_t> charges; // all charges (not integrated charges, but integrated charge divided by integration length!)
91 int situation = -1; // flag to select different scenarios for the time sequence of multiple hits
92 switch(nofFrags) {
93 case 2: // only one option: (2, 1)
94 {
95 if(charge.size() != 1) {
96 DropFragments(range);
97 if(fDebug) {
98 std::cout << "2 w/o single charge" << std::endl;
99 }
100 return false;
101 }
102 // create and fill the vector of fragments
103 frags.push_back(std::get<0>((*(range.first)).second));
104 frags.push_back(frag);
105 // create and fill the vector of all integration lengths
106 if(fDebug) {
107 std::cout << "inserting ... " << std::endl;
108 }
109 kValues.insert(kValues.begin(), std::get<2>((*(range.first)).second).begin(), std::get<2>((*(range.first)).second).end());
110 if(fDebug) {
111 std::cout << "done" << std::endl;
112 }
113 kValues.push_back(integrationLength[0]);
114 // create and fill the vector of all charges
115 // we need the actual charges, not the integrated ones, so we calculate them now
116 int dropped = -1;
117 for(size_t i = 0; i < std::get<1>((*(range.first)).second).size(); ++i) {
118 if(kValues[i] > 0) {
119 charges.push_back((static_cast<float>(std::get<1>((*(range.first)).second)[i]) + static_cast<float>(gRandom->Uniform())) / static_cast<float>(kValues[i]));
120 if(fDebug) {
121 std::cout << "2, " << i << ": " << hex(std::get<1>((*(range.first)).second)[i]) << "/" << hex(kValues[i])
122 << " = " << (std::get<1>((*(range.first)).second)[i] + gRandom->Uniform())
123 << "/" << kValues[i] << " = " << charges.back() << std::endl;
124 }
125 } else {
126 // drop this charge, it's no good
127 if(dropped >= 0) { // we've already dropped one, so we don't have enough left
128 DropFragments(range);
129 if(fDebug) {
130 std::cout << "2 too much dropped" << std::endl;
131 }
132 return false;
133 }
134 if(fDebug) {
135 std::cout << "2, dropping " << i << std::endl;
136 }
137 dropped = static_cast<int>(i);
138 }
139 }
140 if(dropped >= 0 && integrationLength[0] <= 0) { // we've already dropped one, so we don't have enough left
141 DropFragments(range);
142 if(fDebug) {
143 std::cout << "2 too much dropped (end)" << std::endl;
144 }
145 return false;
146 }
147 if(integrationLength[0] <= 0) {
148 dropped = 2;
149 }
150 // we've dropped one, so we use the other two charges to set the fragment charges directly
151 // this should never happen, if the two hits are too close to get an integration of their individual charges, we
152 // don't see them as two hits (and we would miss both of them)
153 // if they are too far apart to get an integration of their sum, they're not piled up
154 if(fDebug) {
155 std::cout << "dropped = " << dropped << ", charges.size() = " << charges.size() << std::endl;
156 }
157 switch(dropped) {
158 case 0: // dropped e0, so only e0+e1 and e1 are left
159 frags[0]->SetCharge(charges[0] * static_cast<float>(integrationLength[0] - charge[0]));
160 frags[1]->SetCharge(charge[0]);
161 frags[0]->SetKValue(integrationLength[0]);
162 frags[1]->SetKValue(integrationLength[1]);
163 frags[0]->SetNumberOfPileups(-200);
164 frags[1]->SetNumberOfPileups(-201);
165 break;
166 case 1: // dropped e0+e1, so only e0 and e1 are left
167 frags[0]->SetCharge(charges[0] * static_cast<float>(integrationLength[0]));
168 frags[1]->SetCharge(charge[0]);
169 frags[0]->SetKValue(integrationLength[0]);
170 frags[1]->SetKValue(integrationLength[1]);
171 frags[0]->SetNumberOfPileups(-200);
172 frags[1]->SetNumberOfPileups(-201);
173 break;
174 case 2: // dropped e1, so only e0 and e0+e1 are left
175 frags[0]->SetCharge(charges[0] * static_cast<float>(integrationLength[0]));
176 frags[1]->SetCharge((charges[1] - charges[0]) * static_cast<float>(integrationLength[0]));
177 frags[0]->SetKValue(integrationLength[0]);
178 frags[1]->SetKValue(integrationLength[1]);
179 frags[0]->SetNumberOfPileups(-200);
180 frags[1]->SetNumberOfPileups(-201);
181 break;
182 default: // dropped none
183 charges.push_back(static_cast<float>(charge[0] + gRandom->Uniform()) / static_cast<float>(integrationLength[0]));
184 if(fDebug) {
185 std::cout << "2, -: " << hex(charge[0]) << "/" << hex(integrationLength[0]) << " = "
186 << (charge[0] + gRandom->Uniform()) << "/" << integrationLength[0] << " = " << charges.back()
187 << std::endl;
188 }
189 Solve(frags, charges, kValues);
190 break;
191 }
192 } break;
193 case 3: // two options: (3, 1, 1), (2, 2, 1)
194 {
195 if(charge.size() != 1) {
196 DropFragments(range);
197 if(fDebug) {
198 std::cout << "3 w/o single charge" << std::endl;
199 }
200 return false;
201 }
202 // create and fill the vector of fragments
203 frags.push_back(std::get<0>((*(range.first)).second));
204 frags.push_back(std::get<0>((*std::next(range.first)).second));
205 frags.push_back(frag);
206 // create and fill the vector of all integration lengths
207 if(fDebug) {
208 std::cout << "inserting first ... " << std::endl;
209 }
210 kValues.insert(kValues.begin(), std::get<2>((*(range.first)).second).begin(), std::get<2>((*(range.first)).second).end());
211 if(fDebug) {
212 std::cout << "done" << std::endl;
213 }
214 situation = kValues.size();
215 if(fDebug) {
216 std::cout << "inserting second ... " << std::endl;
217 }
218 kValues.insert(kValues.end(), std::get<2>((*std::next(range.first)).second).begin(),
219 std::get<2>((*std::next(range.first)).second).end());
220 if(fDebug) {
221 std::cout << "done" << std::endl;
222 }
223 kValues.push_back(integrationLength[0]);
224 // create and fill the vector of all charges
225 // we need the actual charges, not the integrated ones, so we calculate them now
226 std::vector<int> dropped;
227 for(size_t i = 0; i < std::get<1>((*(range.first)).second).size(); ++i) {
228 if(kValues[i] > 0) {
229 charges.push_back((static_cast<float>(std::get<1>((*(range.first)).second)[i]) + static_cast<float>(gRandom->Uniform())) / static_cast<float>(kValues[i]));
230 if(fDebug) {
231 std::cout << "3, " << i << ": " << hex(std::get<1>((*(range.first)).second)[i]) << "/"
232 << hex(kValues[i]) << " = " << (std::get<1>((*(range.first)).second)[i] + gRandom->Uniform())
233 << "/" << kValues[i] << " = " << charges.back() << std::endl;
234 }
235 } else {
236 dropped.push_back(i);
237 if(fDebug) {
238 std::cout << "3, dropping " << i << std::endl;
239 }
240 }
241 }
242 for(size_t i = 0; i < std::get<1>((*std::next(range.first)).second).size(); ++i) {
243 if(kValues[i + situation] > 0) {
244 charges.push_back((static_cast<float>(std::get<1>((*std::next(range.first)).second)[i]) + static_cast<float>(gRandom->Uniform())) / static_cast<float>(kValues[i + situation]));
245 if(fDebug) {
246 std::cout << "3, " << i + situation << ": "
247 << hex(std::get<1>((*std::next(range.first)).second)[i]) << "/" << hex(kValues[i + situation])
248 << " = " << (std::get<1>((*std::next(range.first)).second)[i] + gRandom->Uniform()) << "/"
249 << kValues[i + situation] << " = " << charges.back() << std::endl;
250 }
251 } else {
252 dropped.push_back(i + situation);
253 if(fDebug) {
254 std::cout << "dropping " << i + situation << std::endl;
255 }
256 }
257 }
258 if(integrationLength[0] <= 0) {
259 dropped.push_back(4);
260 }
261 switch(dropped.size()) {
262 case 0: // dropped none
263 charges.push_back((static_cast<float>(charge[0]) + static_cast<float>(gRandom->Uniform())) / static_cast<float>(integrationLength[0]));
264 if(fDebug) {
265 std::cout << "3, -: " << hex(charge[0]) << "/" << hex(integrationLength[0]) << " = "
266 << (charge[0] + gRandom->Uniform()) << "/" << integrationLength[0] << " = " << charges.back()
267 << std::endl;
268 }
269 Solve(frags, charges, kValues, situation);
270 break;
271 case 1: // dropped one
272 // don't know how to handle these right now
273 DropFragments(range);
274 if(fDebug) {
275 std::cout << "3, single drop" << std::endl;
276 }
277 return false;
278 break;
279 case 2: // dropped two => as many left as there are fragments
280 DropFragments(range);
281 if(fDebug) {
282 std::cout << "3, double drop" << std::endl;
283 }
284 return false;
285 switch(dropped[0]) {
286 case 0:
287 switch(dropped[1]) {
288 case 1: // e0+e1+e2, e2, e3
289 break;
290 case 2: break;
291 case 3: break;
292 case 4: break;
293 }
294 break;
295 }
296 break;
297 default: // dropped too many
298 DropFragments(range);
299 if(fDebug) {
300 std::cout << "3, dropped too many" << std::endl;
301 }
302 return false;
303 }
304 } break;
305 case 4: // five options: (4, 1, 1, 1), (3, 2, 1, 1), (3, 1, 2, 1), (2, 3, 1, 1), (2, 2, 2, 1)
306 // break;
307 default:
308 // std::cerr<<"address "<<frag->GetAddress()<<": deconvolution of "<<nofCharges<<" charges for "<<nofFrags<<"
309 // fragments not implemented yet!"<<std::endl;
310 DropFragments(range);
311 if(fDebug) {
312 std::cout << "unknown number of fragments " << nofFrags << std::endl;
313 }
314 return false;
315 break;
316 } // switch(nofFrags)
317 // add all fragments to queue
318 int index = 0;
319 for(auto it = range.first; it != range.second; ++it) {
320 frag->SetEntryNumber();
321 for(const auto& outputQueue : fGoodOutputQueue) {
322 outputQueue->Push(std::get<0>((*it).second));
323 }
324 if(fDebug) {
325 std::cout << "Added " << ++index << ". fragment " << std::get<0>((*it).second) << std::endl;
326 }
327 }
328 frag->SetEntryNumber();
329 for(const auto& outputQueue : fGoodOutputQueue) {
330 outputQueue->Push(frag);
331 }
332 if(fDebug) {
333 std::cout << "address " << frag->GetAddress() << ": added last fragment " << frag << std::endl;
334 }
335 // remove these fragments from the map
336 fMap.erase(range.first, range.second);
337
338 return true;
339}
340
341void TFragmentMap::Solve(std::vector<std::shared_ptr<TFragment>> frag, std::vector<Float_t> charges,
342 std::vector<Long_t> kValues, int situation)
343{
344 /// Solves minimization of charges for given integrated charges (charges) and integration lengths (kValues).
345 /// Resulting charges are stored in the provided fragments with a k-value of 1.
346 /// The situation parameter distinguishes between the two different ways 3 hits can pile up with each other:
347 /// 3 - both later hits pile up with the first, any other value - the third hit only piles up with the second hit not the first one.
348
349 // all k's are needed squared so we square all elements of k, cast to float here, because that is what we use later on
350 std::vector<float> kSquared(kValues.size());
351 for(size_t i = 0; i < kValues.size(); ++i) {
352 kSquared[i] = static_cast<float>(kValues[i] * kValues[i]);
353 }
354
355 switch(frag.size()) {
356 case 2:
357 frag[0]->SetCharge((charges[0] * (kSquared[0] * kSquared[1] + kSquared[0] * kSquared[2]) + (charges[1] - charges[2]) * kSquared[1] * kSquared[2]) /
358 (kSquared[0] * kSquared[1] + kSquared[0] * kSquared[2] + kSquared[1] * kSquared[2]) * static_cast<float>(kValues[0]));
359 frag[1]->SetCharge((charges[2] * (kSquared[0] * kSquared[2] + kSquared[1] * kSquared[2]) + (charges[1] - charges[0]) * kSquared[0] * kSquared[1]) /
360 (kSquared[0] * kSquared[1] + kSquared[0] * kSquared[2] + kSquared[1] * kSquared[2]) * static_cast<float>(kValues[1]));
361 frag[0]->SetKValue(kValues[0]);
362 frag[1]->SetKValue(kValues[1]);
363 frag[0]->SetNumberOfPileups(-20);
364 frag[1]->SetNumberOfPileups(-21);
365 if(fDebug) {
366 std::cout << "2: charges " << charges[0] << ", " << charges[1] << ", " << charges[2] << " and squared int. lengths " << kSquared[0]
367 << ", " << kSquared[1] << ", " << kSquared[2] << " => " << frag[0]->GetCharge() << ", " << frag[1]->GetCharge()
368 << std::endl
369 << "\t("
370 << (charges[0] * (kSquared[0] * kSquared[1] + kSquared[0] * kSquared[2]) + (charges[1] - charges[2]) * kSquared[1] * kSquared[2]) /
371 (kSquared[0] * kSquared[1] + kSquared[0] * kSquared[2] + kSquared[1] * kSquared[2])
372 << ", "
373 << (charges[2] * (kSquared[0] * kSquared[2] + kSquared[1] * kSquared[2]) + (charges[1] - charges[0]) * kSquared[0] * kSquared[1]) /
374 (kSquared[0] * kSquared[1] + kSquared[0] * kSquared[2] + kSquared[1] * kSquared[2])
375 << " = " << (charges[0] * (kSquared[0] * kSquared[1] + kSquared[0] * kSquared[2]) + (charges[1] - charges[2]) * kSquared[1] * kSquared[2]) << "/"
376 << (kSquared[0] * kSquared[1] + kSquared[0] * kSquared[2] + kSquared[1] * kSquared[2]) << " = ("
377 << charges[0] * (kSquared[0] * kSquared[1] + kSquared[0] * kSquared[2]) << "+" << (charges[1] - charges[2]) * kSquared[1] * kSquared[2] << ")/("
378 << kSquared[0] * kSquared[1] << "+" << kSquared[0] * kSquared[2] << "+" << kSquared[1] * kSquared[2] << "))" << std::endl
379 << "pileups = " << frag[0]->GetNumberOfPileups() << ", " << frag[1]->GetNumberOfPileups()
380 << std::endl;
381 }
382 break;
383 case 3:
384 if(situation == 3) { //(3, 1, 1)
385 frag[0]->SetCharge(
386 (charges[0] * (kSquared[0] * kSquared[1] * kSquared[2] + kSquared[0] * kSquared[1] * kSquared[3] + kSquared[0] * kSquared[1] * kSquared[4] + kSquared[0] * kSquared[2] * kSquared[4] +
387 kSquared[0] * kSquared[3] * kSquared[4]) +
388 (charges[1] + charges[4]) * kSquared[1] * kSquared[3] * kSquared[4] + charges[2] * (kSquared[1] * kSquared[2] * kSquared[3] + kSquared[2] * kSquared[3] * kSquared[4]) -
389 charges[3] * (kSquared[1] * kSquared[2] * kSquared[3] + kSquared[1] * kSquared[3] * kSquared[4] + kSquared[2] * kSquared[3] * kSquared[4])) /
390 (kSquared[0] * kSquared[1] * kSquared[2] + kSquared[0] * kSquared[1] * kSquared[3] + kSquared[0] * kSquared[1] * kSquared[4] + kSquared[0] * kSquared[2] * kSquared[4] +
391 kSquared[0] * kSquared[3] * kSquared[4] + kSquared[1] * kSquared[2] * kSquared[3] + kSquared[1] * kSquared[3] * kSquared[4] + kSquared[2] * kSquared[3] * kSquared[4]) *
392 static_cast<float>(kValues[0]));
393 frag[1]->SetCharge(
394 (charges[0] * (kSquared[0] * kSquared[1] * kSquared[2] + kSquared[0] * kSquared[1] * kSquared[3] + kSquared[0] * kSquared[1] * kSquared[4] + kSquared[0] * kSquared[2] * kSquared[4]) -
395 charges[1] * (kSquared[0] * kSquared[1] * kSquared[2] + kSquared[0] * kSquared[1] * kSquared[3] + kSquared[0] * kSquared[1] * kSquared[4] + kSquared[1] * kSquared[2] * kSquared[3]) +
396 charges[2] * (kSquared[1] * kSquared[2] * kSquared[3] - kSquared[0] * kSquared[2] * kSquared[4]) -
397 charges[3] * (kSquared[0] * kSquared[3] * kSquared[4] + kSquared[1] * kSquared[2] * kSquared[3] + kSquared[1] * kSquared[3] * kSquared[4] + kSquared[2] * kSquared[3] * kSquared[4]) +
398 charges[4] * (kSquared[0] * kSquared[2] * kSquared[4] + kSquared[0] * kSquared[3] * kSquared[4] + kSquared[1] * kSquared[3] * kSquared[4] + kSquared[2] * kSquared[3] * kSquared[4])) /
399 (kSquared[0] * kSquared[1] * kSquared[2] + kSquared[0] * kSquared[1] * kSquared[3] + kSquared[0] * kSquared[1] * kSquared[4] + kSquared[0] * kSquared[2] * kSquared[4] +
400 kSquared[0] * kSquared[3] * kSquared[4] + kSquared[1] * kSquared[2] * kSquared[3] + kSquared[1] * kSquared[3] * kSquared[4] + kSquared[2] * kSquared[3] * kSquared[4]) *
401 static_cast<float>(kValues[1]));
402 frag[2]->SetCharge(((charges[0] + charges[3]) * kSquared[0] * kSquared[1] * kSquared[3] +
403 charges[1] * (kSquared[0] * kSquared[1] * kSquared[2] + kSquared[0] * kSquared[1] * kSquared[3] + kSquared[1] * kSquared[2] * kSquared[3]) +
404 charges[2] * (kSquared[0] * kSquared[1] * kSquared[2] + kSquared[1] * kSquared[2] * kSquared[3]) +
405 charges[4] * (kSquared[0] * kSquared[1] * kSquared[4] + kSquared[0] * kSquared[2] * kSquared[4] + kSquared[0] * kSquared[3] * kSquared[4] +
406 kSquared[1] * kSquared[3] * kSquared[4] + kSquared[2] * kSquared[3] * kSquared[4])) /
407 (kSquared[0] * kSquared[1] * kSquared[2] + kSquared[0] * kSquared[1] * kSquared[3] + kSquared[0] * kSquared[1] * kSquared[4] +
408 kSquared[0] * kSquared[2] * kSquared[4] + kSquared[0] * kSquared[3] * kSquared[4] + kSquared[1] * kSquared[2] * kSquared[3] +
409 kSquared[1] * kSquared[3] * kSquared[4] + kSquared[2] * kSquared[3] * kSquared[4]) *
410 static_cast<float>(kValues[2]));
411 } else { //(2, 2, 1)
412 frag[0]->SetCharge(
413 (charges[0] * (kSquared[0] * kSquared[1] * kSquared[3] + kSquared[0] * kSquared[1] * kSquared[4] + kSquared[0] * kSquared[2] * kSquared[3] + kSquared[0] * kSquared[2] * kSquared[4] +
414 kSquared[0] * kSquared[3] * kSquared[4]) +
415 charges[1] * (kSquared[1] * kSquared[2] * kSquared[3] + kSquared[1] * kSquared[2] * kSquared[4] + kSquared[1] * kSquared[3] * kSquared[4]) -
416 charges[2] * (kSquared[1] * kSquared[2] * kSquared[3] + kSquared[1] * kSquared[2] * kSquared[4]) - (charges[3] - charges[4]) * kSquared[1] * kSquared[3] * kSquared[4]) /
417 (kSquared[0] * kSquared[1] * kSquared[3] + kSquared[0] * kSquared[1] * kSquared[4] + kSquared[0] * kSquared[2] * kSquared[3] + kSquared[0] * kSquared[2] * kSquared[4] +
418 kSquared[0] * kSquared[3] * kSquared[4] + kSquared[1] * kSquared[2] * kSquared[3] + kSquared[1] * kSquared[2] * kSquared[4] + kSquared[1] * kSquared[3] * kSquared[4]) *
419 static_cast<float>(kValues[0]));
420 frag[1]->SetCharge(
421 -(charges[0] * kSquared[0] * kSquared[1] * kSquared[3] + charges[0] * kSquared[0] * kSquared[1] * kSquared[4] - charges[1] * kSquared[0] * kSquared[1] * kSquared[3] -
422 charges[1] * kSquared[0] * kSquared[1] * kSquared[4] - charges[2] * kSquared[0] * kSquared[2] * kSquared[3] - charges[2] * kSquared[0] * kSquared[2] * kSquared[4] -
423 charges[2] * kSquared[1] * kSquared[2] * kSquared[3] - charges[2] * kSquared[1] * kSquared[2] * kSquared[4] - charges[3] * kSquared[0] * kSquared[3] * kSquared[4] -
424 charges[3] * kSquared[1] * kSquared[3] * kSquared[4] + charges[4] * kSquared[0] * kSquared[3] * kSquared[4] + charges[4] * kSquared[1] * kSquared[3] * kSquared[4]) /
425 (kSquared[0] * kSquared[1] * kSquared[3] + kSquared[0] * kSquared[1] * kSquared[4] + kSquared[0] * kSquared[2] * kSquared[3] + kSquared[0] * kSquared[2] * kSquared[4] +
426 kSquared[0] * kSquared[3] * kSquared[4] + kSquared[1] * kSquared[2] * kSquared[3] + kSquared[1] * kSquared[2] * kSquared[4] + kSquared[1] * kSquared[3] * kSquared[4]) *
427 static_cast<float>(kValues[1]));
428 frag[2]->SetCharge(
429 (charges[0] * kSquared[0] * kSquared[1] * kSquared[3] - charges[1] * kSquared[0] * kSquared[1] * kSquared[3] - charges[2] * kSquared[0] * kSquared[2] * kSquared[3] -
430 charges[2] * kSquared[1] * kSquared[2] * kSquared[3] + charges[3] * kSquared[0] * kSquared[1] * kSquared[3] + charges[3] * kSquared[0] * kSquared[2] * kSquared[3] +
431 charges[3] * kSquared[1] * kSquared[2] * kSquared[3] + charges[4] * kSquared[0] * kSquared[1] * kSquared[4] + charges[4] * kSquared[0] * kSquared[2] * kSquared[4] +
432 charges[4] * kSquared[0] * kSquared[3] * kSquared[4] + charges[4] * kSquared[1] * kSquared[2] * kSquared[4] + charges[4] * kSquared[1] * kSquared[3] * kSquared[4]) /
433 (kSquared[0] * kSquared[1] * kSquared[3] + kSquared[0] * kSquared[1] * kSquared[4] + kSquared[0] * kSquared[2] * kSquared[3] + kSquared[0] * kSquared[2] * kSquared[4] +
434 kSquared[0] * kSquared[3] * kSquared[4] + kSquared[1] * kSquared[2] * kSquared[3] + kSquared[1] * kSquared[2] * kSquared[4] + kSquared[1] * kSquared[3] * kSquared[4]) *
435 static_cast<float>(kValues[2]));
436 }
437 frag[0]->SetKValue(kValues[0]);
438 frag[1]->SetKValue(kValues[1]);
439 frag[2]->SetKValue(kValues[2]);
440 frag[0]->SetNumberOfPileups(-30);
441 frag[1]->SetNumberOfPileups(-31);
442 frag[2]->SetNumberOfPileups(-32);
443 if(fDebug) {
444 std::cout << "3, situation " << situation << ": charges " << charges[0] << ", " << charges[1] << ", " << charges[2] << ", "
445 << charges[3] << ", " << charges[4] << " and squared int. lengths " << kSquared[0] << ", " << kSquared[1] << ", " << kSquared[2]
446 << ", " << kSquared[3] << ", " << kSquared[4] << " => " << frag[0]->GetCharge() << ", " << frag[1]->GetCharge()
447 << ", " << frag[2]->GetCharge() << std::endl;
448 }
449 break;
450 }
451}
452
454 std::multimap<UInt_t, std::tuple<std::shared_ptr<TFragment>, std::vector<Int_t>, std::vector<Short_t>>>::iterator,
455 std::multimap<UInt_t, std::tuple<std::shared_ptr<TFragment>, std::vector<Int_t>, std::vector<Short_t>>>::iterator>& range)
456{
457 /// put the fragments within the range of the two iterators into the bad output queue
458 for(auto it = range.first; it != range.second; ++it) {
459 //(*it).second is a tuple, with the first element being a shared_ptr<TFragment>
460 // we need to convert this to a shared_ptr<TBadFragment>
461 fBadOutputQueue->Push(std::make_shared<TBadFragment>(*(std::get<0>((*it).second).get())));
462 if(fDebug) {
463 std::cout << "Added bad fragment " << std::get<0>((*it).second) << std::endl;
464 }
465 }
466 fMap.erase(range.first, range.second);
467}
std::string hex(T val, int width=-1)
Definition Globals.h:129
TFragmentMap(std::vector< std::shared_ptr< ThreadsafeQueue< std::shared_ptr< const TFragment > > > > &goodOutputQueue, std::shared_ptr< ThreadsafeQueue< std::shared_ptr< const TBadFragment > > > &badOutputQueue)
bool Add(const std::shared_ptr< TFragment > &, const std::vector< Int_t > &, const std::vector< Short_t > &)
void DropFragments(std::pair< std::multimap< UInt_t, std::tuple< std::shared_ptr< TFragment >, std::vector< Int_t >, std::vector< Short_t > > >::iterator, std::multimap< UInt_t, std::tuple< std::shared_ptr< TFragment >, std::vector< Int_t >, std::vector< Short_t > > >::iterator > &range)
std::vector< std::shared_ptr< ThreadsafeQueue< std::shared_ptr< const TFragment > > > > & fGoodOutputQueue
std::shared_ptr< ThreadsafeQueue< std::shared_ptr< const TBadFragment > > > & fBadOutputQueue
void Solve(std::vector< std::shared_ptr< TFragment > >, std::vector< Float_t >, std::vector< Long_t >, int situation=-1)
std::multimap< UInt_t, std::tuple< std::shared_ptr< TFragment >, std::vector< Int_t >, std::vector< Short_t > > > fMap
static bool fDebug