21 #ifndef TrackTimeAssoc_h 22 #define TrackTimeAssoc_h 1 50 std::vector<double> GetMIPHypotheses(
trkf::BezierTrack* BTrack,
double XOffset=0);
52 void PrintHypotheses(
std::vector<std::vector<double> > TrackHypotheses);
53 double GetChi2(std::vector<double> signal, std::vector<double> hypothesis,
double UpperLim=0);
54 double GetMinChi2(
std::vector<std::vector<double> > ScannedHypotheses, std::vector<double> FlashShape);
136 #include "CLHEP/Random/RandFlat.h" 137 #include "CLHEP/Random/RandGaussQ.h" 149 produces< std::vector<anab::FlashMatch> >();
150 produces< art::Assns<recob::Track, anab::FlashMatch> >();
151 produces< art::Assns<recob::OpFlash, anab::FlashMatch> >();
153 this->reconfigure(pset);
161 fTrackModuleLabel = pset.
get<std::string>(
"TrackModuleLabel");
162 fFlashModuleLabel = pset.
get<std::string>(
"FlashModuleLabel");
163 fBezierResolution = pset.
get<
int>(
"BezierResolution");
164 fLengthCut = pset.
get<
double>(
"LengthCut");
165 fPECut = pset.
get<
double>(
"PECut");
166 fPairingMode = pset.
get<
int>(
"PairingMode");
182 TrackTimeAssoc::~TrackTimeAssoc()
197 std::vector<std::vector<double> > ReturnVector(XSteps);
198 for(
size_t i=0; i!=XSteps; ++i)
199 ReturnVector[i].resize(geom->
NOpDets());
206 std::vector<bool> ValidTrajectory(XSteps,
true);
209 for (
int b=0; b!=fBezierResolution; b++)
211 auto const* larp = lar::providerFrom<detinfo::LArPropertiesService>();
213 double MIPYield = larp->ScintYield();
215 double MIPdQdx = 2.1;
216 double PromptFrac = 0.25;
217 double PromptMIPScintYield = MIPYield * QE * MIPdQdx * PromptFrac;
221 float s = float(b) / float(fBezierResolution);
222 float LightAmount = PromptMIPScintYield * TrackLength/float(fBezierResolution);
225 for(
size_t i=0; i!=XSteps; ++i)
227 if(ValidTrajectory[i])
229 float NewVertex = MinX + float(i)/float(XSteps)*(MaxX-MinX);
231 xyz[0] += NewVertex-OldVertex;
233 if((xyz[0] > MaxX) || (xyz[0] < MinX) ) ValidTrajectory[i]=
false;
236 if (!PointVisibility)
continue;
238 for(
size_t OpDet =0; OpDet!=pvs->
NOpChannels(); OpDet++)
240 ReturnVector.at(i).at(OpDet) += PointVisibility[OpDet] * LightAmount;
245 for(
size_t i=0; i!=ReturnVector.size(); ++i)
246 if(!ValidTrajectory[i]) ReturnVector.at(i).clear();
258 double TrackTimeAssoc::GetMinChi2(
std::vector<std::vector<double> > ScannedHypotheses, std::vector<double> FlashShape)
260 double MinChi2 = 10000;
261 if(FlashShape.size()==0)
return MinChi2;
263 for(
size_t i=0; i!=ScannedHypotheses.size(); ++i)
265 if(ScannedHypotheses.at(i).size()>0)
267 double Chi2 = GetChi2(FlashShape, ScannedHypotheses.at(i), MinChi2);
284 std::vector<double> ReturnVector(geom->
NOpDets(),0);
291 for (
int b=0; b!=fBezierResolution; b++)
293 float s = float(b) / float(fBezierResolution);
298 const float* PointVisibility = pvs->GetAllVisibilities(xyz);
299 if (!PointVisibility)
continue;
300 float LightAmount = dQdx*TrackLength/float(fBezierResolution);
302 for(
size_t OpDet =0; OpDet!=pvs->NOpChannels(); OpDet++)
304 ReturnVector.at(OpDet)+= PointVisibility[OpDet] * LightAmount;
322 std::vector<art::Ptr<recob::OpFlash> > Flashes;
323 for(
unsigned int i=0; i < flashh->size(); ++i)
326 if(flash->
TotalPE()>fPECut) Flashes.push_back(flash);
332 std::vector<art::Ptr<recob::Track> > Tracks;
333 for(
unsigned int i=0; i < trackh->size(); ++i)
336 if(track->
Length()>fLengthCut) Tracks.push_back(track);
342 std::vector<bool> TracksToCut(Tracks.size(),
false);
343 std::vector<trkf::BezierTrack*> BTracks;
345 for(
size_t i=0; i!=Tracks.size(); i++)
349 size_t NOpDets = geom->
NOpDets();
351 std::map<int, bool> OnBeamFlashes;
353 std::vector<std::vector<std::vector<double> > > TrackHypotheses;
354 std::vector<std::vector<double> > FlashShapes;
358 for (
size_t i=0; i!=BTracks.size(); ++i)
360 TrackHypotheses.push_back(ScanMIPHypotheses(BTracks.at(i)));
364 for(
size_t f=0;
f!=Flashes.size(); ++
f)
367 std::vector<double> ThisFlashShape(NOpDets,0);
371 for (
unsigned int c = 0; c < geom->
NOpChannels(); c++){
373 ThisFlashShape[o]+=Flashes.at(
f)->PE(c);
375 if(Flashes.at(
f)->OnBeamTime()) OnBeamFlashes[
f]=
true;
377 FlashShapes.push_back(ThisFlashShape);
383 std::map<int, std::map<int, double> > Chi2Map;
387 std::vector<std::map<double, std::vector<int> > > SortedPrefs(Tracks.size());
390 for(
size_t i=0; i!=TrackHypotheses.size(); ++i)
392 for(
size_t j=0; j!=FlashShapes.size(); ++j)
394 double Chi2 = GetMinChi2(TrackHypotheses.at(i), FlashShapes.at(j));
397 SortedPrefs[i][Chi2].push_back(j);
404 std::vector<anab::FlashMatch> Matches;
412 for(
size_t i=0; i!=BTracks.size(); ++i)
413 for(
size_t j=0; j!=Flashes.size(); ++j)
414 Matches.push_back(
anab::FlashMatch(Chi2Map[i][j], j, i, (Flashes.at(j)->OnBeamTime()>0)));
417 else if(fPairingMode==1)
422 bool StillPairing =
true;
423 std::vector<int> FlashesPaired(Flashes.size(),-1);
424 std::vector<int> TracksPaired(BTracks.size(),-1);
430 for(
size_t i=0; i!=BTracks.size(); ++i)
433 if(TracksPaired[i]<0)
436 bool MadeMatch =
false;
437 for(
auto itPref = SortedPrefs[i].
begin(); itPref!=SortedPrefs[i].end(); ++itPref)
439 for(
size_t iflash =0; iflash!=itPref->second.size(); ++iflash)
441 int FlashID = itPref->second.at(iflash);
442 int FlashExistingPref = FlashesPaired[FlashID];
443 if(FlashExistingPref < 0)
446 TracksPaired[i] = FlashID;
451 if(!OnBeamFlashes[FlashID])
452 FlashesPaired[FlashID] = i;
460 if(Chi2Map[i][FlashID] < Chi2Map[FlashExistingPref][FlashID])
463 FlashesPaired[FlashID] = i;
464 TracksPaired[i] = FlashID;
465 TracksPaired[FlashExistingPref] = -1;
480 for(
size_t i=0; i!=BTracks.size(); ++i)
482 if(TracksPaired[i]>0)
485 int FlashID = TracksPaired[i];
487 Matches.push_back(
anab::FlashMatch(Chi2Map[TrackID][FlashID], FlashID, TrackID, Flashes.at(FlashID)->OnBeamTime() ));
493 StoreFlashMatches(Tracks, Flashes, Matches, evt);
502 double TrackTimeAssoc::GetChi2(std::vector<double> signal, std::vector<double> hypothesis,
double UpperLim)
505 double SignalIntegral = 0;
506 double HypoIntegral = 0;
508 for(
size_t i=0; i!=signal.size(); ++i)
510 SignalIntegral+=signal.at(i);
511 HypoIntegral+=hypothesis.at(i);
518 double NormFactor = SignalIntegral/HypoIntegral;
521 for(
size_t i=0; i!=hypothesis.size(); ++i)
523 hypothesis.at(i) *= NormFactor;
529 for(
size_t i=0; i!=signal.size(); ++i)
533 if(hypothesis.at(i)!=0)
534 Chi2 += pow(hypothesis.at(i) - signal.at(i),2)/(hypothesis.at(i));
545 void TrackTimeAssoc::PrintHypotheses(
std::vector<std::vector<double> > TrackHypotheses)
548 for (
size_t i=0; i!=TrackHypotheses.size(); ++i)
550 mf::LogVerbatim(
"TrackTimeAssoc")<<
"Visbility for track " << i <<std::endl;
552 for(
size_t j=0; j!=TrackHypotheses.at(i).size(); ++j)
554 mf::LogVerbatim(
"TrackTimeAssoc") <<
"Signal at PMT " << j <<
", " << TrackHypotheses.at(i).at(j)<<std::endl;
566 std::unique_ptr< std::vector<anab::FlashMatch> > flash_matches (
new std::vector<anab::FlashMatch>);
570 for(
size_t i=0; i!=Matches.size(); ++i)
572 flash_matches->push_back(Matches.at(i));
574 util::CreateAssn(*
this, evt, *(flash_matches.get()), Tracks.at(Matches.at(i).SubjectID()), *(assn_track.get()), i);
576 util::CreateAssn(*
this, evt, *(flash_matches.get()), Flashes.at(Matches.at(i).FlashID()), *(assn_flash.get()), i);
580 evt.
put(std::move(flash_matches));
581 evt.
put(std::move(assn_track));
582 evt.
put(std::move(assn_flash));
MaybeLogger_< ELseverityLevel::ELsev_info, true > LogVerbatim
Reconstruction base classes.
std::string fTrackModuleLabel
double Length(size_t startAt=0) const
Returns the approximate length of the trajectory.
unsigned int NOpChannels() const
Number of electronics channels for all the optical detectors.
void GetTrackPoint(double s, double *xyz) const
unsigned int OpDetFromOpChannel(int opChannel) const
Convert unique channel to detector number.
ProductID put(std::unique_ptr< PROD > &&product)
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
double Length(size_t p=0) const
Access to various track properties.
float const * GetAllVisibilities(double const *xyz, bool wantReflected=false) const
#define DEFINE_ART_MODULE(klass)
recob::Trajectory const & GetTrajectory() const
Returns the current trajectory.
T get(std::string const &key) const
std::vector< evd::details::RawDigitInfo_t >::const_iterator begin(RawDigitCacheDataClass const &cache)
bool CreateAssn(PRODUCER const &prod, art::Event &evt, std::vector< T > const &a, art::Ptr< U > const &b, art::Assns< U, T > &assn, std::string a_instance, size_t indx=UINT_MAX)
Creates a single one-to-one association.
unsigned int NOpDets() const
Number of OpDets in the whole detector.
Utility object to perform functions of association.
bool getByLabel(std::string const &label, std::string const &productInstanceName, Handle< PROD > &result) const
std::string fFlashModuleLabel
size_t NOpChannels() const
Point_t const & Start() const
Returns the position of the first point of the trajectory [cm].
bool TrackTimeAssoc_tracksort(art::Ptr< recob::Track > t1, art::Ptr< recob::Track > t2)
art framework interface to geometry description