20 #include "art_root_io/TFileService.h" 69 size_t FlashMatch (
const double reco_time, std::vector<double> op_times_v);
182 auto const* geom = lar::providerFrom<geo::Geometry>();
189 for (
geo::TPCID const& tID: geom->IterateTPCIDs()) {
198 double tpc_top = center[1] + TPC.
HalfHeight();
199 double tpc_bottom = center[1] - TPC.
HalfHeight();
200 double tpc_front = center[2] - TPC.
HalfLength();
201 double tpc_back = center[2] + TPC.
HalfLength();
203 if (tpc_top > det_top) det_top = tpc_top;
213 double efield = detProp.Efield();
214 if(
fDebug) std::cout <<
"Nominal electric field is: " << efield <<
" V/cm" <<
std::endl;
216 double temp = detProp.Temperature();
217 if(
fDebug) std::cout <<
"LAr temperature is: " << temp <<
" K" <<
std::endl;
230 produces < std::vector<anab::T0> >();
231 produces < art::Assns<recob::PFParticle, anab::T0> >();
236 MC = !(
event.isRealData());
247 if(
fDebug) std::cout <<
"\tAnode piercing tracks selected by cuts.\n\t\t Min length: " 249 " and flash-reco time difference between " <<
dtMin <<
" and " 252 auto t0_v = std::make_unique<std::vector<anab::T0>>();
253 auto pfp_t0 = std::make_unique<art::Assns<recob::PFParticle, anab::T0>>();
255 int track_number = 0;
260 double TPC_trigger_offset = 0.0;
263 if(
fDebug) std::cout <<
"Set event number: " <<
event.event() <<
"\nTop: " 283 std::cerr<<
"\033[93m[ERROR]\033[00m ... could not locate Flash!"<<
std::endl;
290 auto trigger_h =
event.getHandle<std::vector<recob::OpFlash> >(
fTriggerProducer);
292 if( (!trigger_h) || trigger_h->empty()) {
299 if(
fDebug) std::cout <<
"Loading trigger time from producer " 302 trigger_time = trigger_h->at(0).Time();
308 auto reco_particles_h =
event.getValidHandle<std::vector<recob::PFParticle>>(
fPFPProducer);
309 const art::FindManyP<recob::Track> findTracks(reco_particles_h,event,
fTrackProducer);
310 auto reco_tracks_h =
event.getValidHandle<std::vector<recob::Track>>(
fTrackProducer);
311 art::FindManyP<recob::Hit> findHits(reco_tracks_h, event,
fTrackProducer);
313 if(!reco_particles_h.isValid()) {
314 std::cerr<<
"\033[93m[ERROR]\033[00m ... could not locate PFParticles!"<<
std::endl;
324 TPC_trigger_offset = clockData.TriggerOffsetTPC();
325 if(
fDebug) std::cout <<
"TPC time offset from trigger: " 326 << TPC_trigger_offset <<
" us" <<
std::endl;
330 size_t flash_ctr = 0;
331 for (
auto const& flash : *
flash_h){
332 if (flash.TotalPE() >
fMinPE){
333 double op_flash_time;
335 if(
MC) op_flash_time = flash.Time() - trigger_time - TPC_trigger_offset;
338 if (
fDebug) std::cout <<
"\t Flash: " << flash_ctr <<
" has time : " 339 << op_flash_time <<
", PE : " << flash.TotalPE() <<
std::endl;
348 size_t ev_particle_ctr = 0;
350 for(
unsigned int particle = 0; particle < reco_particles_h->size(); ++particle){
363 const std::vector<art::Ptr<recob::Track>> pfpTracks = findTracks.at(pfparticle.
Self());
364 if( pfpTracks.size() != 0 ){
365 track = (pfpTracks.at(0)).
get();
368 if(
fDebug) std::cout <<
"\tPFParticle " << ev_particle_ctr <<
" is not track like" <<
std::endl;
372 if (
fDebug) std::cout <<
"\tLooping through reco PFParticle " << ev_particle_ctr <<
std::endl;
376 std::vector<art::Ptr<recob::Hit>> inputHits = findHits.at(track->
ID());
377 std::vector<const recob::Hit*> hit_v;
379 hit_v.push_back(
hit.get());
415 std::vector<TVector3> sorted_trk;
418 TVector3 track_start = sorted_trk.at(0);
419 TVector3 track_end = sorted_trk.at(sorted_trk.size() - 1);
421 if(
fDebug) std::cout <<
"\t\tTrack goes from (" << track_start.X() <<
", " 422 << track_start.Y() <<
", " << track_start.Z() <<
") --> (" << track_end.X() <<
", " 423 << track_end.Y() <<
", " << track_end.Z() <<
")" <<
std::endl;
426 if(
fDebug) std::cout <<
"\t\t\tParticle track too short. Skipping." <<
std::endl;
430 auto const* geom = lar::providerFrom<geo::Geometry>();
431 auto const* first_hit = hit_v.at(0);
433 const auto TPCGeoObject_start = geom->TPC(wireID_start.
TPC,wireID_start.
Cryostat);
434 short int driftDir_start = TPCGeoObject_start.DetectDriftDirection();
436 short int driftDir_end = 0;
439 for (
size_t ii = 1; ii < hit_v.size(); ii++) {
440 const geo::WireID wireID_end = hit_v.at(ii)->WireID();
441 const auto TPCGeoObject_end = geom->TPC(wireID_end.
TPC,wireID_end.
Cryostat);
442 driftDir_end = TPCGeoObject_end.DetectDriftDirection();
444 if(driftDir_end + driftDir_start == 0){
452 if(
fDebug) std::cout <<
"\t\tThis track starts in TPC " << wireID_start.
TPC 453 <<
" which has a drift direction of " << driftDir_start <<
std::endl;
457 rc_xs = track_start.X();
458 rc_ys = track_start.Y();
459 rc_zs = track_start.Z();
460 rc_xe = track_end.X();
461 rc_ye = track_end.Y();
462 rc_ze = track_end.Z();
470 for (
auto& hits : hit_v) {
471 auto hit_tick = hits->PeakTime();
474 if(
fDebug) std::cout <<
"\tTrack hits edge of readout window. " 479 double hit_time = clockData.TPCTick2TrigTime(hit_tick);
498 if(
fDebug) std::cout <<
"\t\tTrack may enter TPC through " 511 if(
fDebug) std::cout <<
"\t\tTrack may exit TPC through " 520 if(
fDebug) std::cout <<
"\t\tTrack does not pierce anode." <<
std::endl;
525 if(
fDebug) std::cout <<
"\t\tTrack neither enters nor exits" 526 " through non-anode TPC face. No useful end point for SCE" 538 if(op_match_result==99999) {
539 if(
fDebug) std::cout <<
"Unable to match flash to track." <<
std::endl;
588 if(
fDebug) std::cout <<
"\t\t Matched to flash w/ index " << op_match_result
598 if(
fDebug) std::cout <<
"\t\tPFParticle: " << particle <<
599 " has a matched flash and passes cuts. Assigning T0: " 603 t0_v->push_back(anode_t0);
626 TVector3 track_start, track_end;
633 if ((trk_loc.X() < -998.)||(trk_loc.Y() < -998.)||(trk_loc.Z() < -998))
continue;
635 if (trk_loc.Y() < end_y){
637 track_end = {trk_loc.X(), trk_loc.Y(), trk_loc.Z()};
640 if (trk_loc.Y() > start_y){
641 start_y = trk_loc.Y();
642 track_start = {trk_loc.X(), trk_loc.Y(), trk_loc.Z()};
646 sorted_trk.push_back(track_start);
647 sorted_trk.push_back(track_end);
655 double dt_min = 9999999.;
656 size_t matched_op_id = 99999;
658 for (
size_t i=0; i < op_times_v.size(); i++){
659 double op_time_i = op_times_v[i];
661 double corrected_flash_reco_time_diff = corrected_op_time_i - reco_time;
662 if (fabs(corrected_flash_reco_time_diff) < dt_min){
663 dt_min = fabs(corrected_flash_reco_time_diff);
668 return matched_op_id;
void SortTrackPoints(const recob::Track &track, std::vector< TVector3 > &sorted_trk)
std::vector< size_t > flash_id_v
size_t Self() const
Returns the index of this particle.
double corrected_matched_flash_time
Point_t const & LocationAtPoint(size_t i) const
EDProducer(fhicl::ParameterSet const &pset)
Geometry information for a single TPC.
size_t NumberTrajectoryPoints() const
Various functions related to the presence and the number of (valid) points.
CryostatID_t Cryostat
Index of cryostat.
double HalfLength() const
Length is associated with z coordinate [cm].
art framework interface to geometry description
bool anode_piercing_candidate
bool isValid() const noexcept
std::string fTriggerProducer
timescale_traits< TriggerTimeCategory >::time_point_t trigger_time
A point in time on the trigger time scale.
std::string fTrackProducer
double Length(size_t p=0) const
Access to various track properties.
#define DEFINE_ART_MODULE(klass)
unsigned int ReadoutWindow
key_type key() const noexcept
T get(std::string const &key) const
T0RecoAnodePiercers(fhicl::ParameterSet const &p)
void produce(art::Event &event)
std::string fFlashProducerData
bool IsPrimary() const
Returns whether the particle is the root of the flow.
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.
bool TPC_entering_candidate
The data type to uniquely identify a TPC.
bool TPC_exiting_candidate
std::string fFlashProducerMC
Detector simulation of raw signals on wires.
double HalfHeight() const
Height is associated with y coordinate [cm].
Declaration of signal hit object.
T0RecoAnodePiercers & operator=(T0RecoAnodePiercers const &)=delete
double DriftDistance() const
Hierarchical representation of particle flow.
art::Handle< std::vector< recob::OpFlash > > flash_h
Provides recob::Track data product.
std::vector< double > op_times
constexpr WireID()=default
Default constructor: an invalid TPC ID.
double matched_flash_time
size_t FlashMatch(const double reco_time, std::vector< double > op_times_v)
TPCID_t TPC
Index of the TPC within its cryostat.
void LocalToWorld(const double *tpc, double *world) const
Transform point from local TPC frame to world frame.
std::string fFlashProducer
Track from a non-cascading particle.A recob::Track consists of a recob::TrackTrajectory, plus additional members relevant for a "fitted" track:
constexpr Point origin()
Returns a origin position with a point of the specified type.
cet::coded_exception< error, detail::translate > exception
QTextStream & endl(QTextStream &s)
Event finding and building.