34 , DEBUG_FLAG(p.
get<bool>(
"RunDebugMode", false))
35 , fMinTrackLength(p.
get<float>(
"MinTrackLength"))
36 , fMinOpHitPE(p.
get<float>(
"MinOpHitPE", 0.1))
37 , fMIPdQdx(p.
get<float>(
"MIPdQdx", 2.1))
38 , fOpDetSaturation(p.
get<float>(
"OpDetSaturation", 200.))
39 , fSingleChannelCut(p.
get<float>(
"SingleChannelCut"))
40 , fCumulativeChannelThreshold(p.
get<float>(
"CumulativeChannelThreshold"))
41 , fCumulativeChannelCut(p.
get<unsigned int>(
"CumulativeChannelCut"))
42 , fIntegralCut(p.
get<float>(
"IntegralCut"))
43 , fMakeOutsideDriftTags(p.
get<bool>(
"MakeOutsideDriftTags", false))
44 , fNormalizeHypothesisToFlash(p.
get<bool>(
"NormalizeHypothesisToFlash"))
54 cOpDetHist_flash->SetNameTitle(
"opdet_hist_flash",
"Optical Detector Occupancy, Flash");
57 cOpDetHist_hyp->SetNameTitle(
"opdet_hist_hyp",
"Optical Detector Occupancy, Hypothesis");
67 std::vector<recob::OpFlash>
const& flashVector,
68 std::vector<recob::Track>
const& trackVector,
69 std::vector<anab::CosmicTag>& cosmicTagVector,
70 std::vector<size_t>& assnTrackTagVector,
78 std::vector<const recob::OpFlash*> flashesOnBeamTime;
79 for (
auto const& flash : flashVector) {
80 if (!flash.OnBeamTime())
continue;
81 flashesOnBeamTime.push_back(&flash);
85 assnTrackTagVector.resize(trackVector.size(), std::numeric_limits<size_t>::max());
86 cosmicTagVector.reserve(trackVector.size());
88 for (
size_t track_i = 0; track_i < trackVector.size(); track_i++) {
97 std::vector<float> xyz_begin = {(float)pt_begin.x(), (float)pt_begin.y(), (float)pt_begin.z()};
98 std::vector<float> xyz_end = {(float)pt_end.x(), (float)pt_end.y(), (float)pt_end.z()};
104 assnTrackTagVector[track_i] = cosmicTagVector.size() - 1;
110 std::vector<float> lightHypothesis =
GetMIPHypotheses(track, providers, pvs, opdigip);
113 bool compatible =
false;
116 if (result == CompatibilityResultType::kCompatible) compatible =
true;
125 float cosmicScore = 1.;
126 if (compatible) cosmicScore = 0.;
128 assnTrackTagVector[track_i] = cosmicTagVector.size() - 1;
134 unsigned int const run,
135 unsigned int const event,
136 std::vector<recob::OpFlash>
const& flashVector,
137 std::vector<recob::Track>
const& trackVector,
148 std::vector<std::pair<unsigned int, const recob::OpFlash*>> flashesOnBeamTime;
149 for (
unsigned int i = 0; i < flashVector.size(); i++) {
152 flashesOnBeamTime.push_back(std::make_pair(i, &flash));
155 for (
size_t track_i = 0; track_i < trackVector.size(); track_i++) {
164 std::vector<float> xyz_begin = {(float)pt_begin.x(), (float)pt_begin.y(), (float)pt_begin.z()};
165 std::vector<float> xyz_end = {(float)pt_end.x(), (float)pt_end.y(), (float)pt_end.z()};
168 if (!
InDriftWindow(pt_begin.x(), pt_end.x(), geom))
continue;
189 for (
auto flash : flashesOnBeamTime) {
192 for (
size_t c = 0; c <= geom.MaxOpChannel(); c++) {
193 if (geom.IsValidOpChannel(c)) {
194 unsigned int OpDet = geom.OpDetFromOpChannel(c);
218 unsigned int const run,
219 unsigned int const event,
220 std::vector<recob::OpFlash>
const& flashVector,
221 std::vector<simb::MCParticle>
const& mcParticleVector,
232 std::vector<std::pair<unsigned int, const recob::OpFlash*>> flashesOnBeamTime;
233 for (
unsigned int i = 0; i < flashVector.size(); i++) {
236 flashesOnBeamTime.push_back(std::make_pair(i, &flash));
239 for (
size_t particle_i = 0; particle_i < mcParticleVector.size(); particle_i++) {
242 if (particle.
Process().compare(
"primary") != 0)
continue;
247 bool prev_inside =
false;
250 if (inside && !prev_inside) start_i = pt_i;
251 if (!inside && prev_inside) {
255 prev_inside = inside;
257 TVector3
const& pt_begin = particle.
Position(start_i).Vect();
258 TVector3
const& pt_end = particle.
Position(end_i).Vect();
259 std::vector<float> xyz_begin = {(float)pt_begin.x(), (float)pt_begin.y(), (float)pt_begin.z()};
260 std::vector<float> xyz_end = {(float)pt_end.x(), (float)pt_end.y(), (float)pt_end.z()};
263 if (!
InDriftWindow(pt_begin.x(), pt_end.x(), geom))
continue;
284 for (
auto flash : flashesOnBeamTime) {
288 for (
size_t c = 0; c <= geom.MaxOpChannel(); c++) {
289 if (geom.IsValidOpChannel(c)) {
290 unsigned int OpDet = geom.OpDetFromOpChannel(c);
314 std::cout <<
"Flash/Hyp " << i <<
" : " <<
cOpDetHist_flash->GetBinContent(i + 1) <<
" " 325 std::vector<float>
const& opdetVector,
339 sum += opdetVector[
opdet];
341 y += opdetVector[
opdet] * xyz.Y();
342 z += opdetVector[
opdet] * xyz.Z();
350 sigmay += (opdetVector[
opdet] * xyz.Y() -
y) * (opdetVector[
opdet] * xyz.Y() -
y);
351 sigmaz += (opdetVector[
opdet] * xyz.Z() -
y) * (opdetVector[
opdet] * xyz.Z() -
y);
354 sigmay = std::sqrt(sigmay) /
sum;
355 sigmaz = std::sqrt(sigmaz) /
sum;
361 if (pt.x() < 0 || pt.x() > 2 * geom.
DetHalfWidth())
return false;
363 if (pt.z() < 0 || pt.z() > geom.
DetLength())
return false;
371 if (start_x < 0. || end_x < 0.)
return false;
379 std::vector<float>& lightHypothesis,
380 float& totalHypothesisPE,
383 float const& PromptMIPScintYield,
387 double xyz_segment[3];
388 xyz_segment[0] = 0.5 * (pt2.x() + pt1.x()) + XOffset;
389 xyz_segment[1] = 0.5 * (pt2.y() + pt1.y());
390 xyz_segment[2] = 0.5 * (pt2.z() + pt1.z());
396 if (!PointVisibility)
return;
399 float LightAmount = PromptMIPScintYield * (pt2 -
pt1).Mag();
401 for (
size_t opdet_i = 0; opdet_i < pvs.
NOpChannels(); opdet_i++) {
402 lightHypothesis[opdet_i] += PointVisibility[opdet_i] * LightAmount;
403 totalHypothesisPE += PointVisibility[opdet_i] * LightAmount;
415 std::vector<float>& lightHypothesis,
416 float const& totalHypothesisPE,
419 for (
size_t opdet_i = 0; opdet_i < geom.
NOpDets(); opdet_i++)
420 lightHypothesis[opdet_i] /= totalHypothesisPE;
433 std::vector<float> lightHypothesis(geom.NOpDets(), 0);
434 float totalHypothesisPE = 0;
435 const float PromptMIPScintYield =
436 larp.ScintYield() * larp.ScintYieldRatio() * opdigip.
QE() *
fMIPdQdx;
454 return lightHypothesis;
470 std::vector<float> lightHypothesis(geom.NOpDets(), 0);
471 float totalHypothesisPE = 0;
472 const float PromptMIPScintYield =
473 larp.ScintYield() * larp.ScintYieldRatio() * opdigip.
QE() *
fMIPdQdx;
475 for (
size_t pt = start_i + 1;
pt <= end_i;
pt++)
488 return lightHypothesis;
504 float hypothesis_integral = 0;
505 float flash_integral = 0;
506 unsigned int cumulativeChannels = 0;
508 std::vector<double> PEbyOpDet(geom.
NOpDets(), 0);
510 for (
unsigned int c = 0; c <= geom.
MaxOpChannel(); c++) {
513 PEbyOpDet[o] += flashPointer->
PE(c);
517 float hypothesis_scale = 1.;
520 for (
size_t pmt_i = 0; pmt_i < lightHypothesis.size(); pmt_i++) {
522 flash_integral += PEbyOpDet[pmt_i];
524 if (lightHypothesis[pmt_i] < std::numeric_limits<float>::epsilon())
continue;
525 hypothesis_integral += lightHypothesis[pmt_i] * hypothesis_scale;
529 float diff_scaled = (lightHypothesis[pmt_i] * hypothesis_scale - PEbyOpDet[pmt_i]) /
530 std::sqrt(lightHypothesis[pmt_i] * hypothesis_scale);
532 if (diff_scaled >
fSingleChannelCut)
return CompatibilityResultType::kSingleChannelCut;
536 return CompatibilityResultType::kCumulativeChannelCut;
539 if ((hypothesis_integral - flash_integral) / std::sqrt(hypothesis_integral) >
fIntegralCut)
540 return CompatibilityResultType::kIntegralCut;
542 return CompatibilityResultType::kCompatible;
546 std::vector<float>
const& light_track)
550 for (
size_t pmt_i = 0; pmt_i < light_flash.size(); pmt_i++) {
555 if (light_track[pmt_i] > 1) err2 = light_track[pmt_i];
558 (light_flash[pmt_i] - light_track[pmt_i]) * (light_flash[pmt_i] - light_track[pmt_i]) / err2;
565 std::ostream* output)
567 *output <<
"----------------------------------------------" << std::endl;
568 *output <<
"Track properties: ";
569 *output <<
"\n\tLength=" << track.
Length();
572 *output <<
"\n\tBegin Location (x,y,z)=(" << pt_begin.x() <<
"," << pt_begin.y() <<
"," 573 << pt_begin.z() <<
")";
576 *output <<
"\n\tEnd Location (x,y,z)=(" << pt_end.x() <<
"," << pt_end.y() <<
"," << pt_end.z()
580 *output << std::endl;
581 *output <<
"----------------------------------------------" << std::endl;
585 std::ostream* output)
587 *output <<
"----------------------------------------------" << std::endl;
588 *output <<
"Flash properties: ";
590 *output <<
"\n\tTime=" << flash.
Time();
591 *output <<
"\n\tOnBeamTime=" << flash.
OnBeamTime();
592 *output <<
"\n\ty position (center,width)=(" << flash.
YCenter() <<
"," << flash.
YWidth() <<
")";
593 *output <<
"\n\tz position (center,width)=(" << flash.
ZCenter() <<
"," << flash.
ZWidth() <<
")";
594 *output <<
"\n\tTotal PE=" << flash.
TotalPE();
596 *output << std::endl;
597 *output <<
"----------------------------------------------" << std::endl;
601 std::vector<float>
const& lightHypothesis,
605 std::ostream* output)
608 *output <<
"----------------------------------------------" << std::endl;
609 *output <<
"Hypothesis-flash comparison: ";
611 float hypothesis_integral = 0;
612 float flash_integral = 0;
614 float hypothesis_scale = 1.;
617 std::vector<double> PEbyOpDet(geom.
NOpDets(), 0);
619 for (
unsigned int c = 0; c <= geom.
MaxOpChannel(); c++) {
622 PEbyOpDet[o] += flashPointer->
PE(c);
626 for (
size_t pmt_i = 0; pmt_i < lightHypothesis.size(); pmt_i++) {
628 flash_integral += PEbyOpDet[pmt_i];
630 *output <<
"\n\t pmt_i=" << pmt_i <<
", (hypothesis,flash)=(" 631 << lightHypothesis[pmt_i] * hypothesis_scale <<
"," << PEbyOpDet[pmt_i] <<
")";
633 if (lightHypothesis[pmt_i] < std::numeric_limits<float>::epsilon())
continue;
635 *output <<
" difference=" 636 << (lightHypothesis[pmt_i] * hypothesis_scale - PEbyOpDet[pmt_i]) /
637 std::sqrt(lightHypothesis[pmt_i] * hypothesis_scale);
639 hypothesis_integral += lightHypothesis[pmt_i] * hypothesis_scale;
642 *output <<
"\n\t TOTAL (hypothesis,flash)=(" << hypothesis_integral <<
"," << flash_integral
645 << (hypothesis_integral - flash_integral) / std::sqrt(hypothesis_integral);
647 *output << std::endl;
648 *output <<
"End result=" << result << std::endl;
649 *output <<
"----------------------------------------------" << std::endl;
unsigned int NumberTrajectoryPoints() const
const TLorentzVector & Position(const int i=0) const
CompatibilityResultType CheckCompatibility(std::vector< float > const &lightHypothesis, const recob::OpFlash *flashPointer, geo::GeometryCore const &geom)
BeamFlashTrackMatchTaggerAlg(fhicl::ParameterSet const &p)
float fCumulativeChannelThreshold
const simb::MCTrajectory & Trajectory() const
enum anab::cosmic_tag_id CosmicTagID_t
Point_t const & LocationAtPoint(size_t i) const
Access to track position at different points.
Length_t DetHalfWidth(TPCID const &tpcid=tpc_zero) const
Returns the half width of the active volume of the specified TPC.
bool fNormalizeHypothesisToFlash
void RunHypothesisComparison(unsigned int const, unsigned int const, std::vector< recob::OpFlash > const &, std::vector< recob::Track > const &, Providers_t, phot::PhotonVisibilityService const &, opdet::OpDigiProperties const &)
float CalculateChi2(std::vector< float > const &, std::vector< float > const &)
size_t NumberTrajectoryPoints() const
Various functions related to the presence and the number of (valid) points.
constexpr auto abs(T v)
Returns the absolute value of the argument.
Provider const * get() const
Returns the provider with the specified type.
double PE(unsigned int i) const
std::string Process() const
CryostatGeo const & Cryostat(CryostatID const &cryoid=cryostat_zero) const
Returns the specified cryostat.
void RunCompatibilityCheck(std::vector< recob::OpFlash > const &, std::vector< recob::Track > const &, std::vector< anab::CosmicTag > &, std::vector< size_t > &, Providers_t, phot::PhotonVisibilityService const &, opdet::OpDigiProperties const &)
Length_t DetLength(TPCID const &tpcid=tpc_zero) const
Returns the length of the active volume of the specified TPC.
unsigned int OpDetFromOpChannel(int opChannel) const
Convert unique channel to detector number.
Access the description of detector geometry.
std::vector< float > GetMIPHypotheses(recob::Track const &track, Providers_t providers, phot::PhotonVisibilityService const &pvs, opdet::OpDigiProperties const &, float XOffset=0)
const anab::CosmicTagID_t COSMIC_TYPE_OUTSIDEDRIFT
double QE() const noexcept
Returns quantum efficiency.
std::vector< float > cOpDetVector_flash
double Length(size_t p=0) const
Access to various track properties.
void NormalizeLightHypothesis(std::vector< float > &lightHypothesis, float const &totalHypothesisPE, geo::GeometryCore const &geom)
const OpDetGeo & OpDet(unsigned int iopdet) const
Return the iopdet'th optical detector in the cryostat.
void AddLightFromSegment(TVector3 const &pt1, TVector3 const &pt2, std::vector< float > &lightHypothesis, float &totalHypothesisPE, geo::GeometryCore const &geom, phot::PhotonVisibilityService const &pvs, float const &PromptMIPScintYield, float XOffset)
FlashComparisonProperties_t cFlashComparison_p
bool fMakeOutsideDriftTags
void PrintTrackProperties(recob::Track const &, std::ostream *output=&std::cout)
unsigned int flash_nOpDet
unsigned int MaxOpChannel() const
Largest optical channel number.
Description of geometry of one entire detector.
std::string leaf_structure
MappedCounts_t GetAllVisibilities(Point const &p, bool wantReflected=false) const
void SetHypothesisComparisonTree(TTree *, TH1F *, TH1F *)
unsigned int NOpDets() const
Number of OpDets in the whole detector.
Encapsulate the geometry of an optical detector.
geo::Point_t const & GetCenter() const
decltype(auto) get(T &&obj)
ADL-aware version of std::to_string.
unsigned int fCumulativeChannelCut
double TotalLength() const
std::vector< float > cOpDetVector_hyp
void PrintHypothesisFlashComparison(std::vector< float > const &, const recob::OpFlash *, geo::GeometryCore const &geom, CompatibilityResultType, std::ostream *output=&std::cout)
Container for a list of pointers to providers.
bool InDriftWindow(double, double, geo::GeometryCore const &)
void FillFlashProperties(std::vector< float > const &opdetVector, float &, float &, float &, float &, float &, geo::GeometryCore const &geom)
const anab::CosmicTagID_t COSMIC_TYPE_FLASHMATCH
Length_t DetHalfHeight(TPCID const &tpcid=tpc_zero) const
Returns the half height of the active volume of the specified TPC.
bool InDetector(TVector3 const &, geo::GeometryCore const &)
size_t NOpChannels() const
bool IsValidOpChannel(int opChannel) const
Is this a valid OpChannel number?
art framework interface to geometry description
Track from a non-cascading particle.A recob::Track consists of a recob::TrackTrajectory, plus additional members relevant for a "fitted" track:
Event finding and building.
void PrintFlashProperties(recob::OpFlash const &, std::ostream *output=&std::cout)