7 #include "art/Framework/Core/EDAnalyzer.h"
8 #include "art/Framework/Core/ModuleMacros.h"
9 #include "art/Framework/Principal/Event.h"
10 #include "art/Framework/Principal/Handle.h"
11 #include "art/Framework/Services/Registry/ServiceHandle.h"
12 #include "art_root_io/TFileService.h"
13 #include "canvas/Persistency/Common/Ptr.h"
14 #include "fhiclcpp/ParameterSet.h"
15 #include "messagefacility/MessageLogger/MessageLogger.h"
23 #include "nusimdata/SimulationBase/MCParticle.h"
50 void analyze (
const art::Event&);
71 std::vector<recob::Track>
const&);
77 std::vector<simb::MCParticle>
const&,
87 std::vector<simb::MCParticle>
const&,
95 std::vector<simb::MCParticle>
const&,
132 DEFINE_ART_MODULE(OpticalRecoAna)
144 fPEMin = pset.get<
float>(
"PEMin");
157 art::ServiceHandle<art::TFileService const>
tfs;
158 fTimeDiff = tfs->make<TH1F>(
"htdiff",
"Time difference between particles and flashes; t_diff (ns); flash/particle pairs",1e3,-5e6,5e6);
159 fTimeDiff_fine = tfs->make<TH1F>(
"htdiff_fine",
"Time difference between particles and flashes; t_diff (ns); flash/particle pairs",100,-1000,1000);
160 fNBeamFlashes = tfs->make<TH1I>(
"hNBeamFlashes",
"Number of flashes OnBeamTime per event; N_{Flashes}; Events",5,0,5);
162 fMatchTree_PF = tfs->make<TTree>(
"MatchTree_PF",
"MatchTree_PF");
163 fMatchTree_PF->Branch(
"Run",&fRun,
"Run/I");
164 fMatchTree_PF->Branch(
"Event",&fEvent,
"Event/I");
165 fMatchTree_PF->Branch(
"p_id",&fParticleID,
"p_id/I");
166 fMatchTree_PF->Branch(
"p_time",&fParticleTime,
"p_time/F");
167 fMatchTree_PF->Branch(
"p_vx",&fParticleVx,
"p_vx/F");
168 fMatchTree_PF->Branch(
"p_vy",&fParticleVy,
"p_vy/F");
169 fMatchTree_PF->Branch(
"p_vz",&fParticleVz,
"p_vz/F");
170 fMatchTree_PF->Branch(
"p_mid",&fParticleMother,
"p_mid/I");
171 fMatchTree_PF->Branch(
"p_trackid",&fParticleTrackID,
"p_trackid/I");
172 fMatchTree_PF->Branch(
"FlashID",&fFlashID,
"flash_id/I");
173 fMatchTree_PF->Branch(
"f_time",&fFlashTime,
"f_time/F");
174 fMatchTree_PF->Branch(
"f_timewidth",&fFlashTimeWidth,
"f_timewidth/F");
175 fMatchTree_PF->Branch(
"f_y",&fFlashY,
"f_y/F");
176 fMatchTree_PF->Branch(
"f_z",&fFlashZ,
"f_z/F");
177 fMatchTree_PF->Branch(
"f_ywidth",&fFlashYWidth,
"f_ywidth/F");
178 fMatchTree_PF->Branch(
"f_zwidth",&fFlashYWidth,
"f_zwidth/F");
179 fMatchTree_PF->Branch(
"f_onbeamtime",&fFlashOnBeamTime,
"f_onbeamtime/I");
180 fMatchTree_PF->Branch(
"f_pe",&fFlashPE,
"f_pe/F");
181 fMatchTree_PF->Branch(
"matchIndex",&fMatchIndex,
"matchIndex/I");
183 fMatchTree_PF_NotNu = tfs->make<TTree>(
"MatchTree_PF_NotNu",
"MatchTree_PF_NotNu");
184 fMatchTree_PF_NotNu->Branch(
"Run",&fRun,
"Run/I");
185 fMatchTree_PF_NotNu->Branch(
"Event",&fEvent,
"Event/I");
186 fMatchTree_PF_NotNu->Branch(
"p_id",&fParticleID,
"p_id/I");
187 fMatchTree_PF_NotNu->Branch(
"p_time",&fParticleTime,
"p_time/F");
188 fMatchTree_PF_NotNu->Branch(
"p_vx",&fParticleVx,
"p_vx/F");
189 fMatchTree_PF_NotNu->Branch(
"p_vy",&fParticleVy,
"p_vy/F");
190 fMatchTree_PF_NotNu->Branch(
"p_vz",&fParticleVz,
"p_vz/F");
191 fMatchTree_PF_NotNu->Branch(
"p_mid",&fParticleMother,
"p_mid/I");
192 fMatchTree_PF_NotNu->Branch(
"p_trackid",&fParticleTrackID,
"p_trackid/I");
193 fMatchTree_PF_NotNu->Branch(
"FlashID",&fFlashID,
"flash_id/I");
194 fMatchTree_PF_NotNu->Branch(
"f_time",&fFlashTime,
"f_time/F");
195 fMatchTree_PF_NotNu->Branch(
"f_timewidth",&fFlashTimeWidth,
"f_timewidth/F");
196 fMatchTree_PF_NotNu->Branch(
"f_y",&fFlashY,
"f_y/F");
197 fMatchTree_PF_NotNu->Branch(
"f_z",&fFlashZ,
"f_z/F");
198 fMatchTree_PF_NotNu->Branch(
"f_ywidth",&fFlashYWidth,
"f_ywidth/F");
199 fMatchTree_PF_NotNu->Branch(
"f_zwidth",&fFlashYWidth,
"f_zwidth/F");
200 fMatchTree_PF_NotNu->Branch(
"f_onbeamtime",&fFlashOnBeamTime,
"f_onbeamtime/I");
201 fMatchTree_PF_NotNu->Branch(
"f_pe",&fFlashPE,
"f_pe/F");
202 fMatchTree_PF_NotNu->Branch(
"matchIndex",&fMatchIndex_NotNu,
"matchIndex/I");
213 const bool is_MC= !(evt.isRealData());
215 fRun = evt.id().run();
216 fEvent = evt.id().event();
219 art::Handle< std::vector<recob::OpFlash> > flash_handle;
220 evt.getByLabel(fFlashModuleLabel, flash_handle);
221 std::vector<recob::OpFlash>
const& flash_vector(*flash_handle);
222 fFlash_match_vector.resize(flash_vector.size());
224 MF_LOG_INFO (
"OpticalRecoAna")
225 <<
"Number of flashes is " << flash_vector.size() << std::flush;
240 art::ServiceHandle<cheat::ParticleInventoryService const> pi_serv;
241 std::vector<simb::MCParticle> particle_list;
242 get_MC_particle_list(pi_serv->ParticleList(),particle_list);
243 fParticle_match_vector.resize(particle_list.size());
245 mf::LogInfo(
"OpticalRecoAna")
246 <<
"Number of MC particles is " << particle_list.size();
249 art::ServiceHandle<opdet::OpDigiProperties const> odp;
250 const float ns_per_PMT_tick = 1e3;
251 art::ServiceHandle<geo::Geometry const> geometry_handle;
253 match_flashes_to_particles(flash_vector,
264 for(
auto const& my_flash : flash_vector){
265 if(my_flash.OnBeamTime()==1) n_flashes++;
267 fNBeamFlashes->Fill(n_flashes);
278 art::ServiceHandle<cheat::ParticleInventoryService const> pi_serv;
279 return (pi_serv->TrackIdToMCTruth_P(particle.TrackId()))->Origin();
284 for(sim::ParticleList::const_iterator ipart = plist.begin(); ipart != plist.end(); ++ipart) {
286 const simb::MCParticle* particle = (*ipart).second;
293 if( particle->E() < 0.001*particle->Mass() + fKineticEnergyMin )
continue;
310 particle_vector.emplace_back(*particle);
323 unsigned int tpc = 0;
324 unsigned int cstat = 0;
326 const size_t numtraj = particle.NumberTrajectoryPoints();
328 while(t_iter < numtraj){
331 double pos[3] = {particle.Vx(t_iter), particle.Vy(t_iter), particle.Vz(t_iter)};
334 catch(cet::exception &
e){
341 if(t_iter == numtraj)
345 return particle.T(t_iter);
349 std::vector<recob::Track>
const& track_vector){
352 for(
size_t i_flash=0; i_flash < flash_vector.size(); i_flash++){
355 if(my_flash.TotalPE() < fPEMin)
continue;
357 for(
size_t i_track=0; i_track < track_vector.size(); i_track++){
359 recob::Track const& my_track( track_vector.at(i_track) );
362 compare_track_and_flash(my_track,my_flash,matching);
364 fFlash_match_vector.at(i_flash).track_indices.push_back(i_track);
365 fTrack_match_vector.at(i_track).flash_indices.push_back(i_flash);
380 std::vector<simb::MCParticle>
const& particle_vector,
381 float const& ns_per_PMT_tick,
386 int lastFlashID = -1;
388 for(
size_t i_particle=0; i_particle < particle_vector.size(); i_particle++){
390 simb::MCParticle
const& my_particle( particle_vector.at(i_particle) );
391 bool pass_check =
false;
392 const float particle_time = update_MC_particle_time(my_particle,pass_check,geometry);
393 if(!pass_check)
continue;
397 for(
size_t i_flash=0; i_flash < flash_vector.size(); i_flash++){
400 if(my_flash.TotalPE() < fPEMin)
continue;
402 const float flash_time = my_flash.
Time()*ns_per_PMT_tick;
407 fTimeDiff->Fill(particle_time-flash_time);
408 fTimeDiff_fine->Fill(particle_time-flash_time);
410 fParticleID = i_particle;
411 fParticleTime = particle_time;
412 fParticleVx = my_particle.Vx(0);
413 fParticleVy = my_particle.Vy(0);
414 fParticleVz = my_particle.Vz(0);
415 fParticleMother = my_particle.Mother();
416 fParticleTrackID = my_particle.TrackId();
418 fFlashTime = flash_time;
419 fFlashTimeWidth = my_flash.TimeWidth()*ns_per_PMT_tick;
420 fFlashY = my_flash.YCenter();
421 fFlashZ = my_flash.ZCenter();
422 fFlashYWidth = my_flash.YWidth();
423 fFlashZWidth = my_flash.ZWidth();
424 fFlashPE = my_flash.TotalPE();
425 fFlashOnBeamTime = my_flash.OnBeamTime();
427 bool beam_match = ((
std::abs(particle_time - flash_time )/fFlashTimeWidth)<fTimeMatchMax &&
428 get_MC_particle_origin(my_particle)==simb::kBeamNeutrino);
429 bool nonbeam_match = ((
std::abs(particle_time - flash_time )/fFlashTimeWidth)<fTimeMatchMax &&
430 get_MC_particle_origin(my_particle)!=simb::kBeamNeutrino);
433 fMatchTree_PF->Fill();
442 fFlash_match_vector.at(i_flash).particle_indices.push_back(i_particle);
443 fParticle_match_vector.at(i_particle).flash_indices.push_back(i_flash);
445 else if( nonbeam_match ){
446 if(lastFlashID!=fFlashID){
447 fMatchTree_PF_NotNu->Fill();
449 lastFlashID = fFlashID;
461 std::vector<simb::MCParticle>
const& particle_vector,
462 float const& ns_per_PMT_tick,
465 for(
size_t i_flash=0; i_flash < flash_vector.size(); i_flash++){
468 const float flash_time = my_flash.
Time()*ns_per_PMT_tick;
470 for(
auto i_particle : fFlash_match_vector.at(i_flash).particle_indices){
472 simb::MCParticle
const& my_particle( particle_vector.at(i_particle) );
473 bool pass_check =
false;
474 const float particle_time = update_MC_particle_time(my_particle,pass_check,geometry);
476 if(my_particle.Mother()==0 && my_particle.TrackId()>1e4){
478 fParticleID = i_particle;
479 fParticleTime = particle_time;
480 fParticleVx = my_particle.Vx(0);
481 fParticleVy = my_particle.Vy(0);
482 fParticleVz = my_particle.Vz(0);
484 fFlashTime = flash_time;
485 fFlashY = my_flash.YCenter();
486 fFlashZ = my_flash.ZCenter();
487 fFlashYWidth = my_flash.YWidth();
488 fFlashZWidth = my_flash.ZWidth();
490 fMatchTree_PF->Fill();
505 float const& ns_per_PMT_tick,
510 std::vector<simb::MCParticle>
const& particle_vector,
514 for(
size_t i_track=0; i_track < track_vector.size(); i_track++){
516 recob::Track const& my_track( track_vector.at(i_track) );
518 for(
size_t i_particle=0; i_particle < particle_vector.size(); i_particle++){
520 simb::MCParticle
const& my_particle( particle_vector.at(i_particle) );
523 compare_particle_and_track(my_particle,my_track,matching,geometry);
525 fTrack_match_vector.at(i_track).particle_indices.push_back(i_track);
526 fParticle_match_vector.at(i_particle).track_indices.push_back(i_track);
void match_flashes_to_particles(std::vector< recob::OpFlash > const &, std::vector< simb::MCParticle > const &, float const &, geo::Geometry const &)
std::string fFlashModuleLabel
OpticalRecoAna(const fhicl::ParameterSet &)
const geo::GeometryCore * geometry
void compare_track_and_flash(recob::Track const &, recob::OpFlash const &, bool &)
void analyze(const art::Event &)
std::vector< flash_match > fFlash_match_vector
process_name use argoneut_mc_hitfinder track
std::vector< size_t > track_indices
geo::TPCGeo const & PositionToTPC(geo::Point_t const &point) const
Returns the TPC at specified location.
simb::Origin_t get_MC_particle_origin(simb::MCParticle const &)
std::vector< size_t > flash_indices
void FillMatchTree_PF(std::vector< recob::OpFlash > const &, std::vector< simb::MCParticle > const &, float const &, geo::Geometry const &)
std::string fTrackModuleLabel
void compare_particle_and_flash(simb::MCParticle const &, recob::OpFlash const &, bool &, float const &, geo::Geometry const &)
TTree * fMatchTree_PF_NotNu
std::vector< size_t > flash_indices
The geometry of one entire detector, as served by art.
void match_flashes_to_tracks(std::vector< recob::OpFlash > const &, std::vector< recob::Track > const &)
Provides recob::Track data product.
std::vector< particle_match > fParticle_match_vector
void get_MC_particle_list(sim::ParticleList const &, std::vector< simb::MCParticle > &)
void compare_particle_and_track(simb::MCParticle const &, recob::Track const &, bool &, geo::Geometry const &)
std::vector< size_t > particle_indices
float update_MC_particle_time(simb::MCParticle const &, bool &, geo::Geometry const &)
std::vector< size_t > particle_indices
art::ServiceHandle< art::TFileService > tfs
std::vector< size_t > track_indices
std::vector< track_match > fTrack_match_vector
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: