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;
56 for (
auto const& flash : FlashVector)
57 if (flash.OnBeamTime() == 1)
58 std::cout <<
"OnBeamFlash with time " << flash.Time() << std::endl;
64 std::vector<recob::OpFlash>& FlashVector,
66 double const BinWidth,
71 float const TrigCoinc)
74 int initialsize = 6400;
77 std::vector<double> Binned1(initialsize);
78 std::vector<double> Binned2(initialsize);
81 std::vector<std::vector<int>> Contributors1(initialsize);
82 std::vector<std::vector<int>> Contributors2(initialsize);
86 std::vector<int> FlashesInAccumulator1;
87 std::vector<int> FlashesInAccumulator2;
89 double minTime = std::numeric_limits<float>::max();
90 for (
auto const&
hit : HitVector)
91 if (
hit.PeakTime() < minTime) minTime =
hit.PeakTime();
93 for (
auto const&
hit : HitVector) {
95 double peakTime =
hit.PeakTime();
97 unsigned int AccumIndex1 =
GetAccumIndex(peakTime, minTime, BinWidth, 0.0);
99 unsigned int AccumIndex2 =
GetAccumIndex(peakTime, minTime, BinWidth, BinWidth / 2.0);
102 if (AccumIndex2 >= Binned1.size()) {
103 std::cout <<
"Extending vectors to " << AccumIndex2 * 1.2 << std::endl;
104 Binned1.resize(AccumIndex2 * 1.2);
105 Binned2.resize(AccumIndex2 * 1.2);
106 Contributors1.resize(AccumIndex2 * 1.2);
107 Contributors2.resize(AccumIndex2 * 1.2);
110 size_t const hitIndex = &
hit - &HitVector[0];
118 FlashesInAccumulator1);
126 FlashesInAccumulator2);
132 std::vector<std::vector<int>> HitsPerFlash;
137 FlashesInAccumulator2,
149 std::vector<std::vector<int>> RefinedHitsPerFlash;
150 for (
auto const& HitsThisFlash : HitsPerFlash)
152 HitsThisFlash, HitVector, RefinedHitsPerFlash, WidthTolerance, FlashThreshold);
156 for (
auto const& HitsPerFlashVec : RefinedHitsPerFlash)
157 ConstructFlash(HitsPerFlashVec, HitVector, FlashVector, geom, ClocksData, TrigCoinc);
165 for (
auto& HitIndicesThisFlash : RefinedHitsPerFlash)
166 AssocList.push_back(HitIndicesThisFlash);
173 double const MinTime,
174 double const BinWidth,
175 double const BinOffset)
177 return static_cast<unsigned int>((PeakTime - MinTime + BinOffset) / BinWidth);
183 unsigned int const& HitIndex,
186 std::vector<double>& Binned,
188 std::vector<int>& FlashesInAccumulator)
191 Contributors.at(AccumIndex).push_back(HitIndex);
193 Binned.at(AccumIndex) += PE;
196 if (Binned.at(AccumIndex) >= FlashThreshold && (Binned.at(AccumIndex) - PE) < FlashThreshold)
197 FlashesInAccumulator.push_back(AccumIndex);
203 std::vector<int>
const& FlashesInAccumulator,
204 std::vector<double>
const& BinnedPE,
205 int const& Accumulator,
206 std::map<
double, std::map<
int, std::vector<int>>, std::greater<double>>& FlashesBySize)
208 for (
auto const& flash : FlashesInAccumulator)
209 FlashesBySize[BinnedPE.at(flash)][Accumulator].push_back(flash);
216 std::vector<int>
const& HitClaimedByFlash,
217 std::vector<int>& HitsThisFlash)
220 for (
auto const& HitIndex : Contributors.at(Bin))
222 if (HitClaimedByFlash.at(HitIndex) == -1) HitsThisFlash.push_back(HitIndex);
228 std::vector<int>
const& HitsThisFlash,
231 std::vector<int>& HitClaimedByFlash)
235 for (
auto const& Hit : HitsThisFlash)
236 PE += HitVector.at(Hit).PE();
238 if (PE < FlashThreshold)
return;
241 HitsPerFlash.push_back(HitsThisFlash);
244 for (
auto const& Hit : HitsThisFlash)
245 if (HitClaimedByFlash.at(Hit) == -1) HitClaimedByFlash.at(Hit) = HitsPerFlash.size() - 1;
251 std::vector<int>
const& FlashesInAccumulator2,
252 std::vector<double>
const& Binned1,
253 std::vector<double>
const& Binned2,
254 std::vector<std::vector<int>>
const& Contributors1,
255 std::vector<std::vector<int>>
const& Contributors2,
256 std::vector<recob::OpHit>
const&
HitVector,
262 std::map<double, std::map<int, std::vector<int>>, std::greater<double>> FlashesBySize;
269 std::vector<int> HitClaimedByFlash(HitVector.size(), -1);
274 for (
auto const& itFlash : FlashesBySize)
276 for (
auto const& itAcc : itFlash.second) {
278 int Accumulator = itAcc.first;
281 for (
auto const& Bin : itAcc.second) {
283 std::vector<int> HitsThisFlash;
285 if (Accumulator == 1)
287 else if (Accumulator == 2)
290 ClaimHits(HitVector, HitsThisFlash, FlashThreshold, HitsPerFlash, HitClaimedByFlash);
301 FindSeedHit(std::map<
double, std::vector<int>, std::greater<double>>
const& HitsBySize,
302 std::vector<bool>& HitsUsed,
303 std::vector<recob::OpHit>
const&
HitVector,
304 std::vector<int>& HitsThisRefinedFlash,
305 double& PEAccumulated,
306 double& FlashMaxTime,
307 double& FlashMinTime)
309 for (
auto const& itHit : HitsBySize)
310 for (
auto const& HitID : itHit.second) {
312 if (HitsUsed.at(HitID))
continue;
314 PEAccumulated = HitVector.at(HitID).PE();
315 FlashMaxTime = HitVector.at(HitID).PeakTime() + 0.5 * HitVector.at(HitID).Width();
316 FlashMinTime = HitVector.at(HitID).PeakTime() - 0.5 * HitVector.at(HitID).Width();
318 HitsThisRefinedFlash.clear();
319 HitsThisRefinedFlash.push_back(HitID);
321 HitsUsed.at(HitID) =
true;
332 std::vector<bool>& HitsUsed,
335 std::vector<int>& HitsThisRefinedFlash,
336 double& PEAccumulated,
337 double& FlashMaxTime,
338 double& FlashMinTime)
340 if (HitsUsed.at(HitID))
return;
342 double HitTime = currentHit.
PeakTime();
343 double HitWidth = 0.5 * currentHit.
Width();
344 double FlashTime = 0.5 * (FlashMaxTime + FlashMinTime);
345 double FlashWidth = 0.5 * (FlashMaxTime - FlashMinTime);
347 if (
std::abs(HitTime - FlashTime) > WidthTolerance * (HitWidth + FlashWidth))
return;
349 HitsThisRefinedFlash.push_back(HitID);
350 FlashMaxTime = std::max(FlashMaxTime, HitTime + HitWidth);
351 FlashMinTime = std::min(FlashMinTime, HitTime - HitWidth);
352 PEAccumulated += currentHit.
PE();
353 HitsUsed[HitID] =
true;
360 std::vector<int>
const& HitsThisRefinedFlash,
361 double const PEAccumulated,
363 std::vector<bool>& HitsUsed)
366 if (PEAccumulated >= FlashThreshold) {
367 RefinedHitsPerFlash.push_back(HitsThisRefinedFlash);
372 if (HitsThisRefinedFlash.size() == 1)
return;
375 for (std::vector<int>::const_iterator hitIterator = std::next(HitsThisRefinedFlash.begin());
376 hitIterator != HitsThisRefinedFlash.end();
378 HitsUsed.at(*hitIterator) =
false;
385 std::vector<recob::OpHit>
const&
HitVector,
386 std::vector<std::vector<int>>& RefinedHitsPerFlash,
392 std::map<double, std::vector<int>, std::greater<double>> HitsBySize;
393 for (
auto const& HitID : HitsThisFlash)
394 HitsBySize[HitVector.at(HitID).PE()].push_back(HitID);
404 std::vector<bool> HitsUsed(HitVector.size(),
false);
405 double PEAccumulated, FlashMaxTime, FlashMinTime;
406 std::vector<int> HitsThisRefinedFlash;
410 HitsThisRefinedFlash.clear();
418 HitsThisRefinedFlash,
423 if (HitsThisRefinedFlash.size() == 0)
return;
426 size_t NHitsThisRefinedFlash = 0;
430 while (NHitsThisRefinedFlash < HitsThisRefinedFlash.size()) {
431 NHitsThisRefinedFlash = HitsThisRefinedFlash.size();
433 for (
auto const& itHit : HitsBySize)
434 for (
auto const& HitID : itHit.second)
439 HitsThisRefinedFlash,
448 RefinedHitsPerFlash, HitsThisRefinedFlash, PEAccumulated, FlashThreshold, HitsUsed);
463 std::vector<double>& PEs)
465 double PEThisHit = currentHit.
PE();
466 double TimeThisHit = currentHit.
PeakTime();
467 if (TimeThisHit > MaxTime) MaxTime = TimeThisHit;
468 if (TimeThisHit < MinTime) MinTime = TimeThisHit;
472 AveTime += PEThisHit * TimeThisHit;
473 FastToTotal += PEThisHit * currentHit.
FastToTotal();
474 AveAbsTime += PEThisHit * currentHit.
PeakTimeAbs();
477 TotalPE += PEThisHit;
478 PEs.at(static_cast<unsigned int>(currentHit.
OpChannel())) += PEThisHit;
485 std::vector<double>& sumw,
486 std::vector<double>& sumw2,
494 double PEThisHit = currentHit.
PE();
500 for (
size_t p = 0;
p != geom.
Nplanes(); ++
p) {
503 sumw.at(
p) += PEThisHit *
w;
504 sumw2.at(
p) += PEThisHit * w *
w;
507 sumy += PEThisHit * xyz[1];
508 sumy2 += PEThisHit * xyz[1] * xyz[1];
509 sumz += PEThisHit * xyz[2];
510 sumz2 += PEThisHit * xyz[2] * xyz[2];
515 CalculateWidth(
double const sum,
double const sum_squared,
double const weights_sum)
517 if (sum_squared * weights_sum - sum * sum < 0)
520 return std::sqrt(sum_squared * weights_sum - sum * sum) / weights_sum;
526 std::vector<recob::OpHit>
const&
HitVector,
527 std::vector<recob::OpFlash>& FlashVector,
530 float const TrigCoinc)
532 double MaxTime = -std::numeric_limits<double>::max();
533 double MinTime = std::numeric_limits<double>::max();
536 unsigned int Nplanes = geom.
Nplanes();
537 std::vector<double> sumw(Nplanes, 0.0);
538 std::vector<double> sumw2(Nplanes, 0.0);
542 double AveAbsTime = 0;
543 double FastToTotal = 0;
549 for (
auto const& HitID : HitsPerFlashVec) {
551 HitVector.at(HitID), MaxTime, MinTime, AveTime, FastToTotal, AveAbsTime, TotalPE, PEs);
556 AveAbsTime /= TotalPE;
557 FastToTotal /= TotalPE;
559 double meany = sumy / TotalPE;
560 double meanz = sumz / TotalPE;
565 std::vector<double> WireCenters(Nplanes, 0.0);
566 std::vector<double> WireWidths(Nplanes, 0.0);
568 for (
size_t p = 0;
p != Nplanes; ++
p) {
569 WireCenters.at(
p) = sumw.at(
p) / TotalPE;
576 if (Frame == 0) Frame = 1;
579 bool InBeamFrame =
false;
580 if (!(ClocksData.
TriggerTime() < 0)) InBeamFrame = (Frame == BeamFrame);
582 double TimeWidth = (MaxTime - MinTime) / 2.0;
585 if (InBeamFrame && (
std::abs(AveTime) < TrigCoinc)) OnBeamTime = 1;
587 FlashVector.emplace_back(AveTime,
612 if (iTime > jTime)
return 1e6;
616 double HypPE = iPE * jWidth / iWidth *
std::exp(-(jTime - iTime) / 1.6);
617 double nsigma = (jPE - HypPE) / std::sqrt(HypPE);
624 size_t const BeginFlash,
625 std::vector<bool>& MarkedForRemoval)
627 for (
size_t iFlash = BeginFlash; iFlash != FlashVector.size(); ++iFlash) {
629 double iTime = FlashVector.at(iFlash).Time();
630 double iPE = FlashVector.at(iFlash).TotalPE();
631 double iWidth = FlashVector.at(iFlash).TimeWidth();
633 for (
size_t jFlash = iFlash + 1; jFlash != FlashVector.size(); ++jFlash) {
635 if (MarkedForRemoval.at(jFlash - BeginFlash))
continue;
637 double jTime = FlashVector.at(jFlash).Time();
638 double jPE = FlashVector.at(jFlash).TotalPE();
639 double jWidth = FlashVector.at(jFlash).TimeWidth();
644 MarkedForRemoval.at(jFlash - BeginFlash) =
true;
652 std::vector<recob::OpFlash>& FlashVector,
653 size_t const BeginFlash,
654 std::vector<std::vector<int>>& RefinedHitsPerFlash)
656 for (
int iFlash = MarkedForRemoval.size() - 1; iFlash != -1; --iFlash)
657 if (MarkedForRemoval.at(iFlash)) {
658 RefinedHitsPerFlash.erase(RefinedHitsPerFlash.begin() + iFlash);
659 FlashVector.erase(FlashVector.begin() + BeginFlash + iFlash);
666 std::vector<std::vector<int>>& RefinedHitsPerFlash)
668 std::vector<bool> MarkedForRemoval(RefinedHitsPerFlash.size(),
false);
670 size_t const BeginFlash = FlashVector.size() - RefinedHitsPerFlash.size();
675 auto sort_order =
sort_permutation(FlashVector, BeginFlash, sort_flash_by_time);
680 std::sort(FlashVector.begin() + BeginFlash, FlashVector.end(), sort_flash_by_time);
689 template <
typename T,
typename Compare>
694 std::vector<int>
p(vec.size() -
offset);
695 std::iota(
p.begin(),
p.end(), 0);
697 p.begin(),
p.end(), [&](
int i,
int j) {
return compare(vec[i + offset], vec[j + offset]); });
702 template <
typename T>
707 std::vector<T> sorted_vec(p.size());
708 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
BEGIN_PROLOG TPC Trig offset(g4 rise time) ProjectToHeight
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)
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
std::array< float, 2 > HitVector(const recob::Hit &hit, const geo::GeometryCore *geo, const detinfo::DetectorPropertiesData &dprop)
bool Compare(const T &a, const T &b, const std::string &key)
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)
geo::TPCID FindTPCAtPosition(double const worldLoc[3]) const
Returns the ID of the TPC at specified location.
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
Access the description of detector geometry.
unsigned int Nplanes(unsigned int tpc=0, unsigned int cstat=0) const
Returns the total number of wire planes in the specified TPC.
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)
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)
constexpr float FlashThreshold
geo::WireID::WireID_t NearestWire(geo::Point_t const &point, geo::PlaneID const &planeid) const
Returns the index of wire closest to position in the specified TPC.
std::vector< int > sort_permutation(std::vector< T > const &vec, int offset, Compare compare)
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].
ElecClock const & OpticalClock() const noexcept
Borrow a const Optical clock with time set to Trigger time [us].
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.
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.
constexpr double WidthTolerance
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)
BEGIN_PROLOG could also be cout
double GetLikelihoodLateLight(double const iPE, double const iTime, double const iWidth, double const jPE, double const jTime, double const jWidth)