181 art::ServiceHandle<geo::Geometry const> geom;
182 if (geom->Nplanes() > 3)
return;
185 art::Handle<std::vector<recob::Hit>> hitListHandle;
187 std::vector<art::Ptr<recob::Hit>> allhits;
188 art::fill_ptr_vector(allhits, hitListHandle);
189 if (
empty(allhits))
return;
192 art::Handle<std::vector<recob::Cluster>> clusterListHandle;
195 if (clusterListHandle->size() == 0)
return;
198 art::Handle<std::vector<recob::Vertex>> vertexListHandle;
200 art::PtrVector<recob::Vertex> recoVtxList;
201 double xyz[3] = {0, 0, 0};
202 for (
unsigned int ii = 0; ii < vertexListHandle->size(); ++ii) {
203 art::Ptr<recob::Vertex>
vertex(vertexListHandle, ii);
204 recoVtxList.push_back(
vertex);
209 art::Handle<std::vector<recob::PFParticle>> PFPListHandle;
211 art::PtrVector<recob::PFParticle> recoPFPList;
212 for (
unsigned int ii = 0; ii < PFPListHandle->size(); ++ii) {
213 art::Ptr<recob::PFParticle> pfp(PFPListHandle, ii);
214 recoPFPList.push_back(pfp);
215 mf::LogVerbatim(
"PFPAna") <<
"PFParticle PDG " << pfp->PdgCode();
219 art::ServiceHandle<cheat::BackTrackerService const> bt_serv;
220 art::ServiceHandle<cheat::ParticleInventoryService const> pi_serv;
221 sim::ParticleList
const& plist = pi_serv->ParticleList();
223 std::vector<const simb::MCParticle*> plist2;
225 std::vector<std::vector<art::Ptr<recob::Hit>>> hlist2;
227 std::vector<std::vector<short>> truToCl;
229 std::vector<std::vector<unsigned short>> nTruHitInCl;
231 std::vector<unsigned short> nRecHitInCl;
236 float aveNuEP2mu = 0.;
237 float numNuEP2mu = 0.;
238 float aveNuEP2nm = 0.;
239 float numNuEP2nm = 0.;
245 int neutTrackID = -1;
246 std::vector<int> tidlist;
247 float neutEnergy = -1.;
248 int neutIntType = -1;
251 auto const clockData = art::ServiceHandle<detinfo::DetectorClocksService const>()->DataFor(
evt);
253 for (sim::ParticleList::const_iterator ipart = plist.begin(); ipart != plist.end(); ++ipart) {
254 const simb::MCParticle* part = (*ipart).second;
256 int pdg =
abs(part->PdgCode());
257 int trackID = part->TrackId();
258 art::Ptr<simb::MCTruth> theTruth = pi_serv->TrackIdToMCTruth_P(trackID);
262 mf::LogVerbatim(
"PFPAna") <<
"Pre-Cuts origin " << theTruth->Origin() <<
" trackID "
263 << trackID <<
" PDG " << part->PdgCode() <<
" E " << part->E()
264 <<
" mass " << part->Mass() <<
" Mother "
265 << part->Mother() + neutTrackID <<
" Proc " << part->Process();
269 if (theTruth->Origin() == simb::kBeamNeutrino && neutTrackID < 0) {
270 neutTrackID = trackID;
271 simb::MCNeutrino theNeutrino = theTruth->GetNeutrino();
272 neutEnergy = 1000. * theNeutrino.Nu().E();
273 neutIntType = theNeutrino.InteractionType();
274 neutCCNC = theNeutrino.CCNC();
275 for (
unsigned short iv = 0; iv < recoVtxList.size(); ++iv) {
276 recoVtxList[iv]->XYZ(xyz);
283 bool isCharged = (pdg == 11) || (pdg == 13) || (pdg == 211) || (pdg == 321) || (pdg == 2212);
285 if (!isCharged)
continue;
287 float KE = 1000 * (part->E() - part->Mass());
292 if (part->Process() !=
"primary")
continue;
312 if (part->Process() ==
"NeutronInelastic")
continue;
313 plist2.push_back(part);
314 tidlist.push_back(trackID);
316 std::vector<short> temp{-1, -1, -1};
317 truToCl.push_back(temp);
319 std::vector<unsigned short> temp2(3);
320 nTruHitInCl.push_back(temp2);
323 mf::LogVerbatim(
"PFPAna") << plist2.size() - 1 <<
" Origin " << theTruth->Origin()
324 <<
" trackID " << trackID <<
" PDG " << part->PdgCode() <<
" KE "
325 << (int)KE <<
" Mother " << part->Mother() + neutTrackID
326 <<
" Proc " << part->Process();
329 if (
empty(plist2))
return;
332 hlist2 = bt_serv->TrackIdsToHits_Ps(clockData, tidlist, allhits);
333 if (hlist2.size() != plist2.size()) {
334 mf::LogError(
"PFPAna") <<
"MC particle list size " << plist2.size()
335 <<
" != size of MC particle true hits lists " << hlist2.size();
341 std::vector<std::pair<unsigned short, unsigned short>> moda;
346 for (
unsigned short dpl = plist2.size() - 1; dpl > 0; --dpl) {
348 if (plist2[dpl]->Mother() == 0)
continue;
350 if (
abs(plist2[dpl]->PdgCode()) == 11)
continue;
352 int motherID = neutTrackID + plist2[dpl]->Mother() - 1;
354 if (motherID < 0)
continue;
357 for (
unsigned short kpl = 0; kpl < plist2.size(); ++kpl) {
358 if (plist2[kpl]->Mother() == motherID) ++ndtr;
361 if (ndtr > 1)
continue;
364 for (
unsigned short jpl = dpl - 1; jpl > 0; --jpl) {
365 if (plist2[jpl]->TrackId() == motherID) {
371 if (mpl < 0)
continue;
373 if (plist2[dpl]->PdgCode() != plist2[mpl]->PdgCode())
continue;
374 moda.push_back(std::make_pair(mpl, dpl));
379 art::PtrVector<recob::Cluster> clusters;
380 for (
unsigned int ii = 0; ii < clusterListHandle->size(); ++ii) {
381 art::Ptr<recob::Cluster> clusterHolder(clusterListHandle, ii);
382 clusters.push_back(clusterHolder);
386 nRecHitInCl.resize(clusters.size());
390 std::map<geo::View_t, unsigned int> ViewToPlane;
391 for (
unsigned int plane = 0; plane < geom->Nplanes(); ++plane) {
393 ViewToPlane[view] = plane;
395 for (
size_t icl = 0; icl < clusters.size(); ++icl) {
396 unsigned int plane = ViewToPlane[clusters[icl]->View()];
397 std::vector<art::Ptr<recob::Hit>> cluhits = fmh.at(icl);
399 nRecHitInCl[icl] = cluhits.size();
401 std::vector<unsigned short> nHitInPl2(plist2.size());
402 for (
size_t iht = 0; iht < cluhits.size(); ++iht) {
411 for (
unsigned short ipl = 0; ipl < plist2.size(); ++ipl) {
412 unsigned short imat = 0;
413 for (imat = 0; imat < hlist2[ipl].size(); ++imat) {
414 if (cluhits[iht] == hlist2[ipl][imat])
break;
416 if (imat < hlist2[ipl].
size()) {
421 if (hitInPl2 < 0)
continue;
425 for (
unsigned short imd = 0; imd < moda.size(); ++imd) {
426 if (moda[imd].
second == hitInPl2) hitInPl2 = moda[imd].first;
429 ++nHitInPl2[hitInPl2];
433 unsigned short nhit = 0;
435 for (
unsigned int ipl = 0; ipl < nHitInPl2.size(); ++ipl) {
436 if (nHitInPl2[ipl] > nhit) {
437 nhit = nHitInPl2[ipl];
445 if (nhit > nTruHitInCl[imtru][plane]) {
446 truToCl[imtru][plane] = icl;
447 nTruHitInCl[imtru][plane] = nhit;
453 for (
unsigned short ipl = 0; ipl < plist2.size(); ++ipl) {
456 for (
unsigned short ii = 0; ii < moda.size(); ++ii) {
457 if (moda[ii].
second == ipl) {
462 if (skipit)
continue;
465 if (hlist2[ipl].
size() < 3)
continue;
467 int trackID = plist2[ipl]->TrackId();
468 art::Ptr<simb::MCTruth> theTruth = pi_serv->TrackIdToMCTruth_P(trackID);
470 float KE = 1000 * (plist2[ipl]->E() - plist2[ipl]->Mass());
471 int PDG =
abs(plist2[ipl]->PdgCode());
473 std::vector<short> nTru(geom->Nplanes());
474 std::vector<short> nRec(geom->Nplanes());
475 std::vector<short> nTruRec(geom->Nplanes());
476 std::vector<float> eff(geom->Nplanes());
477 std::vector<float> pur(geom->Nplanes());
478 std::vector<float> ep(geom->Nplanes());
479 for (
unsigned int plane = 0; plane < geom->Nplanes(); ++plane) {
482 for (
unsigned short ii = 0; ii < hlist2[ipl].size(); ++ii) {
483 if (ViewToPlane[hlist2[ipl][ii]->View()] == plane) ++nTru[plane];
488 unsigned short mom = ipl;
489 std::vector<std::pair<unsigned short, unsigned short>>::reverse_iterator rit =
491 while (rit != moda.rend()) {
492 if ((*rit).first == mom) {
493 unsigned short dau = (*rit).second;
494 for (
unsigned short jj = 0; jj < hlist2[dau].size(); ++jj) {
495 if (ViewToPlane[hlist2[dau][jj]->View()] == plane) ++nTru[plane];
507 if (nTru[plane] == 0) {
512 short icl = truToCl[ipl][plane];
513 nRec[plane] = nRecHitInCl[icl];
514 nTruRec[plane] = nTruHitInCl[ipl][plane];
517 if (nTru[plane] > 0) eff[plane] = (float)nTruRec[plane] / (
float)nTru[plane];
518 if (nRec[plane] > 0) pur[plane] = (float)nTruRec[plane] / (
float)nRec[plane];
519 ep[plane] = eff[plane] * pur[plane];
522 std::vector<float> temp;
524 std::sort(temp.begin(), temp.end());
526 unsigned short ii = temp.size() - 2;
527 float ep2 = temp[ii];
530 short ep2Cluster = 0;
531 for (
unsigned short jj = 0; jj < temp.size(); ++jj) {
534 ep2Cluster = truToCl[ipl][ep2Plane];
539 std::array<double, 2> clBeg, clEnd;
540 if (ep2Cluster >= 0) {
541 clBeg[0] = clusters[ep2Cluster]->StartWire();
542 clBeg[1] = clusters[ep2Cluster]->StartTick();
543 clEnd[0] = clusters[ep2Cluster]->EndWire();
544 clEnd[1] = clusters[ep2Cluster]->EndTick();
553 fCRE->Fill(eff[ep2Plane]);
554 fCRP->Fill(pur[ep2Plane]);
558 mf::LogVerbatim(
"PFPAna")
559 <<
">>>CREP2 " << std::fixed << std::setprecision(2) << ep2 <<
" E " << eff[ep2Plane]
560 << std::setprecision(2) <<
" P " << pur[ep2Plane] <<
" P:W:T " << ep2Plane <<
":"
561 << (int)clBeg[0] <<
":" << (
int)clBeg[1] << "-" << ep2Plane << ":" << (
int)clEnd[0]
562 << ":" << (
int)clEnd[1] << " PDG " << PDG << " KE " << (
int)KE << "
MeV";
569 aveNuEP2mu += ep2 * wght;
573 aveNuEP2nm += ep2 * wght;
583 else if (PDG == 13) {
590 else if (PDG == 211) {
597 else if (PDG == 321) {
604 else if (PDG == 2212) {
612 mf::LogVerbatim(
"PFPAna")
613 <<
">>>NuEP2 " << std::fixed << std::setprecision(2) << ep2 <<
" E " << eff[ep2Plane]
614 << std::setprecision(2) <<
" P " << pur[ep2Plane] <<
" P:W:T " << ep2Plane <<
":"
615 << (int)clBeg[0] <<
":" << (
int)clBeg[1] << "-" << ep2Plane << ":" << (
int)clEnd[0]
616 << ":" << (
int)clEnd[1] << " PDG " << PDG << " KE " << (
int)KE << " MeV ";
619 mf::LogVerbatim mfp(
"PFPAna");
620 mfp <<
" Truth P:W:T ";
621 for (
unsigned int plane = 0; plane < geom->Nplanes(); ++plane) {
622 unsigned short loW = 9999;
623 unsigned short loT = 0;
624 unsigned short hiW = 0;
625 unsigned short hiT = 0;
626 for (
unsigned short ii = 0; ii < hlist2[ipl].size(); ++ii) {
627 if (ViewToPlane[hlist2[ipl][ii]->View()] == plane) {
628 art::Ptr<recob::Hit> theHit = hlist2[ipl][ii];
629 if (theHit->WireID().Wire < loW) {
630 loW = theHit->WireID().Wire;
631 loT = theHit->PeakTime();
633 if (theHit->WireID().Wire > hiW) {
634 hiW = theHit->WireID().Wire;
635 hiT = theHit->PeakTime();
639 mfp << plane <<
":" << loW <<
":" << loT <<
"-" << plane <<
":" << hiW <<
":" << hiT
647 if (numNuEP2mu > 0.) ave1 = aveNuEP2mu / numNuEP2mu;
650 if (numNuEP2nm > 0.) ave2 = aveNuEP2nm / numNuEP2nm;
653 if (numCREP2 > 0.) ave3 = aveCREP2 / numCREP2;
655 if (fPrintLevel > 0) {
656 std::string nuType =
"Other";
658 if (neutIntType == 1001) nuType =
"CCQE";
659 if (neutIntType == 1091) nuType =
"DIS";
660 if (neutIntType == 1097) nuType =
"COH";
661 if (neutIntType > 1002 && neutIntType < 1091) nuType =
"RES";
669 mf::LogVerbatim(
"PFPAna") <<
"EvtEP2 " <<
evt.id().
event() <<
" NuType " << nuType <<
" Enu "
670 << std::fixed << std::setprecision(0) << neutEnergy <<
std::right
671 << std::fixed << std::setprecision(2) <<
" NuMuons " << ave1
672 <<
" NuPiKp " << ave2 <<
" CosmicRays " << ave3 <<
" CCNC "
673 << neutCCNC <<
" IntType " << neutIntType;
std::vector< float > fElecKERange
process_name stream1 can override from command line with o or output services DetectorPropertiesService services DetectorPropertiesService services DetectorPropertiesService services DetectorPropertiesService physics analyzers pmtresponse NeutronTrackingCut services LArG4Parameters gaussian physics producers generator PDG
then if[["$THISISATEST"==1]]
std::string fVertexModuleLabel
enum geo::_plane_proj View_t
Enumerate the possible plane projections.
std::string fHitsModuleLabel
std::vector< float > fProtKERange
std::size_t size(FixedBins< T, C > const &) noexcept
std::string fClusterModuleLabel
std::vector< float > fPionKERange
TProfile * fNuEP2_KE_kaon
Charged-current interactions.
TProfile * fNuEP2_KE_elec
TProfile * fNuEP2_KE_pion
A value measured in the specified unit.
std::string fPFParticleModuleLabel
TProfile * fNuEP2_KE_prot
TProfile * fNuEP2_KE_muon
Neutral-current interactions.
std::vector< float > fMuonKERange
bool empty(FixedBins< T, C > const &) noexcept
std::vector< float > fKaonKERange