22 TH1D *binned_histogram =
new TH1D(
"binned_histogram",
23 "Collection of All OpHits;Time (ms);PEs",
24 binned.size(), 0, binned.size());
25 for (
size_t i = 0; i < binned.size(); ++i)
26 binned_histogram->SetBinContent(i, binned.at(i));
28 TFile f_out(
"output_hist.root",
"RECREATE");
29 binned_histogram->Write();
32 delete binned_histogram;
39 for (
auto const& flash : FlashVector)
40 if (flash.OnBeamTime() == 1)
41 std::cout <<
"OnBeamFlash with time " << flash.Time() << std::endl;
47 std::vector< recob::OpFlash >& FlashVector,
49 double const& BinWidth,
51 float const& FlashThreshold,
52 float const& WidthTolerance,
54 float const& TrigCoinc) {
57 int initialsize = 6400;
60 std::vector< double > Binned1(initialsize);
61 std::vector< double > Binned2(initialsize);
64 std::vector< std::vector< int > > Contributors1(initialsize);
65 std::vector< std::vector< int > > Contributors2(initialsize);
69 std::vector< int > FlashesInAccumulator1;
70 std::vector< int > FlashesInAccumulator2;
73 for (
auto const&
hit : HitVector)
74 if (
hit.PeakTime() < minTime) minTime =
hit.PeakTime();
76 for (
auto const&
hit : HitVector) {
78 double peakTime =
hit.PeakTime();
91 if (AccumIndex2 >= Binned1.size()) {
92 std::cout <<
"Extending vectors to " << AccumIndex2*1.2 << std::endl;
93 Binned1.resize(AccumIndex2*1.2);
94 Binned2.resize(AccumIndex2*1.2);
95 Contributors1.resize(AccumIndex2*1.2);
96 Contributors2.resize(AccumIndex2*1.2);
99 size_t const hitIndex = &
hit - &HitVector[0];
107 FlashesInAccumulator1);
115 FlashesInAccumulator2);
121 std::vector< std::vector< int > > HitsPerFlash;
126 FlashesInAccumulator2,
138 std::vector< std::vector< int > > RefinedHitsPerFlash;
139 for (
auto const& HitsThisFlash : HitsPerFlash)
148 for (
auto const& HitsPerFlashVec : RefinedHitsPerFlash)
157 RefinedHitsPerFlash);
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< int >((PeakTime - MinTime + BinOffset)/BinWidth);
180 unsigned int const& HitIndex,
182 float const& FlashThreshold,
183 std::vector< double >& Binned,
185 std::vector< int >& FlashesInAccumulator) {
187 Contributors.at(AccumIndex).push_back(HitIndex);
189 Binned.at(AccumIndex) += PE;
192 if (Binned.at(AccumIndex) >= FlashThreshold &&
193 (Binned.at(AccumIndex) - PE) < FlashThreshold)
194 FlashesInAccumulator.push_back(AccumIndex);
200 std::vector< double >
const& BinnedPE,
201 int const& Accumulator,
203 std::map<
int, std::vector< int > >,
204 std::greater< double > >& FlashesBySize){
206 for (
auto const& flash : FlashesInAccumulator)
207 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)
222 HitsThisFlash.push_back(HitIndex);
228 std::vector< int >
const& HitsThisFlash,
229 float const& FlashThreshold,
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)
246 HitClaimedByFlash.at(Hit) = HitsPerFlash.size() - 1;
252 std::vector< int >
const& FlashesInAccumulator2,
253 std::vector< double >
const& Binned1,
254 std::vector< double >
const& Binned2,
255 std::vector< std::vector< int > >
const& Contributors1,
256 std::vector< std::vector< int > >
const& Contributors2,
257 std::vector< recob::OpHit >
const&
HitVector,
259 float const& FlashThreshold) {
264 std::map< int, std::vector< int > >,
265 std::greater< double > > FlashesBySize;
278 std::vector< int > HitClaimedByFlash(HitVector.size(), -1);
283 for (
auto const& itFlash : FlashesBySize)
285 for (
auto const& itAcc : itFlash.second) {
287 int Accumulator = itAcc.first;
290 for (
auto const& Bin : itAcc.second) {
292 std::vector< int > HitsThisFlash;
294 if (Accumulator == 1)
299 else if (Accumulator == 2)
320 std::greater< double > >
const& HitsBySize,
321 std::vector< bool >& HitsUsed,
322 std::vector< recob::OpHit >
const&
HitVector,
323 std::vector< int >& HitsThisRefinedFlash,
324 double& PEAccumulated,
325 double& FlashMaxTime,
326 double& FlashMinTime) {
328 for (
auto const& itHit : HitsBySize)
329 for (
auto const& HitID : itHit.second) {
331 if (HitsUsed.at(HitID))
continue;
333 PEAccumulated = HitVector.at(HitID).PE();
334 FlashMaxTime = HitVector.at(HitID).PeakTime() +
335 0.5*HitVector.at(HitID).Width();
336 FlashMinTime = HitVector.at(HitID).PeakTime() -
337 0.5*HitVector.at(HitID).Width();
339 HitsThisRefinedFlash.clear();
340 HitsThisRefinedFlash.push_back(HitID);
342 HitsUsed.at(HitID) =
true;
352 std::vector< bool >& HitsUsed,
354 double const& WidthTolerance,
355 std::vector< int >& HitsThisRefinedFlash,
356 double& PEAccumulated,
357 double& FlashMaxTime,
358 double& FlashMinTime) {
360 if (HitsUsed.at(HitID))
return;
362 double HitTime = currentHit.
PeakTime();
363 double HitWidth = 0.5*currentHit.
Width();
364 double FlashTime = 0.5*(FlashMaxTime + FlashMinTime);
365 double FlashWidth = 0.5*(FlashMaxTime - FlashMinTime);
367 if (std::abs(HitTime - FlashTime) >
368 WidthTolerance*(HitWidth + FlashWidth))
return;
370 HitsThisRefinedFlash.push_back(HitID);
371 FlashMaxTime =
std::max(FlashMaxTime, HitTime + HitWidth);
372 FlashMinTime =
std::min(FlashMinTime, HitTime - HitWidth);
373 PEAccumulated += currentHit.
PE();
374 HitsUsed[HitID] =
true;
381 std::vector< int >
const& HitsThisRefinedFlash,
382 double const& PEAccumulated,
383 float const& FlashThreshold,
384 std::vector< bool >& HitsUsed) {
387 if (PEAccumulated >= FlashThreshold) {
388 RefinedHitsPerFlash.push_back(HitsThisRefinedFlash);
393 if (HitsThisRefinedFlash.size() == 1)
return;
397 std::next(HitsThisRefinedFlash.begin());
398 hitIterator != HitsThisRefinedFlash.end(); ++hitIterator)
399 HitsUsed.at(*hitIterator) =
false;
405 std::vector< recob::OpHit >
const&
HitVector,
406 std::vector< std::vector< int > >& RefinedHitsPerFlash,
407 float const& WidthTolerance,
408 float const& FlashThreshold) {
412 std::map< double, std::vector< int >, std::greater< double > > HitsBySize;
413 for (
auto const& HitID : HitsThisFlash)
414 HitsBySize[HitVector.at(HitID).PE()].push_back(HitID);
424 std::vector< bool > HitsUsed(HitVector.size(),
false);
425 double PEAccumulated, FlashMaxTime, FlashMinTime;
426 std::vector< int > HitsThisRefinedFlash;
430 HitsThisRefinedFlash.clear();
431 PEAccumulated = 0; FlashMaxTime = 0; FlashMinTime = 0;
436 HitsThisRefinedFlash,
441 if (HitsThisRefinedFlash.size() == 0)
return;
444 size_t NHitsThisRefinedFlash = 0;
448 while (NHitsThisRefinedFlash < HitsThisRefinedFlash.size()) {
449 NHitsThisRefinedFlash = HitsThisRefinedFlash.size();
451 for (
auto const& itHit : HitsBySize)
452 for (
auto const& HitID : itHit.second)
457 HitsThisRefinedFlash,
466 HitsThisRefinedFlash,
483 std::vector< double >& PEs) {
485 double PEThisHit = currentHit.
PE();
486 double TimeThisHit = currentHit.
PeakTime();
487 if (TimeThisHit > MaxTime) MaxTime = TimeThisHit;
488 if (TimeThisHit < MinTime) MinTime = TimeThisHit;
492 AveTime += PEThisHit*TimeThisHit;
497 TotalPE += PEThisHit;
498 PEs.at(static_cast< unsigned int >(currentHit.
OpChannel())) += PEThisHit;
505 std::vector< double >& sumw,
506 std::vector< double >& sumw2,
514 double PEThisHit = currentHit.
PE();
520 for (
size_t p = 0; p != geom.
Nplanes(); ++p) {
523 sumw.at(p) += PEThisHit*
w;
524 sumw2.at(p) += PEThisHit*w*
w;
527 sumy += PEThisHit*xyz[1];
528 sumy2 += PEThisHit*xyz[1]*xyz[1];
529 sumz += PEThisHit*xyz[2];
530 sumz2 += PEThisHit*xyz[2]*xyz[2];
536 double const& sum_squared,
537 double const& weights_sum) {
539 if (sum_squared*weights_sum - sum*sum < 0)
return 0;
540 else return std::sqrt(sum_squared*weights_sum - sum*sum)/weights_sum;
546 std::vector< recob::OpHit >
const&
HitVector,
547 std::vector< recob::OpFlash >& FlashVector,
550 float const& TrigCoinc) {
552 double MaxTime = -1e9;
553 double MinTime = 1e9;
555 std::vector< double > PEs(geom.
MaxOpChannel() + 1, 0.0);
556 unsigned int Nplanes = geom.
Nplanes();
557 std::vector< double > sumw (Nplanes, 0.0);
558 std::vector< double > sumw2(Nplanes, 0.0);
562 double AveAbsTime = 0;
563 double FastToTotal = 0;
569 for (
auto const& HitID : HitsPerFlashVec) {
589 AveAbsTime /= TotalPE;
590 FastToTotal /= TotalPE;
592 double meany = sumy/TotalPE;
593 double meanz = sumz/TotalPE;
598 std::vector< double > WireCenters(Nplanes, 0.0);
599 std::vector< double > WireWidths(Nplanes, 0.0);
601 for (
size_t p = 0; p != Nplanes; ++p) {
602 WireCenters.at(p) = sumw.at(p)/TotalPE;
603 WireWidths.at(p) =
CalculateWidth(sumw.at(p), sumw2.at(p), TotalPE);
609 if (Frame == 0) Frame = 1;
612 bool InBeamFrame =
false;
613 if (!(ts.
TriggerTime() < 0)) InBeamFrame = (Frame == BeamFrame);
615 double TimeWidth = (MaxTime - MinTime)/2.0;
618 if (InBeamFrame && (std::abs(AveTime) < TrigCoinc)) OnBeamTime = 1;
620 FlashVector.emplace_back(AveTime,
640 double const& iWidth,
643 double const& jWidth) {
645 if (iTime > jTime)
return 1e6;
649 double HypPE = iPE*jWidth/iWidth*std::exp(-(jTime - iTime)/1.6);
650 double nsigma = (jPE - HypPE)/std::sqrt(HypPE);
657 size_t const& BeginFlash,
658 std::vector< bool >& MarkedForRemoval) {
660 for (
size_t iFlash = BeginFlash; iFlash != FlashVector.size(); ++iFlash) {
662 double iTime = FlashVector.at(iFlash).Time();
663 double iPE = FlashVector.at(iFlash).TotalPE();
664 double iWidth = FlashVector.at(iFlash).TimeWidth();
666 for (
size_t jFlash = iFlash + 1; jFlash != FlashVector.size(); ++jFlash) {
668 if (MarkedForRemoval.at(jFlash - BeginFlash))
continue;
670 double jTime = FlashVector.at(jFlash).Time();
671 double jPE = FlashVector.at(jFlash).TotalPE();
672 double jWidth = FlashVector.at(jFlash).TimeWidth();
677 jPE, jTime, jWidth) < 3.0)
678 MarkedForRemoval.at(jFlash - BeginFlash) =
true;
689 std::vector< recob::OpFlash >& FlashVector,
690 size_t const& BeginFlash,
692 RefinedHitsPerFlash) {
694 for (
int iFlash = MarkedForRemoval.size() - 1; iFlash != -1; --iFlash)
695 if (MarkedForRemoval.at(iFlash)) {
696 RefinedHitsPerFlash.erase(RefinedHitsPerFlash.begin() + iFlash);
697 FlashVector.erase(FlashVector.begin() + BeginFlash + iFlash);
704 std::vector< std::vector< int > >& RefinedHitsPerFlash) {
706 std::vector< bool > MarkedForRemoval(RefinedHitsPerFlash.size(),
false);
708 size_t BeginFlash = FlashVector.size() - RefinedHitsPerFlash.size();
719 std::sort(FlashVector.begin() + BeginFlash,
730 RefinedHitsPerFlash);
735 template <
typename T,
typename Compare >
737 int offset, Compare compare) {
739 std::vector< int > p(vec.size() - offset);
740 std::iota(p.begin(), p.end(), 0);
741 std::sort(p.begin(), p.end(),
742 [&](
int i,
int j){
return compare(vec[i + offset],
743 vec[j + offset]); });
749 template <
typename T >
752 std::vector< T > sorted_vec(p.size());
753 std::transform(p.begin(), p.end(), sorted_vec.begin(),
754 [&](
int i){
return vec[i]; });
double FastToTotal() const
void RemoveLateLight(std::vector< recob::OpFlash > &FlashVector, std::vector< std::vector< int > > &RefinedHitsPerFlash)
double CalculateWidth(double const &sum, double const &sum_squared, double const &weights_sum)
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::DetectorClocks const &ts, float const &TrigCoinc)
virtual double TriggerTime() const =0
Harware trigger time (in electronics time frame) [µs].
void RemoveFlashesFromVectors(std::vector< bool > const &MarkedForRemoval, std::vector< recob::OpFlash > &FlashVector, size_t const &BeginFlash, std::vector< std::vector< int > > &RefinedHitsPerFlash)
The data type to uniquely identify a Plane.
bool isValid
Whether this ID points to a valid element.
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 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)
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)
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)
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.
int Frame() const
Returns the number of the frame containing the clock current time.
unsigned int Nplanes(unsigned int tpc=0, unsigned int cstat=0) const
Returns the total number of wire planes in the specified TPC.
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.
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)
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.
double GetLikelihoodLateLight(double const &iPE, double const &iTime, double const &iWidth, double const &jPE, double const &jTime, double const &jWidth)
void writeHistogram(std::vector< double > const &binned)
The data type to uniquely identify a TPC.
Description of geometry of one entire detector.
std::vector< art::Ptr< recob::Hit > > HitVector
Detector simulation of raw signals on wires.
Conversion of times between different formats and references.
void CheckAndStoreFlash(std::vector< std::vector< int > > &RefinedHitsPerFlash, std::vector< int > const &HitsThisRefinedFlash, double const &PEAccumulated, float const &FlashThreshold, std::vector< bool > &HitsUsed)
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)
virtual const detinfo::ElecClock & OpticalClock() const =0
Lends a constant optical clock with time set to trigger time.
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)
double PeakTimeAbs() const
void ConstructFlash(std::vector< int > const &HitsPerFlashVec, std::vector< recob::OpHit > const &HitVector, std::vector< recob::OpFlash > &FlashVector, geo::GeometryCore const &geom, detinfo::DetectorClocks const &ts, float const &TrigCoinc)
unsigned int GetAccumIndex(double const &PeakTime, double const &MinTime, double const &BinWidth, double const &BinOffset)
void MarkFlashesForRemoval(std::vector< recob::OpFlash > const &FlashVector, size_t const &BeginFlash, std::vector< bool > &MarkedForRemoval)
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)
OpDetGeo const & OpDetGeoFromOpChannel(unsigned int OpChannel) const
Access the OpDetGeo object by OpDet or Channel Number.
void FillHitsThisFlash(std::vector< std::vector< int > > const &Contributors, int const &Bin, std::vector< int > const &HitClaimedByFlash, std::vector< int > &HitsThisFlash)
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)