37 TH1D* binned_histogram =
new TH1D(
"binned_histogram",
38 "Collection of All OpHits;Time (ms);PEs",
42 for (
size_t i = 0; i < binned.size(); ++i)
43 binned_histogram->SetBinContent(i, binned.at(i));
45 TFile f_out(
"output_hist.root",
"RECREATE");
46 binned_histogram->Write();
49 delete binned_histogram;
55 for (
auto const& flash : FlashVector)
56 if (flash.OnBeamTime() == 1)
57 std::cout <<
"OnBeamFlash with time " << flash.Time() << std::endl;
62 std::vector<recob::OpFlash>& FlashVector,
64 double const BinWidth,
67 float const FlashThreshold,
68 float const WidthTolerance,
70 float const TrigCoinc)
73 int initialsize = 6400;
76 std::vector<double> Binned1(initialsize);
77 std::vector<double> Binned2(initialsize);
80 std::vector<std::vector<int>> Contributors1(initialsize);
81 std::vector<std::vector<int>> Contributors2(initialsize);
85 std::vector<int> FlashesInAccumulator1;
86 std::vector<int> FlashesInAccumulator2;
88 double minTime = std::numeric_limits<float>::max();
89 for (
auto const&
hit : HitVector)
90 if (
hit.PeakTime() < minTime) minTime =
hit.PeakTime();
92 for (
auto const&
hit : HitVector) {
94 double peakTime =
hit.PeakTime();
96 unsigned int AccumIndex1 =
GetAccumIndex(peakTime, minTime, BinWidth, 0.0);
98 unsigned int AccumIndex2 =
GetAccumIndex(peakTime, minTime, BinWidth, BinWidth / 2.0);
101 if (AccumIndex2 >= Binned1.size()) {
102 std::cout <<
"Extending vectors to " << AccumIndex2 * 1.2 << std::endl;
103 Binned1.resize(AccumIndex2 * 1.2);
104 Binned2.resize(AccumIndex2 * 1.2);
105 Contributors1.resize(AccumIndex2 * 1.2);
106 Contributors2.resize(AccumIndex2 * 1.2);
109 size_t const hitIndex = &
hit - &HitVector[0];
117 FlashesInAccumulator1);
125 FlashesInAccumulator2);
131 std::vector<std::vector<int>> HitsPerFlash;
134 FlashesInAccumulator2,
146 std::vector<std::vector<int>> RefinedHitsPerFlash;
147 for (
auto const& HitsThisFlash : HitsPerFlash)
149 HitsThisFlash, HitVector, RefinedHitsPerFlash, WidthTolerance, FlashThreshold);
153 for (
auto const& HitsPerFlashVec : RefinedHitsPerFlash)
155 HitsPerFlashVec, HitVector, FlashVector, geom, wireReadoutGeom, ClocksData, TrigCoinc);
163 for (
auto& HitIndicesThisFlash : RefinedHitsPerFlash)
164 AssocList.push_back(HitIndicesThisFlash);
170 double const MinTime,
171 double const BinWidth,
172 double const BinOffset)
174 return static_cast<unsigned int>((PeakTime - MinTime + BinOffset) / BinWidth);
179 unsigned int const& HitIndex,
181 float const FlashThreshold,
182 std::vector<double>& Binned,
184 std::vector<int>& FlashesInAccumulator)
187 Contributors.at(AccumIndex).push_back(HitIndex);
189 Binned.at(AccumIndex) += PE;
192 if (Binned.at(AccumIndex) >= FlashThreshold && (Binned.at(AccumIndex) - PE) < FlashThreshold)
193 FlashesInAccumulator.push_back(AccumIndex);
198 std::vector<int>
const& FlashesInAccumulator,
199 std::vector<double>
const& BinnedPE,
200 int const& Accumulator,
201 std::map<
double, std::map<
int, std::vector<int>>, std::greater<double>>& FlashesBySize)
203 for (
auto const& flash : FlashesInAccumulator)
204 FlashesBySize[BinnedPE.at(flash)][Accumulator].push_back(flash);
210 std::vector<int>
const& HitClaimedByFlash,
211 std::vector<int>& HitsThisFlash)
214 for (
auto const& HitIndex : Contributors.at(Bin))
216 if (HitClaimedByFlash.at(HitIndex) == -1) HitsThisFlash.push_back(HitIndex);
221 std::vector<int>
const& HitsThisFlash,
222 float const FlashThreshold,
224 std::vector<int>& HitClaimedByFlash)
228 for (
auto const& Hit : HitsThisFlash)
229 PE += HitVector.at(Hit).PE();
231 if (PE < FlashThreshold)
return;
234 HitsPerFlash.push_back(HitsThisFlash);
237 for (
auto const& Hit : HitsThisFlash)
238 if (HitClaimedByFlash.at(Hit) == -1) HitClaimedByFlash.at(Hit) = HitsPerFlash.size() - 1;
243 std::vector<int>
const& FlashesInAccumulator2,
244 std::vector<double>
const& Binned1,
245 std::vector<double>
const& Binned2,
246 std::vector<std::vector<int>>
const& Contributors1,
247 std::vector<std::vector<int>>
const& Contributors2,
248 std::vector<recob::OpHit>
const&
HitVector,
250 float const FlashThreshold)
254 std::map<double, std::map<int, std::vector<int>>, std::greater<double>> FlashesBySize;
261 std::vector<int> HitClaimedByFlash(HitVector.size(), -1);
266 for (
auto const& itFlash : FlashesBySize)
268 for (
auto const& itAcc : itFlash.second) {
270 int Accumulator = itAcc.first;
273 for (
auto const& Bin : itAcc.second) {
275 std::vector<int> HitsThisFlash;
277 if (Accumulator == 1)
279 else if (Accumulator == 2)
282 ClaimHits(HitVector, HitsThisFlash, FlashThreshold, HitsPerFlash, HitClaimedByFlash);
292 void FindSeedHit(std::map<
double, std::vector<int>, std::greater<double>>
const& HitsBySize,
293 std::vector<bool>& HitsUsed,
294 std::vector<recob::OpHit>
const&
HitVector,
295 std::vector<int>& HitsThisRefinedFlash,
296 double& PEAccumulated,
297 double& FlashMaxTime,
298 double& FlashMinTime)
300 for (
auto const& itHit : HitsBySize)
301 for (
auto const& HitID : itHit.second) {
303 if (HitsUsed.at(HitID))
continue;
305 PEAccumulated = HitVector.at(HitID).PE();
306 FlashMaxTime = HitVector.at(HitID).PeakTime() + 0.5 * HitVector.at(HitID).Width();
307 FlashMinTime = HitVector.at(HitID).PeakTime() - 0.5 * HitVector.at(HitID).Width();
309 HitsThisRefinedFlash.clear();
310 HitsThisRefinedFlash.push_back(HitID);
312 HitsUsed.at(HitID) =
true;
322 std::vector<bool>& HitsUsed,
324 double const WidthTolerance,
325 std::vector<int>& HitsThisRefinedFlash,
326 double& PEAccumulated,
327 double& FlashMaxTime,
328 double& FlashMinTime)
330 if (HitsUsed.at(HitID))
return;
332 double HitTime = currentHit.
PeakTime();
333 double HitWidth = 0.5 * currentHit.
Width();
334 double FlashTime = 0.5 * (FlashMaxTime + FlashMinTime);
335 double FlashWidth = 0.5 * (FlashMaxTime - FlashMinTime);
337 if (
std::abs(HitTime - FlashTime) > WidthTolerance * (HitWidth + FlashWidth))
return;
339 HitsThisRefinedFlash.push_back(HitID);
340 FlashMaxTime = std::max(FlashMaxTime, HitTime + HitWidth);
341 FlashMinTime = std::min(FlashMinTime, HitTime - HitWidth);
342 PEAccumulated += currentHit.
PE();
343 HitsUsed[HitID] =
true;
349 std::vector<int>
const& HitsThisRefinedFlash,
350 double const PEAccumulated,
351 float const FlashThreshold,
352 std::vector<bool>& HitsUsed)
355 if (PEAccumulated >= FlashThreshold) {
356 RefinedHitsPerFlash.push_back(HitsThisRefinedFlash);
361 if (HitsThisRefinedFlash.size() == 1)
return;
365 hitIterator != HitsThisRefinedFlash.end();
367 HitsUsed.at(*hitIterator) =
false;
373 std::vector<recob::OpHit>
const&
HitVector,
374 std::vector<std::vector<int>>& RefinedHitsPerFlash,
375 float const WidthTolerance,
376 float const FlashThreshold)
380 std::map<double, std::vector<int>, std::greater<double>> HitsBySize;
381 for (
auto const& HitID : HitsThisFlash)
382 HitsBySize[HitVector.at(HitID).PE()].push_back(HitID);
392 std::vector<bool> HitsUsed(HitVector.size(),
false);
393 double PEAccumulated, FlashMaxTime, FlashMinTime;
394 std::vector<int> HitsThisRefinedFlash;
398 HitsThisRefinedFlash.clear();
406 HitsThisRefinedFlash,
411 if (HitsThisRefinedFlash.size() == 0)
return;
414 size_t NHitsThisRefinedFlash = 0;
418 while (NHitsThisRefinedFlash < HitsThisRefinedFlash.size()) {
419 NHitsThisRefinedFlash = HitsThisRefinedFlash.size();
421 for (
auto const& itHit : HitsBySize)
422 for (
auto const& HitID : itHit.second)
427 HitsThisRefinedFlash,
436 RefinedHitsPerFlash, HitsThisRefinedFlash, PEAccumulated, FlashThreshold, HitsUsed);
450 std::vector<double>& PEs)
452 double PEThisHit = currentHit.
PE();
453 double TimeThisHit = currentHit.
PeakTime();
454 if (TimeThisHit > MaxTime) MaxTime = TimeThisHit;
455 if (TimeThisHit < MinTime) MinTime = TimeThisHit;
459 AveTime += PEThisHit * TimeThisHit;
460 FastToTotal += PEThisHit * currentHit.
FastToTotal();
461 AveAbsTime += PEThisHit * currentHit.
PeakTimeAbs();
464 TotalPE += PEThisHit;
465 PEs.at(static_cast<unsigned int>(currentHit.
OpChannel())) += PEThisHit;
472 std::vector<double>& sumw,
473 std::vector<double>& sumw2,
480 double PEThisHit = currentHit.
PE();
486 for (
size_t p = 0; p != wireReadoutGeom.
Nplanes(); ++p) {
489 sumw.at(p) += PEThisHit *
w;
490 sumw2.at(p) += PEThisHit * w *
w;
493 sumy += PEThisHit * xyz.Y();
494 sumy2 += PEThisHit * xyz.Y() * xyz.Y();
495 sumz += PEThisHit * xyz.Z();
496 sumz2 += PEThisHit * xyz.Z() * xyz.Z();
502 if (sum_squared * weights_sum - sum * sum < 0)
505 return std::sqrt(sum_squared * weights_sum - sum * sum) / weights_sum;
510 std::vector<recob::OpHit>
const&
HitVector,
511 std::vector<recob::OpFlash>& FlashVector,
515 float const TrigCoinc)
517 double MaxTime = -std::numeric_limits<double>::max();
518 double MinTime = std::numeric_limits<double>::max();
520 std::vector<double> PEs(wireReadoutGeom.
MaxOpChannel() + 1, 0.0);
521 unsigned int Nplanes = wireReadoutGeom.
Nplanes();
522 std::vector<double> sumw(Nplanes, 0.0);
523 std::vector<double> sumw2(Nplanes, 0.0);
527 double AveAbsTime = 0;
528 double FastToTotal = 0;
534 for (
auto const& HitID : HitsPerFlashVec) {
536 HitVector.at(HitID), MaxTime, MinTime, AveTime, FastToTotal, AveAbsTime, TotalPE, PEs);
538 HitVector.at(HitID), geom, wireReadoutGeom, sumw, sumw2, sumy, sumy2, sumz, sumz2);
542 AveAbsTime /= TotalPE;
543 FastToTotal /= TotalPE;
545 double meany = sumy / TotalPE;
546 double meanz = sumz / TotalPE;
551 std::vector<double> WireCenters(Nplanes, 0.0);
552 std::vector<double> WireWidths(Nplanes, 0.0);
554 for (
size_t p = 0; p != Nplanes; ++p) {
555 WireCenters.at(p) = sumw.at(p) / TotalPE;
556 WireWidths.at(p) =
CalculateWidth(sumw.at(p), sumw2.at(p), TotalPE);
562 if (Frame == 0) Frame = 1;
565 bool InBeamFrame =
false;
566 if (!(ClocksData.
TriggerTime() < 0)) InBeamFrame = (Frame == BeamFrame);
568 double TimeWidth = (MaxTime - MinTime) / 2.0;
571 if (InBeamFrame && (
std::abs(AveTime) < TrigCoinc)) OnBeamTime = 1;
573 FlashVector.emplace_back(AveTime,
597 if (iTime > jTime)
return 1e6;
601 double HypPE = iPE * jWidth / iWidth * std::exp(-(jTime - iTime) / 1.6);
602 double nsigma = (jPE - HypPE) / std::sqrt(HypPE);
608 size_t const BeginFlash,
609 std::vector<bool>& MarkedForRemoval)
611 for (
size_t iFlash = BeginFlash; iFlash != FlashVector.size(); ++iFlash) {
613 double iTime = FlashVector.at(iFlash).Time();
614 double iPE = FlashVector.at(iFlash).TotalPE();
615 double iWidth = FlashVector.at(iFlash).TimeWidth();
617 for (
size_t jFlash = iFlash + 1; jFlash != FlashVector.size(); ++jFlash) {
619 if (MarkedForRemoval.at(jFlash - BeginFlash))
continue;
621 double jTime = FlashVector.at(jFlash).Time();
622 double jPE = FlashVector.at(jFlash).TotalPE();
623 double jWidth = FlashVector.at(jFlash).TimeWidth();
628 MarkedForRemoval.at(jFlash - BeginFlash) =
true;
635 std::vector<recob::OpFlash>& FlashVector,
636 size_t const BeginFlash,
637 std::vector<std::vector<int>>& RefinedHitsPerFlash)
639 for (
int iFlash = MarkedForRemoval.size() - 1; iFlash != -1; --iFlash)
640 if (MarkedForRemoval.at(iFlash)) {
641 RefinedHitsPerFlash.erase(RefinedHitsPerFlash.begin() + iFlash);
642 FlashVector.erase(FlashVector.begin() + BeginFlash + iFlash);
648 std::vector<std::vector<int>>& RefinedHitsPerFlash)
650 std::vector<bool> MarkedForRemoval(RefinedHitsPerFlash.size(),
false);
652 size_t const BeginFlash = FlashVector.size() - RefinedHitsPerFlash.size();
657 auto sort_order =
sort_permutation(FlashVector, BeginFlash, sort_flash_by_time);
662 std::sort(FlashVector.begin() + BeginFlash, FlashVector.end(), sort_flash_by_time);
671 template <
typename T,
typename Compare>
675 std::vector<int> p(vec.size() - offset);
676 std::iota(p.begin(), p.end(), 0);
678 p.begin(), p.end(), [&](
int i,
int j) {
return compare(vec[i + offset], vec[j + offset]); });
683 template <
typename T>
687 std::vector<T> sorted_vec(p.size());
688 std::transform(p.begin(), p.end(), sorted_vec.begin(), [&](
int i) {
return vec[i]; });
void FillHitsThisFlash(std::vector< std::vector< int >> const &Contributors, int const &Bin, std::vector< int > const &HitClaimedByFlash, std::vector< int > &HitsThisFlash)
double FastToTotal() const
void CheckAndStoreFlash(std::vector< std::vector< int >> &RefinedHitsPerFlash, std::vector< int > const &HitsThisRefinedFlash, double const PEAccumulated, float const FlashThreshold, std::vector< bool > &HitsUsed)
WireID NearestWireID(Point_t const &pos) const
Returns the ID of wire closest to the specified position.
The data type to uniquely identify a Plane.
bool isValid
Whether this ID points to a valid element.
void AddHitContribution(recob::OpHit const ¤tHit, double &MaxTime, double &MinTime, double &AveTime, double &FastToTotal, double &AveAbsTime, double &TotalPE, std::vector< double > &PEs)
constexpr auto abs(T v)
Returns the absolute value of the argument.
void RunFlashFinder(std::vector< recob::OpHit > const &HitVector, std::vector< recob::OpFlash > &FlashVector, std::vector< std::vector< int >> &AssocList, double const BinWidth, geo::GeometryCore const &geom, geo::WireReadoutGeom const &wireReadoutGeom, float const FlashThreshold, float const WidthTolerance, detinfo::DetectorClocksData const &ClocksData, float const TrigCoinc)
WireID_t Wire
Index of the wire within its plane.
void apply_permutation(std::vector< T > &vec, std::vector< int > const &p)
constexpr int Frame() const noexcept
Returns the number of the frame containing the clock current time.
void AssignHitsToFlash(std::vector< int > const &FlashesInAccumulator1, std::vector< int > const &FlashesInAccumulator2, std::vector< double > const &Binned1, std::vector< double > const &Binned2, std::vector< std::vector< int >> const &Contributors1, std::vector< std::vector< int >> const &Contributors2, std::vector< recob::OpHit > const &HitVector, std::vector< std::vector< int >> &HitsPerFlash, float const FlashThreshold)
pure virtual base interface for detector clocks
void FindSeedHit(std::map< double, std::vector< int >, std::greater< double >> const &HitsBySize, std::vector< bool > &HitsUsed, std::vector< recob::OpHit > const &HitVector, std::vector< int > &HitsThisRefinedFlash, double &PEAccumulated, double &FlashMaxTime, double &FlashMinTime)
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
Access the description of the physical detector geometry.
OpDetGeo const & OpDetGeoFromOpChannel(unsigned int opChannel) const
Returns the optical detector the specified optical channel belongs.
void MarkFlashesForRemoval(std::vector< recob::OpFlash > const &FlashVector, size_t const BeginFlash, std::vector< bool > &MarkedForRemoval)
double CalculateWidth(double const sum, double const sum_squared, double const weights_sum)
TPCID FindTPCAtPosition(Point_t const &point) const
Returns the ID of the TPC at specified location.
void ClaimHits(std::vector< recob::OpHit > const &HitVector, std::vector< int > const &HitsThisFlash, float const FlashThreshold, std::vector< std::vector< int >> &HitsPerFlash, std::vector< int > &HitClaimedByFlash)
std::function< bool(T const &, T const &)> Compare
Interface for a class providing readout channel mapping to geometry.
std::vector< int > sort_permutation(std::vector< T > const &vec, int offset, Compare compare)
ElecClock const & OpticalClock() const noexcept
Borrow a const Optical clock with time set to Trigger time [us].
void checkOnBeamFlash(std::vector< recob::OpFlash > const &FlashVector)
void FillFlashesBySizeMap(std::vector< int > const &FlashesInAccumulator, std::vector< double > const &BinnedPE, int const &Accumulator, std::map< double, std::map< int, std::vector< int >>, std::greater< double >> &FlashesBySize)
void RemoveLateLight(std::vector< recob::OpFlash > &FlashVector, std::vector< std::vector< int >> &RefinedHitsPerFlash)
void writeHistogram(std::vector< double > const &binned)
The data type to uniquely identify a TPC.
Description of the physical geometry of one entire detector.
Definition of data types for geometry description.
void GetHitGeometryInfo(recob::OpHit const ¤tHit, geo::GeometryCore const &geom, geo::WireReadoutGeom const &wireReadoutGeom, std::vector< double > &sumw, std::vector< double > &sumw2, double &sumy, double &sumy2, double &sumz, double &sumz2)
double TriggerTime() const
Trigger electronics clock time in [us].
Detector simulation of raw signals on wires.
void AddHitToFlash(int const &HitID, std::vector< bool > &HitsUsed, recob::OpHit const ¤tHit, double const WidthTolerance, std::vector< int > &HitsThisRefinedFlash, double &PEAccumulated, double &FlashMaxTime, double &FlashMinTime)
unsigned int Nplanes(TPCID const &tpcid=details::tpc_zero) const
Returns the total number of planes in the specified TPC.
Encapsulate the geometry of an optical detector.
std::vector< art::Ptr< recob::Hit > > HitVector
void RefineHitsInFlash(std::vector< int > const &HitsThisFlash, std::vector< recob::OpHit > const &HitVector, std::vector< std::vector< int >> &RefinedHitsPerFlash, float const WidthTolerance, float const FlashThreshold)
Contains all timing reference information for the detector.
unsigned int MaxOpChannel() const
Largest optical channel number.
unsigned int GetAccumIndex(double const PeakTime, double const MinTime, double const BinWidth, double const BinOffset)
double PeakTimeAbs() const
Class def header for a class ElecClock.
PlaneGeo const & Plane(TPCID const &tpcid, View_t view) const
Returns the specified wire.
void ConstructFlash(std::vector< int > const &HitsPerFlashVec, std::vector< recob::OpHit > const &HitVector, std::vector< recob::OpFlash > &FlashVector, geo::GeometryCore const &geom, geo::WireReadoutGeom const &wireReadoutGeom, detinfo::DetectorClocksData const &ClocksData, float const TrigCoinc)
void RemoveFlashesFromVectors(std::vector< bool > const &MarkedForRemoval, std::vector< recob::OpFlash > &FlashVector, size_t const BeginFlash, std::vector< std::vector< int >> &RefinedHitsPerFlash)
Interface to geometry for wire readouts .
void FillAccumulator(unsigned int const &AccumIndex, unsigned int const &HitIndex, double const PE, float const FlashThreshold, std::vector< double > &Binned, std::vector< std::vector< int >> &Contributors, std::vector< int > &FlashesInAccumulator)
double GetLikelihoodLateLight(double const iPE, double const iTime, double const iWidth, double const jPE, double const jTime, double const jWidth)