43 #include "art/Framework/Core/EDProducer.h"
44 #include "art/Framework/Core/ModuleMacros.h"
45 #include "art/Framework/Principal/Event.h"
46 #include "art/Framework/Principal/Handle.h"
47 #include "art_root_io/TFileService.h"
48 #include "canvas/Persistency/Common/FindManyP.h"
49 #include "canvas/Persistency/Common/Ptr.h"
51 #include "canvas/Utilities/InputTag.h"
52 #include "fhiclcpp/ParameterSet.h"
72 #include "nusimdata/SimulationBase/MCParticle.h"
78 class MCTruthT0Matching;
94 void produce(art::Event&
e)
override;
128 fTrackModuleLabel = (
p.get<art::InputTag>(
"TrackModuleLabel"));
129 fShowerModuleLabel = (
p.get<art::InputTag>(
"ShowerModuleLabel"));
130 fPFParticleModuleLabel = (
p.get<art::InputTag>(
"PFParticleModuleLabel",
"pandoraNu"));
131 fMakeT0Assns = (
p.get<
bool>(
"makeT0Assns",
true));
132 fMakePFParticleAssns = (
p.get<
bool>(
"makePFParticleAssns",
false));
134 fMakeHitAssns =
p.get<
bool>(
"makeHitAssns",
true);
135 if (fMakeHitAssns) fHitModuleLabel =
p.get<art::InputTag>(
"HitModuleLabel");
136 fOverrideRealData =
p.get<
bool>(
"OverrideRealData",
false);
140 std::cout <<
"WARNING - You are using deprecated functionality\n";
141 std::cout <<
"MCTruthT0Matching T0 assns will be removed soon\n";
142 std::cout <<
"set your fcl parameter makeT0Assns to false and use MCParticle direct "
143 "associations instead"
145 produces<std::vector<anab::T0>>();
146 produces<art::Assns<recob::Track, anab::T0>>();
147 produces<art::Assns<recob::Shower, anab::T0>>();
148 if (fMakePFParticleAssns) {
149 produces<art::Assns<recob::PFParticle, anab::T0>>();
153 produces<art::Assns<recob::Track, simb::MCParticle, anab::BackTrackerMatchingData>>();
154 produces<art::Assns<recob::Shower, simb::MCParticle, anab::BackTrackerMatchingData>>();
155 if (fMakePFParticleAssns) {
156 produces<art::Assns<recob::PFParticle, simb::MCParticle, anab::BackTrackerMatchingData>>();
160 produces<art::Assns<recob::Hit, simb::MCParticle, anab::BackTrackerHitMatchingData>>();
167 art::ServiceHandle<art::TFileService const>
tfs;
168 fTree = tfs->make<TTree>(
"MCTruthT0Matching",
"MCTruthT0");
169 fTree->Branch(
"TrueTrackT0", &TrueTrackT0,
"TrueTrackT0/D");
170 fTree->Branch(
"TrueTrackID", &TrueTrackID,
"TrueTrackID/D");
176 if (evt.isRealData() && !fOverrideRealData)
return;
179 art::ServiceHandle<geo::Geometry const> geom;
180 art::ServiceHandle<cheat::BackTrackerService const> bt_serv;
181 art::ServiceHandle<cheat::ParticleInventoryService const> pi_serv;
182 auto const clockData =
183 art::ServiceHandle<detinfo::DetectorClocksService const>()->DataFor(evt);
186 art::Handle<std::vector<recob::Track>> trackListHandle;
187 std::vector<art::Ptr<recob::Track>> tracklist;
188 if (evt.getByLabel(fTrackModuleLabel, trackListHandle))
189 art::fill_ptr_vector(tracklist, trackListHandle);
192 art::Handle<std::vector<recob::Shower>> showerListHandle;
193 std::vector<art::Ptr<recob::Shower>> showerlist;
194 if (evt.getByLabel(fShowerModuleLabel, showerListHandle))
195 art::fill_ptr_vector(showerlist, showerListHandle);
198 art::Handle<std::vector<recob::PFParticle>> pfparticleListHandle;
199 std::vector<art::Ptr<recob::PFParticle>> pfparticlelist;
200 if (evt.getByLabel(fPFParticleModuleLabel, pfparticleListHandle))
201 art::fill_ptr_vector(pfparticlelist, pfparticleListHandle);
203 auto mcpartHandle = evt.getValidHandle<std::vector<simb::MCParticle>>(
"largeant");
206 std::unique_ptr<std::vector<anab::T0>> T0col(
new std::vector<anab::T0>);
208 std::unique_ptr<art::Assns<recob::Track, anab::T0>> Trackassn(
209 new art::Assns<recob::Track, anab::T0>);
210 std::unique_ptr<art::Assns<recob::Shower, anab::T0>> Showerassn(
211 new art::Assns<recob::Shower, anab::T0>);
212 std::unique_ptr<art::Assns<recob::PFParticle, anab::T0>> PFParticleassn(
213 new art::Assns<recob::PFParticle, anab::T0>);
217 std::unique_ptr<art::Assns<recob::Track, simb::MCParticle, anab::BackTrackerMatchingData>>
218 MCPartTrackassn(
new art::Assns<recob::Track, simb::MCParticle, anab::BackTrackerMatchingData>);
219 std::unique_ptr<art::Assns<recob::Shower, simb::MCParticle, anab::BackTrackerMatchingData>>
221 new art::Assns<recob::Shower, simb::MCParticle, anab::BackTrackerMatchingData>);
222 std::unique_ptr<art::Assns<recob::PFParticle, simb::MCParticle, anab::BackTrackerMatchingData>>
223 MCPartPFParticleassn(
224 new art::Assns<recob::PFParticle, simb::MCParticle, anab::BackTrackerMatchingData>);
226 std::unique_ptr<art::Assns<recob::Hit, simb::MCParticle, anab::BackTrackerHitMatchingData>>
227 MCPartHitassn(
new art::Assns<recob::Hit, simb::MCParticle, anab::BackTrackerHitMatchingData>);
238 std::unordered_map<int, int> trkid_lookup;
243 art::Handle<std::vector<recob::Hit>> hitListHandle;
244 evt.getByLabel(fHitModuleLabel, hitListHandle);
246 if (hitListHandle.isValid()) {
248 auto const& hitList(*hitListHandle);
249 auto const& mcpartList(*mcpartHandle);
250 for (
size_t i_h = 0; i_h < hitList.size(); ++i_h) {
251 art::Ptr<recob::Hit> hitPtr(hitListHandle, i_h);
252 auto trkide_list = bt_serv->HitToTrackIDEs(clockData, hitPtr);
253 struct TrackIDEinfo {
257 std::map<int, TrackIDEinfo> trkide_collector;
264 for (
auto const& t : trkide_list) {
265 trkide_collector[t.trackID].E += t.energy;
267 if (trkide_collector[t.trackID].E > maxe) {
268 maxe = trkide_collector[t.trackID].E;
269 maxtrkid = t.trackID;
271 trkide_collector[t.trackID].NumElectrons += t.numElectrons;
272 totn += t.numElectrons;
273 if (trkide_collector[t.trackID].NumElectrons > maxn) {
274 maxn = trkide_collector[t.trackID].NumElectrons;
275 maxntrkid = t.trackID;
279 if (trkid_lookup.find(t.trackID) == trkid_lookup.end()) {
281 while (i_p < mcpartList.size()) {
282 if (mcpartList[i_p].TrackId() == t.trackID) {
283 trkid_lookup[t.trackID] = (int)i_p;
288 if (i_p == mcpartList.size()) trkid_lookup[t.trackID] = -1;
294 for (
auto const& t : trkide_collector) {
295 int mcpart_i = trkid_lookup[t.first];
296 if (mcpart_i == -1)
continue;
297 art::Ptr<simb::MCParticle> mcpartPtr(mcpartHandle, mcpart_i);
299 bthmd.
isMaxIDE = (t.first == maxtrkid);
301 bthmd.
isMaxIDEN = (t.first == maxntrkid);
302 MCPartHitassn->addSingle(hitPtr, mcpartPtr, bthmd);
311 if (trackListHandle.isValid()) {
313 art::FindManyP<recob::Hit> fmtht(trackListHandle, evt, fTrackModuleLabel);
315 size_t NTracks = tracklist.size();
318 for (
size_t iTrk = 0; iTrk < NTracks; ++iTrk) {
323 std::vector<art::Ptr<recob::Hit>> allHits = fmtht.at(iTrk);
325 std::map<int, double> trkide;
326 for (
size_t h = 0;
h < allHits.size(); ++
h) {
327 art::Ptr<recob::Hit>
hit = allHits[
h];
328 std::vector<sim::IDE> ides;
329 std::vector<sim::TrackIDE>
TrackIDs = bt_serv->HitToTrackIDEs(clockData, hit);
331 for (
size_t e = 0;
e < TrackIDs.size(); ++
e) {
332 trkide[TrackIDs[
e].trackID] += TrackIDs[
e].energy;
338 for (std::map<int, double>::iterator ii = trkide.begin(); ii != trkide.end(); ++ii) {
340 if ((ii->second) > maxe) {
348 const simb::MCParticle* tmpParticle = pi_serv->TrackIdToParticle_P(
TrackID);
353 for (
auto const particle : *mcpartHandle) {
355 if (
TrackID == particle.TrackId()) {
break; }
357 const simb::MCParticle particle = mcpartHandle.product()->at(mcpart_i);
358 TrueTrackT0 = particle.T();
359 TrueTrackID = particle.TrackId();
362 T0col->push_back(
anab::T0(TrueTrackT0, TrueTriggerType, TrueTrackID, (*T0col).size()));
364 auto diff = mcpart_i;
365 if (diff >= (
int)mcpartHandle->size()) {
366 std::cout <<
"Error, the backtracker is doing weird things to your pointers!" << std::endl;
367 throw std::exception();
370 art::Ptr<simb::MCParticle> mcpartPtr(mcpartHandle, mcpart_i);
371 MCPartTrackassn->addSingle(tracklist[iTrk], mcpartPtr, btdata);
372 if (fMakeT0Assns) {
util::CreateAssn(*
this, evt, *T0col, tracklist[iTrk], *Trackassn); }
378 if (showerListHandle.isValid()) {
379 art::FindManyP<recob::Hit> fmsht(showerListHandle, evt, fShowerModuleLabel);
381 size_t NShowers = showerlist.size();
386 std::vector<art::Ptr<recob::Hit>> allHits = fmsht.at(
Shower);
389 std::map<int, double> showeride;
390 for (
size_t h = 0;
h < allHits.size(); ++
h) {
391 art::Ptr<recob::Hit>
hit = allHits[
h];
392 std::vector<sim::IDE> ides;
393 std::vector<sim::TrackIDE>
TrackIDs = bt_serv->HitToTrackIDEs(clockData, hit);
395 for (
size_t e = 0;
e < TrackIDs.size(); ++
e) {
396 showeride[TrackIDs[
e].trackID] += TrackIDs[
e].energy;
402 for (std::map<int, double>::iterator ii = showeride.begin(); ii != showeride.end(); ++ii) {
404 if ((ii->second) > maxe) {
406 ShowerID = ii->first;
412 const simb::MCParticle* tmpParticle = pi_serv->TrackIdToParticle_P(ShowerID);
417 for (
auto const particle : *mcpartHandle) {
419 if (ShowerID == particle.TrackId()) {
break; }
421 const simb::MCParticle particle = mcpartHandle.product()->at(mcpart_i);
422 ShowerT0 = particle.T();
423 ShowerID = particle.TrackId();
424 ShowerTriggerType = 2;
425 T0col->push_back(
anab::T0(ShowerT0, ShowerTriggerType, ShowerID, (*T0col).size()));
427 auto diff = mcpart_i;
428 if (diff >= (
int)mcpartHandle->size()) {
429 std::cout <<
"Error, the backtracker is doing weird things to your pointers!" << std::endl;
430 throw std::exception();
432 art::Ptr<simb::MCParticle> mcpartPtr(mcpartHandle, mcpart_i);
434 MCPartShowerassn->addSingle(showerlist[
Shower], mcpartPtr, btdata);
439 if (pfparticleListHandle.isValid()) {
441 art::FindManyP<recob::Cluster> fmcp(pfparticleListHandle, evt, fPFParticleModuleLabel);
443 size_t NPfparticles = pfparticlelist.size();
446 for (
size_t iPfp = 0; iPfp < NPfparticles; ++iPfp) {
452 std::vector<art::Ptr<recob::Hit>> allHits;
454 std::vector<art::Ptr<recob::Cluster>> allClusters = fmcp.at(iPfp);
455 art::FindManyP<recob::Hit> fmhcl(allClusters, evt, fPFParticleModuleLabel);
456 for (
size_t iclu = 0; iclu < allClusters.size(); ++iclu) {
457 std::vector<art::Ptr<recob::Hit>> hits = fmhcl.at(iclu);
458 allHits.insert(allHits.end(), hits.begin(), hits.end());
461 std::map<int, double> trkide;
462 for (
size_t h = 0;
h < allHits.size(); ++
h) {
463 art::Ptr<recob::Hit>
hit = allHits[
h];
464 std::vector<sim::IDE> ides;
465 std::vector<sim::TrackIDE>
TrackIDs = bt_serv->HitToTrackIDEs(clockData, hit);
467 for (
size_t e = 0;
e < TrackIDs.size(); ++
e) {
468 trkide[TrackIDs[
e].trackID] += TrackIDs[
e].energy;
474 for (std::map<int, double>::iterator ii = trkide.begin(); ii != trkide.end(); ++ii) {
476 if ((ii->second) > maxe) {
484 const simb::MCParticle* tmpParticle = pi_serv->TrackIdToParticle_P(
TrackID);
489 for (
auto const particle : *mcpartHandle) {
491 if (
TrackID == particle.TrackId()) {
break; }
493 const simb::MCParticle particle = mcpartHandle.product()->at(mcpart_i);
494 TrueTrackT0 = particle.T();
495 TrueTrackID = particle.TrackId();
501 T0col->push_back(
anab::T0(TrueTrackT0, TrueTriggerType, TrueTrackID, (*T0col).size()));
503 auto diff = mcpart_i;
504 if (diff >= (
int)mcpartHandle->size()) {
505 std::cout <<
"Error, the backtracker is doing weird things to your pointers!" << std::endl;
506 throw std::exception();
509 art::Ptr<simb::MCParticle> mcpartPtr(mcpartHandle, mcpart_i);
514 if (fMakePFParticleAssns) {
516 util::CreateAssn(*
this, evt, *T0col, pfparticlelist[iPfp], *PFParticleassn);
518 MCPartPFParticleassn->addSingle(pfparticlelist[iPfp], mcpartPtr, btdata);
525 evt.put(std::move(T0col));
526 evt.put(std::move(Trackassn));
527 evt.put(std::move(Showerassn));
528 if (fMakePFParticleAssns) { evt.put(std::move(PFParticleassn)); }
530 evt.put(std::move(MCPartTrackassn));
531 evt.put(std::move(MCPartShowerassn));
532 if (fMakePFParticleAssns) { evt.put(std::move(MCPartPFParticleassn)); }
533 if (fMakeHitAssns) evt.put(std::move(MCPartHitassn));
art::InputTag fPFParticleModuleLabel
MCTruthT0Matching & operator=(MCTruthT0Matching const &)=delete
std::vector< TrackID > TrackIDs
Declaration of signal hit object.
MCTruthT0Matching(fhicl::ParameterSet const &p)
void produce(art::Event &e) override
art::InputTag fHitModuleLabel
art::InputTag fTrackModuleLabel
Declaration of cluster object.
Provides recob::Track data product.
bool CreateAssn(art::Event &evt, std::vector< T > const &a, art::Ptr< U > const &b, art::Assns< U, T > &assn, std::string a_instance, size_t index=UINT_MAX)
Creates a single one-to-one association.
bool fMakePFParticleAssns
art::ServiceHandle< art::TFileService > tfs
art::InputTag fShowerModuleLabel
art framework interface to geometry description
BEGIN_PROLOG could also be cout