21 #include "nusimdata/SimulationBase/MCParticle.h"
22 #include "nusimdata/SimulationBase/MCTruth.h"
27 #include "art/Framework/Core/EDAnalyzer.h"
28 #include "art/Framework/Principal/Event.h"
29 #include "art/Framework/Principal/Handle.h"
30 #include "art_root_io/TFileService.h"
31 #include "canvas/Persistency/Common/FindManyP.h"
32 #include "fhiclcpp/ParameterSet.h"
33 #include "fhiclcpp/types/Table.h"
34 #include "fhiclcpp/types/Atom.h"
36 #include "Pandora/PdgTable.h"
62 Name(
"SimModuleLabel"),
63 Comment(
"tag of detector simulation data product")
67 Name(
"TpcTrackModuleLabel"),
68 Comment(
"tag of TPC track producer data product")
72 Name(
"CaloModuleLabel"),
73 Comment(
"tag of calorimetry producer data product")
78 Comment(
"tag of pandora data product")
83 Comment(
"Print information about what's going on")
86 fhicl::Table<StoppingParticleCosmicIdAlg::Config>
SPTagAlg {
101 virtual void analyze(
const art::Event& event)
override;
104 virtual void endJob()
override;
125 std::vector<std::string>
types {
"NuMuTrack",
"CrTrack",
"DirtTrack",
"NuTrack",
"NuMuPfp",
"CrPfp",
"DirtPfp",
"NuPfp"};
139 , fSimModuleLabel (config().SimModuleLabel())
140 , fTpcTrackModuleLabel (config().TpcTrackModuleLabel())
141 , fCaloModuleLabel (config().CaloModuleLabel())
142 , fPandoraLabel (config().PandoraLabel())
143 , fVerbose (config().
Verbose())
144 , spTag (config().SPTagAlg())
154 art::ServiceHandle<art::TFileService>
tfs;
157 hRatioTag[
type] = tfs->make<TH1D>(Form(
"%sRatioTag",
type.c_str()),
"", 20, 1, 3);
165 if(
fVerbose)
std::cout<<
"----------------- Stopping Particle Cosmic ID Ana Module -------------------"<<std::endl;
172 art::ServiceHandle<cheat::ParticleInventoryService> pi_serv;
176 std::cout<<
"============================================"<<std::endl
177 <<
"Run = "<<
event.run()<<
", SubRun = "<<
event.subRun()<<
", Event = "<<
event.id().event()<<std::endl
178 <<
"============================================"<<std::endl;
186 auto particleHandle =
event.getValidHandle<std::vector<simb::MCParticle>>(
fSimModuleLabel);
193 art::FindManyP<anab::Calorimetry> findManyCalo(tpcTrackHandle, event,
fCaloModuleLabel);
198 if( !pfParticleHandle.isValid() ){
205 art::FindManyP< recob::Track > pfPartToTrackAssoc(pfParticleHandle, event,
fTpcTrackModuleLabel);
211 std::map<int, simb::MCParticle> particles;
212 std::vector<int> nuParticleIds;
213 std::vector<int> lepParticleIds;
214 std::vector<int> dirtParticleIds;
215 std::vector<int> crParticleIds;
217 for (
auto const& particle: (*particleHandle)){
220 int partID = particle.TrackId();
221 particles[partID] = particle;
224 art::Ptr<simb::MCTruth> truth = pi_serv->TrackIdToMCTruth_P(partID);
228 if(truth->Origin() == simb::kBeamNeutrino){
230 vtx.SetX(truth->GetNeutrino().Nu().Vx()); vtx.SetY(truth->GetNeutrino().Nu().Vy()); vtx.SetZ(truth->GetNeutrino().Nu().Vz());
233 dirtParticleIds.push_back(partID);
236 else if(pdg==13 && particle.Mother()==0){
237 lepParticleIds.push_back(partID);
241 nuParticleIds.push_back(partID);
247 crParticleIds.push_back(partID);
256 auto const clockData = art::ServiceHandle<detinfo::DetectorClocksService const>()->DataFor(event);
258 for(
auto const& tpcTrack : (*tpcTrackHandle)){
261 std::vector<art::Ptr<recob::Hit>> hits = findManyHits.at(tpcTrack.ID());
263 std::string
type =
"none";
264 if(std::find(lepParticleIds.begin(), lepParticleIds.end(), trueId) != lepParticleIds.end()) type =
"NuMuTrack";
265 if(std::find(nuParticleIds.begin(), nuParticleIds.end(), trueId) != nuParticleIds.end()) type =
"NuTrack";
266 if(std::find(crParticleIds.begin(), crParticleIds.end(), trueId) != crParticleIds.end()) type =
"CrTrack";
267 if(std::find(dirtParticleIds.begin(), dirtParticleIds.end(), trueId) != dirtParticleIds.end()) type =
"DirtTrack";
268 if(type ==
"none")
continue;
270 std::vector<art::Ptr<anab::Calorimetry>> calos = findManyCalo.at(tpcTrack.ID());
271 if(calos.size()==0)
continue;
274 if(
std::abs(particles[trueId].PdgCode()) != 13)
continue;
276 geo::Point_t trueEnd {particles[trueId].EndX(), particles[trueId].EndY(), particles[trueId].EndZ()};
284 TVector3 trueEndVec (particles[trueId].EndX(), particles[trueId].EndY(), particles[trueId].EndZ());
285 TVector3 start = tpcTrack.Vertex<TVector3>();
286 TVector3
end = tpcTrack.End<TVector3>();
288 if((start-trueEndVec).Mag() < (end-trueEndVec).Mag()) recoEnd = tpcTrack.Vertex();
297 int nbins =
hRatioTotal.begin()->second->GetNbinsX();
298 for(
int i = 0; i < nbins; i++){
299 double ratioCut =
hRatioTotal.begin()->second->GetBinCenter(i);
304 if((startChi2 > ratioCut && !
fTPCGeo.
InFiducial(tpcTrack.End(), 5.) && tpcTrack.End().Y() > 0)
305 || (endChi2 > ratioCut && !
fTPCGeo.
InFiducial(tpcTrack.Vertex(), 5.) && tpcTrack.Vertex().Y() > 0)){
314 for (PFParticleIdMap::const_iterator it = pfParticleMap.begin(); it != pfParticleMap.end(); ++it){
316 const art::Ptr<recob::PFParticle> pParticle(it->second);
318 if (!pParticle->IsPrimary())
continue;
320 const int pdg(pParticle->PdgCode());
323 if(!isNeutrino)
continue;
325 std::string
type =
"none";
326 std::vector<recob::Track> nuTracks;
329 for (
const size_t daughterId : pParticle->Daughters()){
332 art::Ptr<recob::PFParticle> pDaughter = pfParticleMap.at(daughterId);
333 const std::vector< art::Ptr<recob::Track> > associatedTracks(pfPartToTrackAssoc.at(pDaughter.key()));
334 if(associatedTracks.size() != 1)
continue;
338 nuTracks.push_back(tpcTrack);
341 std::vector<art::Ptr<recob::Hit>> hits = findManyHits.at(tpcTrack.
ID());
343 if(std::find(lepParticleIds.begin(), lepParticleIds.end(), trueId) != lepParticleIds.end()){
346 else if(std::find(nuParticleIds.begin(), nuParticleIds.end(), trueId) != nuParticleIds.end()){
347 if(type !=
"NuMuPfp") type =
"NuPfp";
349 else if(std::find(dirtParticleIds.begin(), dirtParticleIds.end(), trueId) != dirtParticleIds.end()){
350 if(type !=
"NuMuPfp" && type !=
"NuPfp") type =
"DirtPfp";
352 else if(std::find(crParticleIds.begin(), crParticleIds.end(), trueId) != crParticleIds.end()){
353 if(type !=
"NuMuPfp" && type !=
"NuPfp" && type !=
"DirtPfp") type =
"CrPfp";
357 if(nuTracks.size() == 0)
continue;
359 std::sort(nuTracks.begin(), nuTracks.end(), [](
auto&
left,
auto&
right){
360 return left.Length() >
right.Length();});
363 std::vector<art::Ptr<recob::Hit>> hits = findManyHits.at(tpcTrack.ID());
366 std::vector<art::Ptr<anab::Calorimetry>> calos = findManyCalo.at(tpcTrack.ID());
367 if(calos.size()==0)
continue;
370 if(
std::abs(particles[trueId].PdgCode()) != 13)
continue;
372 geo::Point_t trueEnd {particles[trueId].EndX(), particles[trueId].EndY(), particles[trueId].EndZ()};
380 TVector3 trueEndVec (particles[trueId].EndX(), particles[trueId].EndY(), particles[trueId].EndZ());
381 TVector3 start = tpcTrack.Vertex<TVector3>();
382 TVector3
end = tpcTrack.End<TVector3>();
384 if((start-trueEndVec).Mag() < (end-trueEndVec).Mag()) recoEnd = tpcTrack.Vertex();
393 int nbins =
hRatioTotal.begin()->second->GetNbinsX();
394 for(
int i = 0; i < nbins; i++){
395 double ratioCut =
hRatioTotal.begin()->second->GetBinCenter(i);
400 if((startChi2 > ratioCut && !
fTPCGeo.
InFiducial(tpcTrack.End(), 5.) && tpcTrack.End().Y() > 0)
401 || (endChi2 > ratioCut && !
fTPCGeo.
InFiducial(tpcTrack.Vertex(), 5.) && tpcTrack.Vertex().Y() > 0)){
419 for (
unsigned int i = 0; i < pfParticleHandle->size(); ++i){
420 const art::Ptr<recob::PFParticle> pParticle(pfParticleHandle, i);
421 if (!pfParticleMap.insert(PFParticleIdMap::value_type(pParticle->Self(), pParticle)).second){
422 std::cout <<
" Unable to get PFParticle ID map, the input PFParticle collection has repeat IDs!" <<
"\n";
std::map< std::string, TH1D * > hNoStopLength
fhicl::Atom< art::InputTag > TpcTrackModuleLabel
std::map< std::string, TH1D * > hRatioTag
fhicl::Atom< art::InputTag > SimModuleLabel
Declaration of signal hit object.
std::map< std::string, TH1D * > hRatioTotal
StoppingCosmicIdAna(Parameters const &config)
double StoppingChiSq(geo::Point_t end, std::vector< art::Ptr< anab::Calorimetry >> calos)
std::map< size_t, art::Ptr< recob::PFParticle > > PFParticleIdMap
art::InputTag fSimModuleLabel
name of detsim producer
art::EDAnalyzer::Table< Config > Parameters
virtual void beginJob() override
virtual void analyze(const art::Event &event) override
art::InputTag fTpcTrackModuleLabel
name of TPC track producer
void GetPFParticleIdMap(const PFParticleHandle &pfParticleHandle, PFParticleIdMap &pfParticleMap)
auto end(FixedBins< T, C > const &) noexcept
art::InputTag fPandoraLabel
bool fVerbose
print information about what's going on
BEGIN_PROLOG vertical distance to the surface Name
int TrueParticleIDFromTotalRecoHits(detinfo::DetectorClocksData const &clockData, const std::vector< art::Ptr< recob::Hit > > &hits, bool rollup_unsaved_ids=1)
std::vector< std::string > types
fhicl::Table< StoppingParticleCosmicIdAlg::Config > SPTagAlg
virtual void endJob() override
Definition of data types for geometry description.
fhicl::Atom< art::InputTag > PandoraLabel
Provides recob::Track data product.
art::Handle< std::vector< recob::PFParticle > > PFParticleHandle
StoppingParticleCosmicIdAlg spTag
std::map< std::string, TH1D * > hStopLength
stream1 can override from command line with o or output services user sbnd
art::ServiceHandle< art::TFileService > tfs
art::InputTag fCaloModuleLabel
name of calorimetry producer
std::map< std::string, TH1D * > hStopChiSq
ROOT::Math::PositionVector3D< ROOT::Math::Cartesian3D< double >, ROOT::Math::GlobalCoordinateSystemTag > Point_t
Type for representation of position in physical 3D space.
BEGIN_PROLOG could also be cout
fhicl::Atom< bool > Verbose
std::map< std::string, TH1D * > hNoStopChiSq
fhicl::Atom< art::InputTag > CaloModuleLabel
Track from a non-cascading particle.A recob::Track consists of a recob::TrackTrajectory, plus additional members relevant for a "fitted" track:
bool InFiducial(geo::Point_t point, double fiducial)