371 int track_number = 0;
377 double TPC_trigger_offset = 0.0;
379 std::vector<std::vector<TLorentzVector>> mcpart_list;
382 if(
fDebug) std::cout <<
"Set event number: " <<
event <<
"\nTop: " <<
det_top 401 std::cerr<<
"\033[93m[ERROR]\033[00m ... could not locate Flash!"<<
std::endl;
414 if( !trigger_h || trigger_h->empty()) {
419 if(
fDebug) std::cout <<
"Loading trigger time from producer " 422 trigger_time = trigger_h->at(0).Time();
427 auto reco_particles_h =
evt.getValidHandle<std::vector<recob::PFParticle>>(
fPFPProducer);
429 if(!reco_particles_h.isValid()) {
430 std::cerr<<
"\033[93m[ERROR]\033[00m ... could not locate PFParticles!"<<
std::endl;
441 auto mcpart_h =
evt.getHandle<std::vector<simb::MCParticle> >(
"largeant");
446 if(!mcpart_h.isValid()) {
447 std::cerr<<
"\033[93m[ERROR]\033[00m ... could not locate MCParticle!"<<
std::endl;
455 TPC_trigger_offset = clockData.TriggerOffsetTPC();
456 if(
fDebug) std::cout <<
"TPC time offset from trigger: " 457 << TPC_trigger_offset <<
" us" <<
std::endl;
462 size_t flash_ctr = 0;
463 for (
auto const& flash : *
flash_h){
464 if (flash.TotalPE() >
fMinPE){
466 if(
fUseMC) op_flash_time = op_flash_time - TPC_trigger_offset;
478 if (
fDebug) std::cout <<
"Output all flashes - closest flash to trigger time is: " 486 for (
auto const& op_hit : *
op_hit_h){
487 int op_hit_channel = op_hit.OpChannel();
501 size_t ev_particle_ctr = 0;
503 for(
unsigned int p = 0;
p < reco_particles_h->size(); ++
p){
515 if(
fDebug) std::cout <<
"\tPFParticle " << ev_particle_ctr <<
" is not track like" <<
std::endl;
518 if (
fDebug) std::cout <<
"\tLooping through reco PFParticle " << ev_particle_ctr <<
std::endl;
558 std::vector<TVector3> sorted_trk;
561 TVector3 track_start = sorted_trk.at(0);
562 TVector3 track_end = sorted_trk.at(sorted_trk.size() - 1);
564 if(
fDebug) std::cout <<
"\t\tTrack goes from (" << track_start.X() <<
", " 565 << track_start.Y() <<
", " << track_start.Z() <<
") --> (" <<
566 track_end.X() <<
", " << track_end.Y() <<
", " << track_end.Z() <<
569 if(sqrt(
pow(track_start.X() - track_end.X(),2.0)
570 +
pow(track_start.Y() - track_end.Y(),2.0)
572 if(
fDebug) std::cout <<
"\t\t\tParticle track too short. Skipping." <<
std::endl;
577 auto const* geom = lar::providerFrom<geo::Geometry>();
578 auto const*
hit = hit_v.at(0);
580 const auto TPCGeoObject = geom->TPC(wireID.
TPC,wireID.
Cryostat);
581 short int driftDir_start = TPCGeoObject.DetectDriftDirection();
582 short int driftDir_end = 0;
584 for (
size_t ii = 1; ii < hit_v.size(); ii++) {
585 const geo::WireID wireID2 = hit_v.at(ii)->WireID();
586 const auto TPCGeoObject2 = geom->TPC(wireID2.
TPC,wireID2.
Cryostat);
587 driftDir_end = TPCGeoObject2.DetectDriftDirection();
589 if(driftDir_end + driftDir_start == 0){
596 int last_mc_point = 0;
603 if(mc_particle==0x0) {
604 if(
fDebug) std::cout <<
"\t\t\tNo MC particle matched to PFParticle " 618 " us is significantly different from start time: " <<
mc_time <<
630 if(t0_v.size() == 0)
continue;
631 auto t0 = t0_v.at(0);
634 if (
fDebug) std::cout <<
"\t\tTrack crossers cathode - PFParticle has t0: " 639 std::vector<TVector3> split_trk = sorted_trk;
642 std::vector<TVector3> top_trk = {split_trk.at(0), split_trk.at(1)};
643 std::vector<TVector3> bottom_trk = {split_trk.at(2), split_trk.at(3)};
645 if(
fDebug) std::cout <<
"\t\tCathode-crossing point: (" 646 << top_trk.at(1).X() <<
", " << top_trk.at(1).Y() <<
", " 647 << top_trk.at(1).Z() <<
") --> (" << bottom_trk.at(0).X()
648 <<
", " << bottom_trk.at(0).Y() <<
", " << bottom_trk.at(0).Z()
655 TVector3 top_track_start = top_trk.at(0);
656 TVector3 top_track_end = top_trk.at(1);
658 rc_xs = top_track_start.X();
660 rc_ys = top_track_start.Y();
661 rc_zs = top_track_start.Z();
662 rc_xe = top_track_end.X();
664 rc_ye = top_track_end.Y();
665 rc_ze = top_track_end.Z();
677 TVector3 bottom_track_start = bottom_trk.at(0);
678 TVector3 bottom_track_end = bottom_trk.at(1);
680 rc_xs = bottom_track_start.X();
682 rc_ys = bottom_track_start.Y();
683 rc_zs = bottom_track_start.Z();
684 rc_xe = bottom_track_end.X();
686 rc_ye = bottom_track_end.Y();
687 rc_ze = bottom_track_end.Z();
696 else if(
fDebug) std::cout <<
"\t\tTrack does not cross cathode."<<
std::endl;
707 rc_xs = track_start.X();
708 rc_ys = track_start.Y();
709 rc_zs = track_start.Z();
710 rc_xe = track_end.X();
711 rc_ye = track_end.Y();
712 rc_ze = track_end.Z();
725 for (
auto& hits : hit_v) {
726 auto hit_tick = hits->PeakTime();
727 double hit_time = clockData.TPCTick2TrigTime(hit_tick);
734 if(
fDebug) std::cout <<
"\tTrack hits edge of readout window. " 755 if(
fDebug) std::cout <<
"\t\tTrack may enter TPC through " 768 if(
fDebug) std::cout <<
"\t\tTrack may exit TPC through " 778 if(
fDebug) std::cout <<
"\t\tTrack does not pierce anode." <<
std::endl;
783 if(
fDebug) std::cout <<
"\t\tTrack neither enters nor exits" 784 " through non-anode TPC face. No useful end point for SCE" 795 if(op_match_result==99999) {
796 if(
fDebug) std::cout <<
"Unable to match flash to track." <<
std::endl;
816 unsigned int max_pe_channel = 9999;
819 for(pd_ch = 0; pd_ch <= geom->MaxOpChannel(); pd_ch++) {
820 double channel_i_pe = flash_ptr->PE(pd_ch);
821 if(channel_i_pe > max_pe) {
822 max_pe = channel_i_pe;
823 max_pe_channel = pd_ch;
827 if(max_pe_channel==9999||max_pe==0)
continue;
829 if(max_pe_channel<9999) {
843 if(
fDebug) std::cout <<
"\t\tOpChannel " << max_pe_channel <<
844 " has maximum PE, and is located at: (" <<
850 if(
fDebug) std::cout <<
"\t\t Matched to flash w/ index " << op_match_result <<
" w/ PE " 852 " us vs corrected reco time " << anode_rc_time <<
" us" <<
std::endl;
863 if(
fDebug) std::cout <<
"\t\t Matched to op hit w/ index " << op_match_result <<
881 for(
int mc_hit_i=0; mc_hit_i<last_mc_point; mc_hit_i++) {
883 double mc_particle_xi = mc_particle->
Position(mc_hit_i).X();
884 double mc_particle_yi = mc_particle->
Position(mc_hit_i).Y();
885 double mc_particle_zi = mc_particle->
Position(mc_hit_i).Z();
902 std::cout <<
"\t\tMC Particle matched to track has t0: " 903 <<
mc_time <<
" us against reconstructed t0: " 904 << anode_rc_time <<
" us and passes through anode at: (" 915 unsigned int pIndex = particle.
Self();
917 std::vector<anab::T0> t0_apt_v;
921 for(
unsigned int p = 0;
p < findParticleT0s.at(pIndex).size(); ++
p){
922 t0_apt_v.push_back((*(findParticleT0s.at(pIndex)[
p])));
925 if(t0_apt_v.size() != 0) HasT0 =
true;
928 auto t0_apt = t0_apt_v.at(0);
930 std::cout <<
"PFParticle has T0: " << (t0_apt.Time()/1000) <<
931 " us against anode reco time: " << anode_rc_time <<
932 " us with dt_flash_reco " <<
dt_flash_reco <<
" us." << std::endl;
940 if(anode_rc_time < fReadoutWindow && cathode_rc_time > -
fReadoutWindow)
code to link reconstructed objects back to the MC truth information
double matched_flash_max_pe_det_y
unsigned int NumberTrajectoryPoints() const
const TLorentzVector & Position(const int i=0) const
bool TPC_entering_candidate
std::vector< anab::T0 > GetPFParticleT0(const recob::PFParticle &particle, art::Event const &evt, std::string particleLabel) const
Get the T0(s) from a given PFParticle.
double matched_flash_width_y
size_t Self() const
Returns the index of this particle.
double matched_flash_max_pe_det_x
std::vector< size_t > op_id_v
double matched_flash_max_pe_det_z
art::Handle< std::vector< recob::OpHit > > op_hit_h
double mc_particle_z_anode
unsigned int fReadoutWindow
void SortTrackPoints(const recob::Track &track, std::vector< TVector3 > &sorted_trk)
CryostatID_t Cryostat
Index of cryostat.
double matched_flash_time_width
std::string fAnodeT0Producer
bool cathode_crossing_track
std::vector< size_t > flash_id_v
std::vector< double > op_times
std::string fTriggerProducer
timescale_traits< TriggerTimeCategory >::time_point_t trigger_time
A point in time on the trigger time scale.
double Length(size_t p=0) const
Access to various track properties.
const recob::Track * GetPFParticleTrack(const recob::PFParticle &particle, art::Event const &evt, const std::string particleLabel, const std::string trackLabel) const
Get the track associated to this particle. Returns a null pointer if not found.
double T(const int i=0) const
double mc_particle_x_anode
const simb::MCParticle * GetMCParticleFromRecoTrack(detinfo::DetectorClocksData const &clockData, const recob::Track &track, art::Event const &evt, std::string trackModule) const
bool IsPrimary() const
Returns whether the particle is the root of the flow.
bool anode_piercing_candidate
bool TPC_exiting_candidate
double matched_flash_centre_y
double corrected_matched_flash_time
std::string fFlashProducer
Detector simulation of raw signals on wires.
double mc_particle_y_anode
const std::vector< const recob::Hit * > GetRecoTrackHits(const recob::Track &track, art::Event const &evt, const std::string trackModule) const
Get the hits from a given reco track.
Hierarchical representation of particle flow.
art::Handle< std::vector< recob::OpFlash > > flash_h
std::string fTrackProducer
std::string fOpHitProducer
size_t FlashMatch(const double reco_time, std::vector< double > op_times_v)
double matched_flash_width_z
constexpr WireID()=default
Default constructor: an invalid TPC ID.
TPCID_t TPC
Index of the TPC within its cryostat.
double matched_flash_time
double matched_flash_centre_z
Track from a non-cascading particle.A recob::Track consists of a recob::TrackTrajectory, plus additional members relevant for a "fitted" track:
cet::coded_exception< error, detail::translate > exception
void SplitTrack(const recob::Track &track, std::vector< TVector3 > &sorted_trk)
QTextStream & endl(QTextStream &s)