36 TH1D* binned_histogram =
new TH1D(
"binned_histogram",
37 "Collection of All OpHits;Time (ms);PEs",
41 for (
size_t i = 0; i < binned.size(); ++i)
42 binned_histogram->SetBinContent(i, binned.at(i));
44 TFile f_out(
"output_hist.root",
"RECREATE");
45 binned_histogram->Write();
48 delete binned_histogram;
54 for (
auto const& flash : FlashVector)
55 if (flash.OnBeamTime() == 1)
56 std::cout <<
"OnBeamFlash with time " << flash.Time() << std::endl;
61 std::vector<recob::OpFlash>& FlashVector,
63 double const BinWidth,
65 float const FlashThreshold,
66 float const WidthTolerance,
68 float const TrigCoinc)
71 int initialsize = 6400;
74 std::vector<double> Binned1(initialsize);
75 std::vector<double> Binned2(initialsize);
78 std::vector<std::vector<int>> Contributors1(initialsize);
79 std::vector<std::vector<int>> Contributors2(initialsize);
83 std::vector<int> FlashesInAccumulator1;
84 std::vector<int> FlashesInAccumulator2;
86 double minTime = std::numeric_limits<float>::max();
87 for (
auto const&
hit : HitVector)
88 if (
hit.PeakTime() < minTime) minTime =
hit.PeakTime();
90 for (
auto const&
hit : HitVector) {
92 double peakTime =
hit.PeakTime();
94 unsigned int AccumIndex1 =
GetAccumIndex(peakTime, minTime, BinWidth, 0.0);
96 unsigned int AccumIndex2 =
GetAccumIndex(peakTime, minTime, BinWidth, BinWidth / 2.0);
99 if (AccumIndex2 >= Binned1.size()) {
100 std::cout <<
"Extending vectors to " << AccumIndex2 * 1.2 << std::endl;
101 Binned1.resize(AccumIndex2 * 1.2);
102 Binned2.resize(AccumIndex2 * 1.2);
103 Contributors1.resize(AccumIndex2 * 1.2);
104 Contributors2.resize(AccumIndex2 * 1.2);
107 size_t const hitIndex = &
hit - &HitVector[0];
115 FlashesInAccumulator1);
123 FlashesInAccumulator2);
129 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)
154 ConstructFlash(HitsPerFlashVec, HitVector, FlashVector, geom, ClocksData, TrigCoinc);
162 for (
auto& HitIndicesThisFlash : RefinedHitsPerFlash)
163 AssocList.push_back(HitIndicesThisFlash);
169 double const MinTime,
170 double const BinWidth,
171 double const BinOffset)
173 return static_cast<unsigned int>((PeakTime - MinTime + BinOffset) / BinWidth);
178 unsigned int const& HitIndex,
180 float const FlashThreshold,
181 std::vector<double>& Binned,
183 std::vector<int>& FlashesInAccumulator)
186 Contributors.at(AccumIndex).push_back(HitIndex);
188 Binned.at(AccumIndex) += PE;
191 if (Binned.at(AccumIndex) >= FlashThreshold && (Binned.at(AccumIndex) - PE) < FlashThreshold)
192 FlashesInAccumulator.push_back(AccumIndex);
197 std::vector<int>
const& FlashesInAccumulator,
198 std::vector<double>
const& BinnedPE,
199 int const& Accumulator,
200 std::map<
double, std::map<
int, std::vector<int>>, std::greater<double>>& FlashesBySize)
202 for (
auto const& flash : FlashesInAccumulator)
203 FlashesBySize[BinnedPE.at(flash)][Accumulator].push_back(flash);
209 std::vector<int>
const& HitClaimedByFlash,
210 std::vector<int>& HitsThisFlash)
213 for (
auto const& HitIndex : Contributors.at(Bin))
215 if (HitClaimedByFlash.at(HitIndex) == -1) HitsThisFlash.push_back(HitIndex);
220 std::vector<int>
const& HitsThisFlash,
221 float const FlashThreshold,
223 std::vector<int>& HitClaimedByFlash)
227 for (
auto const& Hit : HitsThisFlash)
228 PE += HitVector.at(Hit).PE();
230 if (PE < FlashThreshold)
return;
233 HitsPerFlash.push_back(HitsThisFlash);
236 for (
auto const& Hit : HitsThisFlash)
237 if (HitClaimedByFlash.at(Hit) == -1) HitClaimedByFlash.at(Hit) = HitsPerFlash.size() - 1;
242 std::vector<int>
const& FlashesInAccumulator2,
243 std::vector<double>
const& Binned1,
244 std::vector<double>
const& Binned2,
245 std::vector<std::vector<int>>
const& Contributors1,
246 std::vector<std::vector<int>>
const& Contributors2,
247 std::vector<recob::OpHit>
const&
HitVector,
249 float const FlashThreshold)
253 std::map<double, std::map<int, std::vector<int>>, std::greater<double>> FlashesBySize;
260 std::vector<int> HitClaimedByFlash(HitVector.size(), -1);
265 for (
auto const& itFlash : FlashesBySize)
267 for (
auto const& itAcc : itFlash.second) {
269 int Accumulator = itAcc.first;
272 for (
auto const& Bin : itAcc.second) {
274 std::vector<int> HitsThisFlash;
276 if (Accumulator == 1)
278 else if (Accumulator == 2)
281 ClaimHits(HitVector, HitsThisFlash, FlashThreshold, HitsPerFlash, HitClaimedByFlash);
291 void FindSeedHit(std::map<
double, std::vector<int>, std::greater<double>>
const& HitsBySize,
292 std::vector<bool>& HitsUsed,
293 std::vector<recob::OpHit>
const&
HitVector,
294 std::vector<int>& HitsThisRefinedFlash,
295 double& PEAccumulated,
296 double& FlashMaxTime,
297 double& FlashMinTime)
299 for (
auto const& itHit : HitsBySize)
300 for (
auto const& HitID : itHit.second) {
302 if (HitsUsed.at(HitID))
continue;
304 PEAccumulated = HitVector.at(HitID).PE();
305 FlashMaxTime = HitVector.at(HitID).PeakTime() + 0.5 * HitVector.at(HitID).Width();
306 FlashMinTime = HitVector.at(HitID).PeakTime() - 0.5 * HitVector.at(HitID).Width();
308 HitsThisRefinedFlash.clear();
309 HitsThisRefinedFlash.push_back(HitID);
311 HitsUsed.at(HitID) =
true;
321 std::vector<bool>& HitsUsed,
323 double const WidthTolerance,
324 std::vector<int>& HitsThisRefinedFlash,
325 double& PEAccumulated,
326 double& FlashMaxTime,
327 double& FlashMinTime)
329 if (HitsUsed.at(HitID))
return;
331 double HitTime = currentHit.
PeakTime();
332 double HitWidth = 0.5 * currentHit.
Width();
333 double FlashTime = 0.5 * (FlashMaxTime + FlashMinTime);
334 double FlashWidth = 0.5 * (FlashMaxTime - FlashMinTime);
336 if (
std::abs(HitTime - FlashTime) > WidthTolerance * (HitWidth + FlashWidth))
return;
338 HitsThisRefinedFlash.push_back(HitID);
339 FlashMaxTime = std::max(FlashMaxTime, HitTime + HitWidth);
340 FlashMinTime = std::min(FlashMinTime, HitTime - HitWidth);
341 PEAccumulated += currentHit.
PE();
342 HitsUsed[HitID] =
true;
348 std::vector<int>
const& HitsThisRefinedFlash,
349 double const PEAccumulated,
350 float const FlashThreshold,
351 std::vector<bool>& HitsUsed)
354 if (PEAccumulated >= FlashThreshold) {
355 RefinedHitsPerFlash.push_back(HitsThisRefinedFlash);
360 if (HitsThisRefinedFlash.size() == 1)
return;
364 hitIterator != HitsThisRefinedFlash.end();
366 HitsUsed.at(*hitIterator) =
false;
372 std::vector<recob::OpHit>
const&
HitVector,
373 std::vector<std::vector<int>>& RefinedHitsPerFlash,
374 float const WidthTolerance,
375 float const FlashThreshold)
379 std::map<double, std::vector<int>, std::greater<double>> HitsBySize;
380 for (
auto const& HitID : HitsThisFlash)
381 HitsBySize[HitVector.at(HitID).PE()].push_back(HitID);
391 std::vector<bool> HitsUsed(HitVector.size(),
false);
392 double PEAccumulated, FlashMaxTime, FlashMinTime;
393 std::vector<int> HitsThisRefinedFlash;
397 HitsThisRefinedFlash.clear();
405 HitsThisRefinedFlash,
410 if (HitsThisRefinedFlash.size() == 0)
return;
413 size_t NHitsThisRefinedFlash = 0;
417 while (NHitsThisRefinedFlash < HitsThisRefinedFlash.size()) {
418 NHitsThisRefinedFlash = HitsThisRefinedFlash.size();
420 for (
auto const& itHit : HitsBySize)
421 for (
auto const& HitID : itHit.second)
426 HitsThisRefinedFlash,
435 RefinedHitsPerFlash, HitsThisRefinedFlash, PEAccumulated, FlashThreshold, HitsUsed);
449 std::vector<double>& PEs)
451 double PEThisHit = currentHit.
PE();
452 double TimeThisHit = currentHit.
PeakTime();
453 if (TimeThisHit > MaxTime) MaxTime = TimeThisHit;
454 if (TimeThisHit < MinTime) MinTime = TimeThisHit;
458 AveTime += PEThisHit * TimeThisHit;
459 FastToTotal += PEThisHit * currentHit.
FastToTotal();
460 AveAbsTime += PEThisHit * currentHit.
PeakTimeAbs();
463 TotalPE += PEThisHit;
464 PEs.at(static_cast<unsigned int>(currentHit.
OpChannel())) += PEThisHit;
470 std::vector<double>& sumw,
471 std::vector<double>& sumw2,
478 double PEThisHit = currentHit.
PE();
484 for (
size_t p = 0; p != geom.
Nplanes(); ++p) {
487 sumw.at(p) += PEThisHit *
w;
488 sumw2.at(p) += PEThisHit * w *
w;
491 sumy += PEThisHit * xyz.Y();
492 sumy2 += PEThisHit * xyz.Y() * xyz.Y();
493 sumz += PEThisHit * xyz.Z();
494 sumz2 += PEThisHit * xyz.Z() * xyz.Z();
500 if (sum_squared * weights_sum - sum * sum < 0)
503 return std::sqrt(sum_squared * weights_sum - sum * sum) / weights_sum;
508 std::vector<recob::OpHit>
const&
HitVector,
509 std::vector<recob::OpFlash>& FlashVector,
512 float const TrigCoinc)
514 double MaxTime = -std::numeric_limits<double>::max();
515 double MinTime = std::numeric_limits<double>::max();
518 unsigned int Nplanes = geom.
Nplanes();
519 std::vector<double> sumw(Nplanes, 0.0);
520 std::vector<double> sumw2(Nplanes, 0.0);
524 double AveAbsTime = 0;
525 double FastToTotal = 0;
531 for (
auto const& HitID : HitsPerFlashVec) {
533 HitVector.at(HitID), MaxTime, MinTime, AveTime, FastToTotal, AveAbsTime, TotalPE, PEs);
538 AveAbsTime /= TotalPE;
539 FastToTotal /= TotalPE;
541 double meany = sumy / TotalPE;
542 double meanz = sumz / TotalPE;
547 std::vector<double> WireCenters(Nplanes, 0.0);
548 std::vector<double> WireWidths(Nplanes, 0.0);
550 for (
size_t p = 0; p != Nplanes; ++p) {
551 WireCenters.at(p) = sumw.at(p) / TotalPE;
552 WireWidths.at(p) =
CalculateWidth(sumw.at(p), sumw2.at(p), TotalPE);
558 if (Frame == 0) Frame = 1;
561 bool InBeamFrame =
false;
562 if (!(ClocksData.
TriggerTime() < 0)) InBeamFrame = (Frame == BeamFrame);
564 double TimeWidth = (MaxTime - MinTime) / 2.0;
567 if (InBeamFrame && (
std::abs(AveTime) < TrigCoinc)) OnBeamTime = 1;
569 FlashVector.emplace_back(AveTime,
593 if (iTime > jTime)
return 1e6;
597 double HypPE = iPE * jWidth / iWidth * std::exp(-(jTime - iTime) / 1.6);
598 double nsigma = (jPE - HypPE) / std::sqrt(HypPE);
604 size_t const BeginFlash,
605 std::vector<bool>& MarkedForRemoval)
607 for (
size_t iFlash = BeginFlash; iFlash != FlashVector.size(); ++iFlash) {
609 double iTime = FlashVector.at(iFlash).Time();
610 double iPE = FlashVector.at(iFlash).TotalPE();
611 double iWidth = FlashVector.at(iFlash).TimeWidth();
613 for (
size_t jFlash = iFlash + 1; jFlash != FlashVector.size(); ++jFlash) {
615 if (MarkedForRemoval.at(jFlash - BeginFlash))
continue;
617 double jTime = FlashVector.at(jFlash).Time();
618 double jPE = FlashVector.at(jFlash).TotalPE();
619 double jWidth = FlashVector.at(jFlash).TimeWidth();
624 MarkedForRemoval.at(jFlash - BeginFlash) =
true;
631 std::vector<recob::OpFlash>& FlashVector,
632 size_t const BeginFlash,
633 std::vector<std::vector<int>>& RefinedHitsPerFlash)
635 for (
int iFlash = MarkedForRemoval.size() - 1; iFlash != -1; --iFlash)
636 if (MarkedForRemoval.at(iFlash)) {
637 RefinedHitsPerFlash.erase(RefinedHitsPerFlash.begin() + iFlash);
638 FlashVector.erase(FlashVector.begin() + BeginFlash + iFlash);
644 std::vector<std::vector<int>>& RefinedHitsPerFlash)
646 std::vector<bool> MarkedForRemoval(RefinedHitsPerFlash.size(),
false);
648 size_t const BeginFlash = FlashVector.size() - RefinedHitsPerFlash.size();
653 auto sort_order =
sort_permutation(FlashVector, BeginFlash, sort_flash_by_time);
658 std::sort(FlashVector.begin() + BeginFlash, FlashVector.end(), sort_flash_by_time);
667 template <
typename T,
typename Compare>
671 std::vector<int> p(vec.size() - offset);
672 std::iota(p.begin(), p.end(), 0);
674 p.begin(), p.end(), [&](
int i,
int j) {
return compare(vec[i + offset], vec[j + offset]); });
679 template <
typename T>
683 std::vector<T> sorted_vec(p.size());
684 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)
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, float const FlashThreshold, float const WidthTolerance, detinfo::DetectorClocksData const &ClocksData, float const TrigCoinc)
void ConstructFlash(std::vector< int > const &HitsPerFlashVec, std::vector< recob::OpHit > const &HitVector, std::vector< recob::OpFlash > &FlashVector, geo::GeometryCore const &geom, detinfo::DetectorClocksData const &ClocksData, float const TrigCoinc)
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.
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 detector geometry.
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::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)
unsigned int MaxOpChannel() const
Largest optical channel number.
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 geometry of one entire detector.
Definition of data types for geometry description.
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)
Encapsulate the geometry of an optical detector.
std::vector< art::Ptr< recob::Hit > > HitVector
WireID NearestWireID(Point_t const &point, PlaneID const &planeid) const
Returns the ID of wire closest to position in the specified TPC.
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 GetAccumIndex(double const PeakTime, double const MinTime, double const BinWidth, double const BinOffset)
double PeakTimeAbs() const
Class def header for a class ElecClock.
unsigned int Nplanes(TPCID const &tpcid=tpc_zero) const
Returns the total number of planes in the specified TPC.
void GetHitGeometryInfo(recob::OpHit const ¤tHit, geo::GeometryCore const &geom, std::vector< double > &sumw, std::vector< double > &sumw2, double &sumy, double &sumy2, double &sumz, double &sumz2)
void RemoveFlashesFromVectors(std::vector< bool > const &MarkedForRemoval, std::vector< recob::OpFlash > &FlashVector, size_t const BeginFlash, std::vector< std::vector< int >> &RefinedHitsPerFlash)
OpDetGeo const & OpDetGeoFromOpChannel(unsigned int OpChannel) const
Returns the geo::OpDetGeo object for the given channel number.
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)