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;
55 for (
auto const& flash : FlashVector)
56 if (flash.OnBeamTime() == 1)
57 std::cout <<
"OnBeamFlash with time " << flash.Time() <<
std::endl;
63 std::vector<recob::OpFlash>& FlashVector,
65 double const BinWidth,
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;
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;
136 FlashesInAccumulator2,
148 std::vector<std::vector<int>> RefinedHitsPerFlash;
149 for (
auto const& HitsThisFlash : HitsPerFlash)
151 HitsThisFlash, HitVector, RefinedHitsPerFlash, WidthTolerance, FlashThreshold);
155 for (
auto const& HitsPerFlashVec : RefinedHitsPerFlash)
156 ConstructFlash(HitsPerFlashVec, HitVector, FlashVector, geom, ClocksData, TrigCoinc);
164 for (
auto& HitIndicesThisFlash : RefinedHitsPerFlash)
165 AssocList.push_back(HitIndicesThisFlash);
172 double const MinTime,
173 double const BinWidth,
174 double const BinOffset)
176 return static_cast<unsigned int>((PeakTime - MinTime + BinOffset) / BinWidth);
182 unsigned int const& HitIndex,
185 std::vector<double>& Binned,
187 std::vector<int>& FlashesInAccumulator)
190 Contributors.at(AccumIndex).push_back(HitIndex);
192 Binned.at(AccumIndex) += PE;
195 if (Binned.at(AccumIndex) >= FlashThreshold && (Binned.at(AccumIndex) - PE) < FlashThreshold)
196 FlashesInAccumulator.push_back(AccumIndex);
202 std::vector<int>
const& FlashesInAccumulator,
203 std::vector<double>
const& BinnedPE,
204 int const& Accumulator,
205 std::map<
double, std::map<
int, std::vector<int>>, std::greater<double>>& FlashesBySize)
207 for (
auto const& flash : FlashesInAccumulator)
208 FlashesBySize[BinnedPE.at(flash)][Accumulator].push_back(flash);
215 std::vector<int>
const& HitClaimedByFlash,
216 std::vector<int>& HitsThisFlash)
219 for (
auto const& HitIndex : Contributors.at(Bin))
221 if (HitClaimedByFlash.at(HitIndex) == -1) HitsThisFlash.push_back(HitIndex);
227 std::vector<int>
const& HitsThisFlash,
230 std::vector<int>& HitClaimedByFlash)
234 for (
auto const&
Hit : HitsThisFlash)
235 PE += HitVector.at(
Hit).PE();
237 if (PE < FlashThreshold)
return;
240 HitsPerFlash.push_back(HitsThisFlash);
243 for (
auto const&
Hit : HitsThisFlash)
244 if (HitClaimedByFlash.at(
Hit) == -1) HitClaimedByFlash.at(
Hit) = HitsPerFlash.size() - 1;
250 std::vector<int>
const& FlashesInAccumulator2,
251 std::vector<double>
const& Binned1,
252 std::vector<double>
const& Binned2,
253 std::vector<std::vector<int>>
const& Contributors1,
254 std::vector<std::vector<int>>
const& Contributors2,
255 std::vector<recob::OpHit>
const&
HitVector,
261 std::map<double, std::map<int, std::vector<int>>, std::greater<double>> FlashesBySize;
268 std::vector<int> HitClaimedByFlash(HitVector.size(), -1);
273 for (
auto const& itFlash : FlashesBySize)
275 for (
auto const& itAcc : itFlash.second) {
277 int Accumulator = itAcc.first;
280 for (
auto const& Bin : itAcc.second) {
282 std::vector<int> HitsThisFlash;
284 if (Accumulator == 1)
286 else if (Accumulator == 2)
289 ClaimHits(HitVector, HitsThisFlash, FlashThreshold, HitsPerFlash, HitClaimedByFlash);
300 FindSeedHit(std::map<
double, std::vector<int>, std::greater<double>>
const& HitsBySize,
301 std::vector<bool>& HitsUsed,
302 std::vector<recob::OpHit>
const&
HitVector,
303 std::vector<int>& HitsThisRefinedFlash,
304 double& PEAccumulated,
305 double& FlashMaxTime,
306 double& FlashMinTime)
308 for (
auto const& itHit : HitsBySize)
309 for (
auto const& HitID : itHit.second) {
311 if (HitsUsed.at(HitID))
continue;
313 PEAccumulated = HitVector.at(HitID).PE();
314 FlashMaxTime = HitVector.at(HitID).PeakTime() + 0.5 * HitVector.at(HitID).Width();
315 FlashMinTime = HitVector.at(HitID).PeakTime() - 0.5 * HitVector.at(HitID).Width();
317 HitsThisRefinedFlash.clear();
318 HitsThisRefinedFlash.push_back(HitID);
320 HitsUsed.at(HitID) =
true;
331 std::vector<bool>& HitsUsed,
334 std::vector<int>& HitsThisRefinedFlash,
335 double& PEAccumulated,
336 double& FlashMaxTime,
337 double& FlashMinTime)
339 if (HitsUsed.at(HitID))
return;
341 double HitTime = currentHit.
PeakTime();
342 double HitWidth = 0.5 * currentHit.
Width();
343 double FlashTime = 0.5 * (FlashMaxTime + FlashMinTime);
344 double FlashWidth = 0.5 * (FlashMaxTime - FlashMinTime);
346 if (
std::abs(HitTime - FlashTime) > WidthTolerance * (HitWidth + FlashWidth))
return;
348 HitsThisRefinedFlash.push_back(HitID);
349 FlashMaxTime =
std::max(FlashMaxTime, HitTime + HitWidth);
350 FlashMinTime =
std::min(FlashMinTime, HitTime - HitWidth);
351 PEAccumulated += currentHit.
PE();
352 HitsUsed[HitID] =
true;
359 std::vector<int>
const& HitsThisRefinedFlash,
360 double const PEAccumulated,
362 std::vector<bool>& HitsUsed)
365 if (PEAccumulated >= FlashThreshold) {
366 RefinedHitsPerFlash.push_back(HitsThisRefinedFlash);
371 if (HitsThisRefinedFlash.size() == 1)
return;
375 hitIterator != HitsThisRefinedFlash.end();
377 HitsUsed.at(*hitIterator) =
false;
384 std::vector<recob::OpHit>
const&
HitVector,
385 std::vector<std::vector<int>>& RefinedHitsPerFlash,
391 std::map<double, std::vector<int>, std::greater<double>> HitsBySize;
392 for (
auto const& HitID : HitsThisFlash)
393 HitsBySize[HitVector.at(HitID).PE()].push_back(HitID);
403 std::vector<bool> HitsUsed(HitVector.size(),
false);
404 double PEAccumulated, FlashMaxTime, FlashMinTime;
405 std::vector<int> HitsThisRefinedFlash;
409 HitsThisRefinedFlash.clear();
417 HitsThisRefinedFlash,
422 if (HitsThisRefinedFlash.size() == 0)
return;
425 size_t NHitsThisRefinedFlash = 0;
429 while (NHitsThisRefinedFlash < HitsThisRefinedFlash.size()) {
430 NHitsThisRefinedFlash = HitsThisRefinedFlash.size();
432 for (
auto const& itHit : HitsBySize)
433 for (
auto const& HitID : itHit.second)
438 HitsThisRefinedFlash,
447 RefinedHitsPerFlash, HitsThisRefinedFlash, PEAccumulated, FlashThreshold, HitsUsed);
462 std::vector<double>& PEs)
464 double PEThisHit = currentHit.
PE();
465 double TimeThisHit = currentHit.
PeakTime();
466 if (TimeThisHit > MaxTime) MaxTime = TimeThisHit;
467 if (TimeThisHit < MinTime) MinTime = TimeThisHit;
471 AveTime += PEThisHit * TimeThisHit;
472 FastToTotal += PEThisHit * currentHit.
FastToTotal();
473 AveAbsTime += PEThisHit * currentHit.
PeakTimeAbs();
476 TotalPE += PEThisHit;
477 PEs.at(static_cast<unsigned int>(currentHit.
OpChannel())) += PEThisHit;
484 std::vector<double>& sumw,
485 std::vector<double>& sumw2,
493 double PEThisHit = currentHit.
PE();
499 for (
size_t p = 0;
p != geom.
Nplanes(); ++
p) {
502 sumw.at(
p) += PEThisHit *
w;
503 sumw2.at(
p) += PEThisHit * w *
w;
506 sumy += PEThisHit * xyz[1];
507 sumy2 += PEThisHit * xyz[1] * xyz[1];
508 sumz += PEThisHit * xyz[2];
509 sumz2 += PEThisHit * xyz[2] * xyz[2];
514 CalculateWidth(
double const sum,
double const sum_squared,
double const weights_sum)
516 if (sum_squared * weights_sum - sum * sum < 0)
519 return std::sqrt(sum_squared * weights_sum - sum * sum) / weights_sum;
525 std::vector<recob::OpHit>
const&
HitVector,
526 std::vector<recob::OpFlash>& FlashVector,
529 float const TrigCoinc)
535 unsigned int Nplanes = geom.
Nplanes();
536 std::vector<double> sumw(Nplanes, 0.0);
537 std::vector<double> sumw2(Nplanes, 0.0);
541 double AveAbsTime = 0;
542 double FastToTotal = 0;
548 for (
auto const& HitID : HitsPerFlashVec) {
550 HitVector.at(HitID), MaxTime, MinTime, AveTime, FastToTotal, AveAbsTime, TotalPE, PEs);
555 AveAbsTime /= TotalPE;
556 FastToTotal /= TotalPE;
558 double meany = sumy / TotalPE;
559 double meanz = sumz / TotalPE;
564 std::vector<double> WireCenters(Nplanes, 0.0);
565 std::vector<double> WireWidths(Nplanes, 0.0);
567 for (
size_t p = 0;
p != Nplanes; ++
p) {
568 WireCenters.at(
p) = sumw.at(
p) / TotalPE;
575 if (Frame == 0) Frame = 1;
578 bool InBeamFrame =
false;
579 if (!(ClocksData.
TriggerTime() < 0)) InBeamFrame = (Frame == BeamFrame);
581 double TimeWidth = (MaxTime - MinTime) / 2.0;
584 if (InBeamFrame && (
std::abs(AveTime) < TrigCoinc)) OnBeamTime = 1;
586 FlashVector.emplace_back(AveTime,
611 if (iTime > jTime)
return 1e6;
615 double HypPE = iPE * jWidth / iWidth * std::exp(-(jTime - iTime) / 1.6);
616 double nsigma = (jPE - HypPE) / std::sqrt(HypPE);
623 size_t const BeginFlash,
624 std::vector<bool>& MarkedForRemoval)
626 for (
size_t iFlash = BeginFlash; iFlash != FlashVector.size(); ++iFlash) {
628 double iTime = FlashVector.at(iFlash).Time();
629 double iPE = FlashVector.at(iFlash).TotalPE();
630 double iWidth = FlashVector.at(iFlash).TimeWidth();
632 for (
size_t jFlash = iFlash + 1; jFlash != FlashVector.size(); ++jFlash) {
634 if (MarkedForRemoval.at(jFlash - BeginFlash))
continue;
636 double jTime = FlashVector.at(jFlash).Time();
637 double jPE = FlashVector.at(jFlash).TotalPE();
638 double jWidth = FlashVector.at(jFlash).TimeWidth();
643 MarkedForRemoval.at(jFlash - BeginFlash) =
true;
651 std::vector<recob::OpFlash>& FlashVector,
652 size_t const BeginFlash,
653 std::vector<std::vector<int>>& RefinedHitsPerFlash)
655 for (
int iFlash = MarkedForRemoval.size() - 1; iFlash != -1; --iFlash)
656 if (MarkedForRemoval.at(iFlash)) {
657 RefinedHitsPerFlash.erase(RefinedHitsPerFlash.begin() + iFlash);
658 FlashVector.erase(FlashVector.begin() + BeginFlash + iFlash);
665 std::vector<std::vector<int>>& RefinedHitsPerFlash)
667 std::vector<bool> MarkedForRemoval(RefinedHitsPerFlash.size(),
false);
669 size_t const BeginFlash = FlashVector.size() - RefinedHitsPerFlash.size();
674 auto sort_order =
sort_permutation(FlashVector, BeginFlash, sort_flash_by_time);
679 std::sort(FlashVector.begin() + BeginFlash, FlashVector.end(), sort_flash_by_time);
688 template <
typename T,
typename Compare>
693 std::vector<int>
p(vec.size() - offset);
694 std::iota(
p.begin(),
p.end(), 0);
696 p.begin(),
p.end(), [&](
int i,
int j) {
return compare(vec[i + offset], vec[j + offset]); });
701 template <
typename T>
706 std::vector<T> sorted_vec(p.size());
707 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)
int compare(unsigned *r, sha1::digest_t const &d)
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)
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.
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)
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)
static int max(int a, int b)
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)
std::vector< reco::ClusterHit2D * > HitVector
What follows are several highly useful typedefs which we want to expose to the outside world...
Encapsulate the geometry of an optical detector.
T min(sqlite3 *const db, std::string const &table_name, std::string const &column_name)
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
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)
QTextStream & endl(QTextStream &s)
pure virtual base interface for detector clocks
double GetLikelihoodLateLight(double const iPE, double const iTime, double const iWidth, double const jPE, double const jTime, double const jWidth)