14 #include "fhiclcpp/ParameterSet.h"
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"))
48 TH1F* hist_flash, TH1F* hist_hyp){
51 cOpDetHist_flash = hist_flash;
52 cOpDetHist_flash->SetNameTitle(
"opdet_hist_flash",
"Optical Detector Occupancy, Flash");
54 cOpDetHist_hyp = hist_hyp;
55 cOpDetHist_hyp->SetNameTitle(
"opdet_hist_hyp",
"Optical Detector Occupancy, Hypothesis");
57 cTree->Branch(
"fcp",&cFlashComparison_p,cFlashComparison_p.leaf_structure.c_str());
58 cTree->Branch(
"opdet_hyp",&cOpDetVector_hyp);
59 cTree->Branch(
"opdet_flash",&cOpDetVector_flash);
60 cTree->Branch(
"opdet_hist_flash",
"TH1F",cOpDetHist_flash);
61 cTree->Branch(
"opdet_hist_hyp",
"TH1F",cOpDetHist_hyp);
65 std::vector<recob::Track>
const& trackVector,
66 std::vector<anab::CosmicTag>& cosmicTagVector,
67 std::vector<size_t>& assnTrackTagVector,
74 std::vector< const recob::OpFlash* > flashesOnBeamTime;
75 for(
auto const& flash : flashVector){
76 if(!flash.OnBeamTime())
continue;
77 flashesOnBeamTime.push_back(&flash);
81 assnTrackTagVector.resize(trackVector.size(),std::numeric_limits<size_t>::max());
82 cosmicTagVector.reserve(trackVector.size());
84 for(
size_t track_i=0; track_i<trackVector.size(); track_i++){
88 if(track.
Length() < fMinTrackLength)
continue;
93 std::vector<float> xyz_begin = { (float)pt_begin.x(), (float)pt_begin.y(), (float)pt_begin.z()};
94 std::vector<float> xyz_end = {(float)pt_end.x(), (float)pt_end.y(), (float)pt_end.z()};
97 if(!InDriftWindow(pt_begin.x(),pt_end.x(),geom)) {
98 if(fMakeOutsideDriftTags){
99 cosmicTagVector.emplace_back(xyz_begin,xyz_end,1.,COSMIC_TYPE_OUTSIDEDRIFT);
100 assnTrackTagVector[track_i] = cosmicTagVector.size()-1;
106 std::vector<float> lightHypothesis = GetMIPHypotheses(track,providers,pvs,opdigip);
109 bool compatible=
false;
112 if(result==CompatibilityResultType::kCompatible) compatible=
true;
114 PrintTrackProperties(track);
115 PrintFlashProperties(*flashPointer);
116 PrintHypothesisFlashComparison(lightHypothesis,flashPointer,geom,result);
121 float cosmicScore=1.;
122 if(compatible) cosmicScore=0.;
123 cosmicTagVector.emplace_back(xyz_begin,xyz_end,cosmicScore,COSMIC_TYPE_FLASHMATCH);
124 assnTrackTagVector[track_i]=cosmicTagVector.size()-1;
131 unsigned int const event,
132 std::vector<recob::OpFlash>
const& flashVector,
133 std::vector<recob::Track>
const& trackVector,
140 cFlashComparison_p.run = run;
141 cFlashComparison_p.event = event;
143 std::vector< std::pair<unsigned int, const recob::OpFlash*> > flashesOnBeamTime;
144 for(
unsigned int i=0; i<flashVector.size(); i++){
147 flashesOnBeamTime.push_back(std::make_pair(i,&flash));
150 for(
size_t track_i=0; track_i<trackVector.size(); track_i++){
154 if(track.
Length() < fMinTrackLength)
continue;
159 std::vector<float> xyz_begin = { (float)pt_begin.x(), (float)pt_begin.y(), (float)pt_begin.z()};
160 std::vector<float> xyz_end = {(float)pt_end.x(), (float)pt_end.y(), (float)pt_end.z()};
163 if(!InDriftWindow(pt_begin.x(),pt_end.x(),geom))
continue;
165 cFlashComparison_p.trk_startx = pt_begin.x();
166 cFlashComparison_p.trk_starty = pt_begin.y();
167 cFlashComparison_p.trk_startz = pt_begin.z();
168 cFlashComparison_p.trk_endx = pt_end.x();
169 cFlashComparison_p.trk_endy = pt_end.y();
170 cFlashComparison_p.trk_endz = pt_end.z();
173 cOpDetVector_hyp = GetMIPHypotheses(track,providers,pvs,opdigip);
175 cFlashComparison_p.hyp_index = track_i;
176 FillFlashProperties(cOpDetVector_hyp,
177 cFlashComparison_p.hyp_totalPE,
178 cFlashComparison_p.hyp_y,cFlashComparison_p.hyp_sigmay,
179 cFlashComparison_p.hyp_z,cFlashComparison_p.hyp_sigmaz,
182 for(
auto flash : flashesOnBeamTime){
183 cOpDetVector_flash = std::vector<float>(geom.NOpDets(),0);
184 cFlashComparison_p.flash_nOpDet = 0;
185 for(
size_t c=0; c<=geom.MaxOpChannel(); c++){
186 if ( geom.IsValidOpChannel( c ) ) {
187 unsigned int OpDet = geom.OpDetFromOpChannel(c);
188 cOpDetVector_flash[OpDet] += flash.second->PE(c);
191 for(
size_t o=0; o<cOpDetVector_flash.size(); o++)
192 if(cOpDetVector_flash[o] < fMinOpHitPE) cFlashComparison_p.flash_nOpDet++;
194 cFlashComparison_p.flash_index = flash.first;
195 cFlashComparison_p.flash_totalPE = flash.second->TotalPE();
196 cFlashComparison_p.flash_y = flash.second->YCenter();
197 cFlashComparison_p.flash_sigmay = flash.second->YWidth();
198 cFlashComparison_p.flash_z = flash.second->ZCenter();
199 cFlashComparison_p.flash_sigmaz = flash.second->ZWidth();
201 cFlashComparison_p.chi2 = CalculateChi2(cOpDetVector_flash,cOpDetVector_hyp);
213 unsigned int const event,
214 std::vector<recob::OpFlash>
const& flashVector,
215 std::vector<simb::MCParticle>
const& mcParticleVector,
222 cFlashComparison_p.run = run;
223 cFlashComparison_p.event = event;
225 std::vector< std::pair<unsigned int, const recob::OpFlash*> > flashesOnBeamTime;
226 for(
unsigned int i=0; i<flashVector.size(); i++){
229 flashesOnBeamTime.push_back(std::make_pair(i,&flash));
232 for(
size_t particle_i=0; particle_i<mcParticleVector.size(); particle_i++){
234 simb::MCParticle
const& particle(mcParticleVector[particle_i]);
235 if(particle.Process().compare(
"primary")!=0)
continue;
236 if(particle.Trajectory().TotalLength() < fMinTrackLength)
continue;
239 size_t start_i=0, end_i=particle.NumberTrajectoryPoints()-1;
240 bool prev_inside=
false;
241 for(
size_t pt_i=0; pt_i < particle.NumberTrajectoryPoints(); pt_i++){
242 bool inside = InDetector(particle.Position(pt_i).Vect(),geom);
243 if(inside && !prev_inside) start_i = pt_i;
244 if(!inside && prev_inside) { end_i = pt_i-1;
break; }
245 prev_inside = inside;
247 TVector3
const& pt_begin = particle.Position(start_i).Vect();
248 TVector3
const& pt_end = particle.Position(end_i).Vect();
249 std::vector<float> xyz_begin = { (float)pt_begin.x(), (float)pt_begin.y(), (float)pt_begin.z()};
250 std::vector<float> xyz_end = {(float)pt_end.x(), (float)pt_end.y(), (float)pt_end.z()};
253 if(!InDriftWindow(pt_begin.x(),pt_end.x(),geom))
continue;
255 cFlashComparison_p.trk_startx = pt_begin.x();
256 cFlashComparison_p.trk_starty = pt_begin.y();
257 cFlashComparison_p.trk_startz = pt_begin.z();
258 cFlashComparison_p.trk_endx = pt_end.x();
259 cFlashComparison_p.trk_endy = pt_end.y();
260 cFlashComparison_p.trk_endz = pt_end.z();
263 cOpDetVector_hyp = GetMIPHypotheses(particle,start_i,end_i,providers,pvs,opdigip);
265 cFlashComparison_p.hyp_index = particle_i;
266 FillFlashProperties(cOpDetVector_hyp,
267 cFlashComparison_p.hyp_totalPE,
268 cFlashComparison_p.hyp_y,cFlashComparison_p.hyp_sigmay,
269 cFlashComparison_p.hyp_z,cFlashComparison_p.hyp_sigmaz,
272 for(
auto flash : flashesOnBeamTime){
273 cOpDetVector_flash = std::vector<float>(geom.NOpDets(),0);
274 cFlashComparison_p.flash_nOpDet = 0;
276 for(
size_t c=0; c<=geom.MaxOpChannel(); c++){
277 if ( geom.IsValidOpChannel(c) ) {
278 unsigned int OpDet = geom.OpDetFromOpChannel(c);
279 cOpDetVector_flash[OpDet] += flash.second->PE(c);
282 for(
size_t o=0; o<cOpDetVector_flash.size(); o++)
283 if(cOpDetVector_flash[o] < fMinOpHitPE) cFlashComparison_p.flash_nOpDet++;
284 cFlashComparison_p.flash_index = flash.first;
285 cFlashComparison_p.flash_totalPE = flash.second->TotalPE();
286 cFlashComparison_p.flash_y = flash.second->YCenter();
287 cFlashComparison_p.flash_sigmay = flash.second->YWidth();
288 cFlashComparison_p.flash_z = flash.second->ZCenter();
289 cFlashComparison_p.flash_sigmaz = flash.second->ZWidth();
291 cFlashComparison_p.chi2 = CalculateChi2(cOpDetVector_flash,cOpDetVector_hyp);
294 for(
size_t i=0; i<cOpDetVector_flash.size(); i++)
295 cOpDetHist_flash->SetBinContent(i+1,cOpDetVector_flash[i]);
298 for(
size_t i=0; i<cOpDetVector_hyp.size(); i++)
299 cOpDetHist_hyp->SetBinContent(i+1,cOpDetVector_hyp[i]);
301 for(
size_t i=0; i<cOpDetVector_flash.size(); i++){
303 << cOpDetHist_flash->GetBinContent(i+1) <<
" "
304 << cOpDetHist_hyp->GetBinContent(i+1) << std::endl;
317 float&
y,
float& sigmay,
318 float&
z,
float& sigmaz,
320 y=0; sigmay=0; z=0; sigmaz=0; sum=0;
322 for(
unsigned int opdet=0; opdet<opdetVector.size(); opdet++){
323 sum+=opdetVector[opdet];
325 y += opdetVector[opdet]*xyz[1];
326 z += opdetVector[opdet]*xyz[2];
331 for(
unsigned int opdet=0; opdet<opdetVector.size(); opdet++){
333 sigmay += (opdetVector[opdet]*xyz[1]-
y)*(opdetVector[opdet]*xyz[1]-y);
334 sigmaz += (opdetVector[opdet]*xyz[2]-
y)*(opdetVector[opdet]*xyz[2]-y);
337 sigmay = std::sqrt(sigmay)/sum;
338 sigmaz = std::sqrt(sigmaz)/sum;
343 if(pt.x() < 0 || pt.x() > 2*geom.
DetHalfWidth())
return false;
345 if(pt.z() < 0 || pt.z() > geom.
DetLength())
return false;
350 if(start_x < 0. || end_x < 0.)
return false;
357 std::vector<float> & lightHypothesis,
358 float & totalHypothesisPE,
361 float const& PromptMIPScintYield,
364 double xyz_segment[3];
365 xyz_segment[0] = 0.5*(pt2.x()+pt1.x()) + XOffset;
366 xyz_segment[1] = 0.5*(pt2.y()+pt1.y());
367 xyz_segment[2] = 0.5*(pt2.z()+pt1.z());
373 if(!PointVisibility)
return;
376 float LightAmount = PromptMIPScintYield*(pt2-pt1).Mag();
378 for(
size_t opdet_i=0; opdet_i<pvs.
NOpChannels(); opdet_i++){
379 lightHypothesis[opdet_i] += PointVisibility[opdet_i]*LightAmount;
380 totalHypothesisPE += PointVisibility[opdet_i]*LightAmount;
383 if(lightHypothesis[opdet_i]>fOpDetSaturation){
384 totalHypothesisPE -= (lightHypothesis[opdet_i]-fOpDetSaturation);
385 lightHypothesis[opdet_i] = fOpDetSaturation;
392 float const& totalHypothesisPE,
394 for(
size_t opdet_i=0; opdet_i<geom.
NOpDets(); opdet_i++)
395 lightHypothesis[opdet_i] /= totalHypothesisPE;
408 std::vector<float> lightHypothesis(geom.NOpDets(),0);
409 float totalHypothesisPE=0;
410 const float PromptMIPScintYield = larp.ScintYield()*larp.ScintYieldRatio()*opdigip.
QE()*fMIPdQdx;
417 lightHypothesis,totalHypothesisPE,
418 geom,pvs,PromptMIPScintYield,
421 if(fNormalizeHypothesisToFlash && totalHypothesisPE > std::numeric_limits<float>::epsilon())
422 NormalizeLightHypothesis(lightHypothesis,totalHypothesisPE,geom);
424 return lightHypothesis;
431 size_t start_i,
size_t end_i,
439 std::vector<float> lightHypothesis(geom.NOpDets(),0);
440 float totalHypothesisPE=0;
441 const float PromptMIPScintYield = larp.ScintYield()*larp.ScintYieldRatio()*opdigip.
QE()*fMIPdQdx;
443 for(
size_t pt=start_i+1; pt<=end_i; pt++)
444 AddLightFromSegment(particle.Position(pt-1).Vect(),particle.Position(pt).Vect(),
445 lightHypothesis,totalHypothesisPE,
446 geom,pvs,PromptMIPScintYield,
449 if(fNormalizeHypothesisToFlash && totalHypothesisPE > std::numeric_limits<float>::epsilon())
450 NormalizeLightHypothesis(lightHypothesis,totalHypothesisPE,geom);
452 return lightHypothesis;
469 float hypothesis_integral=0;
470 float flash_integral=0;
471 unsigned int cumulativeChannels=0;
473 std::vector<double> PEbyOpDet(geom.
NOpDets(),0);
475 for (
unsigned int c = 0; c <= geom.
MaxOpChannel(); c++){
478 PEbyOpDet[o] += flashPointer->
PE(c);
482 float hypothesis_scale=1.;
483 if(fNormalizeHypothesisToFlash) hypothesis_scale = flashPointer->
TotalPE();
485 for(
size_t pmt_i=0; pmt_i<lightHypothesis.size(); pmt_i++){
487 flash_integral += PEbyOpDet[pmt_i];
489 if(lightHypothesis[pmt_i] < std::numeric_limits<float>::epsilon() )
continue;
490 hypothesis_integral += lightHypothesis[pmt_i]*hypothesis_scale;
492 if(PEbyOpDet[pmt_i] < fMinOpHitPE)
continue;
494 float diff_scaled = (lightHypothesis[pmt_i]*hypothesis_scale - PEbyOpDet[pmt_i])/std::sqrt(lightHypothesis[pmt_i]*hypothesis_scale);
496 if( diff_scaled > fSingleChannelCut )
return CompatibilityResultType::kSingleChannelCut;
498 if( diff_scaled > fCumulativeChannelThreshold ) cumulativeChannels++;
499 if(cumulativeChannels >= fCumulativeChannelCut)
return CompatibilityResultType::kCumulativeChannelCut;
503 if( (hypothesis_integral - flash_integral)/std::sqrt(hypothesis_integral)
504 > fIntegralCut)
return CompatibilityResultType::kIntegralCut;
506 return CompatibilityResultType::kCompatible;
511 std::vector<float>
const& light_track){
514 for(
size_t pmt_i=0; pmt_i<light_flash.size(); pmt_i++){
516 if(light_flash[pmt_i] < fMinOpHitPE)
continue;
519 if(light_track[pmt_i] > 1) err2 = light_track[pmt_i];
521 chi2 += (light_flash[pmt_i]-light_track[pmt_i])*(light_flash[pmt_i]-light_track[pmt_i]) / err2;
530 *output <<
"----------------------------------------------" << std::endl;
531 *output <<
"Track properties: ";
532 *output <<
"\n\tLength=" << track.
Length();
535 *output <<
"\n\tBegin Location (x,y,z)=(" << pt_begin.x() <<
"," << pt_begin.y() <<
"," << pt_begin.z() <<
")";
538 *output <<
"\n\tEnd Location (x,y,z)=(" << pt_end.x() <<
"," << pt_end.y() <<
"," << pt_end.z() <<
")";
541 *output << std::endl;
542 *output <<
"----------------------------------------------" << std::endl;
547 *output <<
"----------------------------------------------" << std::endl;
548 *output <<
"Flash properties: ";
550 *output <<
"\n\tTime=" << flash.
Time();
551 *output <<
"\n\tOnBeamTime=" << flash.
OnBeamTime();
552 *output <<
"\n\ty position (center,width)=(" << flash.
YCenter() <<
"," << flash.
YWidth() <<
")";
553 *output <<
"\n\tz position (center,width)=(" << flash.
ZCenter() <<
"," << flash.
ZWidth() <<
")";
554 *output <<
"\n\tTotal PE=" << flash.
TotalPE();
556 *output << std::endl;
557 *output <<
"----------------------------------------------" << std::endl;
568 *output <<
"----------------------------------------------" << std::endl;
569 *output <<
"Hypothesis-flash comparison: ";
571 float hypothesis_integral=0;
572 float flash_integral=0;
574 float hypothesis_scale=1.;
575 if(fNormalizeHypothesisToFlash) hypothesis_scale = flashPointer->
TotalPE();
578 std::vector<double> PEbyOpDet(geom.
NOpDets(),0);
580 for (
unsigned int c = 0; c <= geom.
MaxOpChannel(); c++){
583 PEbyOpDet[o] += flashPointer->
PE(c);
587 for(
size_t pmt_i=0; pmt_i<lightHypothesis.size(); pmt_i++){
589 flash_integral += PEbyOpDet[pmt_i];
591 *output <<
"\n\t pmt_i=" << pmt_i <<
", (hypothesis,flash)=("
592 << lightHypothesis[pmt_i]*hypothesis_scale <<
"," << PEbyOpDet[pmt_i] <<
")";
594 if(lightHypothesis[pmt_i] < std::numeric_limits<float>::epsilon() )
continue;
596 *output <<
" difference="
597 << (lightHypothesis[pmt_i]*hypothesis_scale - PEbyOpDet[pmt_i])/std::sqrt(lightHypothesis[pmt_i]*hypothesis_scale);
599 hypothesis_integral += lightHypothesis[pmt_i]*hypothesis_scale;
602 *output <<
"\n\t TOTAL (hypothesis,flash)=("
603 << hypothesis_integral <<
"," << flash_integral <<
")"
604 <<
" difference=" << (hypothesis_integral - flash_integral)/std::sqrt(hypothesis_integral);
606 *output << std::endl;
607 *output <<
"End result=" << result << std::endl;
608 *output <<
"----------------------------------------------" << std::endl;
process_name opflash particleana ie ie ie z
CompatibilityResultType CheckCompatibility(std::vector< float > const &lightHypothesis, const recob::OpFlash *flashPointer, geo::GeometryCore const &geom)
geo::Length_t DetHalfWidth(geo::TPCID const &tpcid) const
Returns the half width of the active volume of the specified TPC.
BeamFlashTrackMatchTaggerAlg(fhicl::ParameterSet const &p)
enum anab::cosmic_tag_id CosmicTagID_t
Point_t const & LocationAtPoint(size_t i) const
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.
double QE() const noexcept
Returns quantum efficiency.
Provider const * get() const
Returns the provider with the specified type.
void GetCenter(double *xyz, double localz=0.0) const
double PE(unsigned int i) const
process_name use argoneut_mc_hitfinder track
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 &)
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)
geo::Length_t DetHalfHeight(geo::TPCID const &tpcid) const
Returns the half height of the active volume of the specified TPC.
double Length(size_t p=0) const
Access to various track properties.
process_name opflash particleana ie ie y
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)
void PrintTrackProperties(recob::Track const &, std::ostream *output=&std::cout)
geo::Length_t DetLength(geo::TPCID const &tpcid) const
Returns the length of the active volume of the specified TPC.
CryostatGeo const & Cryostat(geo::CryostatID const &cryoid) const
Returns the specified cryostat.
unsigned int MaxOpChannel() const
Largest optical channel number.
Description of geometry of one entire detector.
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.
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.
BEGIN_PROLOG sequence::SlidingWindowTriggerPatternsOppositeWindows END_PROLOG simSlidingORM6O6 effSlidingORW output
bool InDriftWindow(double, double, geo::GeometryCore const &)
void FillFlashProperties(std::vector< float > const &opdetVector, float &, float &, float &, float &, float &, geo::GeometryCore const &geom)
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
BEGIN_PROLOG could also be cout
Track from a non-cascading particle.A recob::Track consists of a recob::TrackTrajectory, plus additional members relevant for a "fitted" track:
void PrintFlashProperties(recob::OpFlash const &, std::ostream *output=&std::cout)