PFPEfficiency_module.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 // Class: PFPEfficiency
3 // Plugin Type: analyzer (art v3_03_01)
4 // File: PFPEfficiency_module.cc
5 //
6 // Generated at Tue Jan 14 20:15:19 2020 by Tingjun Yang using cetskelgen
7 // from cetlib version v3_08_00.
8 ////////////////////////////////////////////////////////////////////////
9 
17 #include "canvas/Persistency/Common/FindManyP.h"
18 #include "fhiclcpp/ParameterSet.h"
22 #include "art_root_io/TFileService.h"
29 #include "TH1D.h"
30 #include "TEfficiency.h"
31 
32 #include <map>
33 #include <string>
34 
35 namespace dune {
36  class PFPEfficiency;
37 }
38 
39 
41 public:
42  explicit PFPEfficiency(fhicl::ParameterSet const& p);
43  // The compiler-generated destructor is fine for non-base
44  // classes without bare pointers or other resource use.
45 
46  // Plugins should not be copied or assigned.
47  PFPEfficiency(PFPEfficiency const&) = delete;
48  PFPEfficiency(PFPEfficiency&&) = delete;
49  PFPEfficiency& operator=(PFPEfficiency const&) = delete;
51 
52  // Required functions.
53  void analyze(art::Event const& e) override;
54 
55  void beginJob() override;
56  void endJob() override;
57 
58 private:
59 
63 
64  float fFidVolCutX;
65  float fFidVolCutY;
66  float fFidVolCutZ;
67 
68  float fFidVolXmin;
69  float fFidVolXmax;
70  float fFidVolYmin;
71  float fFidVolYmax;
72  float fFidVolZmin;
73  float fFidVolZmax;
74 
75  int MC_isCC;
77  double MC_incoming_P[4];
78  double MC_vertex[4];
80 
81  bool insideFV(double vertex[4]);
82 
83  //efficiency
84  TH1D *h_den[6];
85  TH1D *h_num[6];
86  TEfficiency *eff[6];
87 
88  //efficiency for completeness and purity > 0.5
89  TH1D *h_num_good[6];
90  TEfficiency *eff_good[6];
91 
93  int pdg[6];
94 
95 };
96 
97 
99  : EDAnalyzer{p},
100  fMCTruthModuleLabel(p.get<std::string>("MCTruthModuleLabel")),
101  fPFPModuleLabel(p.get<std::string>("PFPModuleLabel")),
102  fHitModuleLabel(p.get<std::string>("HitModuleLabel")),
103  fFidVolCutX(p.get<float>("FidVolCutX")),
104  fFidVolCutY(p.get<float>("FidVolCutY")),
105  fFidVolCutZ(p.get<float>("FidVolCutZ"))
106 {
107  names[0] = "piplus";
108  names[1] = "piminus";
109  names[2] = "proton";
110  names[3] = "muon";
111  names[4] = "el";
112  names[5] = "gamma";
113 
114  pdg[0] = 211;
115  pdg[1] = -211;
116  pdg[2] = 2212;
117  pdg[3] = 13;
118  pdg[4] = 11;
119  pdg[5] = 22;
120 }
121 
123 {
124 
125  //!save neutrino's interaction info
126  auto MCtruthHandle = event.getHandle<std::vector<simb::MCTruth> >(fMCTruthModuleLabel);
127  std::vector<art::Ptr<simb::MCTruth>> MCtruthlist;
128  art::fill_ptr_vector(MCtruthlist, MCtruthHandle);
129  art::Ptr<simb::MCTruth> MCtruth;
130 
131  MCtruth = MCtruthlist[0];
132  if( MCtruth->NeutrinoSet() ){
133  simb::MCNeutrino nu = MCtruth->GetNeutrino();
134  if( nu.CCNC() == 0 ) MC_isCC = 1;
135  else if ( nu.CCNC() == 1 ) MC_isCC = 0;
136  simb::MCParticle neutrino = nu.Nu();
137  MC_incoming_PDG = nu.Nu().PdgCode();
138  const TLorentzVector& nu_momentum = nu.Nu().Momentum(0);
139  nu_momentum.GetXYZT(MC_incoming_P);
140  const TLorentzVector& vertex =neutrino.Position(0);
141  vertex.GetXYZT(MC_vertex);
142  }
143 
144  if (!MC_isCC) return;
145  if (std::abs(MC_incoming_PDG)!=16) return;
146 
147  bool isFiducial =insideFV( MC_vertex );
148  if( !isFiducial ) return;
149 
150  // * hits
151  std::vector<art::Ptr<recob::Hit> > hitlist;
152  auto hitListHandle = event.getHandle< std::vector<recob::Hit> >(fHitModuleLabel);
153  if (hitListHandle)
154  art::fill_ptr_vector(hitlist, hitListHandle);
155 
156  std::vector < art::Ptr < recob::PFParticle > > pfpList;
157  auto pfpListHandle = event.getHandle < std::vector < recob::PFParticle > >(fPFPModuleLabel);
158  if (pfpListHandle) {
159  art::fill_ptr_vector(pfpList, pfpListHandle);
160  }
161 
162  // Get all clusters
163  std::vector < art::Ptr < recob::Cluster > > cluList;
164  auto cluListHandle = event.getHandle < std::vector < recob::Cluster > >(fPFPModuleLabel);
165  if (cluListHandle) {
166  art::fill_ptr_vector(cluList, cluListHandle);
167  }
168 
169  // Get cluster-PFParticle association
170  art::FindManyP<recob::Cluster> fmcpfp(pfpListHandle, event, fPFPModuleLabel);
171 
172  // Get hit-cluster association
173  art::FindManyP<recob::Hit> fmhc(cluListHandle, event, fPFPModuleLabel);
174 
177 
178  std::map<int, int> hitmap;
179 
180  for (auto const& hit : hitlist){
181  if (hit->WireID().Plane!=2) continue;
182  std::map<int,double> trkide;
183  std::vector<sim::TrackIDE> TrackIDs = bt_serv->HitToEveTrackIDEs(hit);
184  for(size_t e = 0; e < TrackIDs.size(); ++e){
185  trkide[TrackIDs[e].trackID] += TrackIDs[e].energy;
186  }
187  double maxe = -1;
188  double tote = 0;
189  int TrackID = 0;
190  for (std::map<int,double>::iterator ii = trkide.begin(); ii!=trkide.end(); ++ii){
191  tote += ii->second;
192  if ((ii->second)>maxe){
193  maxe = ii->second;
194  TrackID = ii->first;
195  }
196  }
197  const simb::MCParticle *particle = pi_serv->TrackIdToParticle_P(TrackID);
198  if (particle){
199  ++hitmap[TrackID];
200  }
201  }
202 
203  std::map<int, float> completeness;
204  std::map<int, float> purity;
205 
206  for (size_t i = 0; i<pfpList.size(); ++i){
207  std::map<int, int> hitmap0;
208  if (fmcpfp.isValid()){
209  // Get clusters associated with pfparticle
210  auto const& clusters = fmcpfp.at(i);
211  for (auto const & cluster : clusters){
212  if (fmhc.isValid()){
213  // Get hits associated with cluster
214  auto const& hits = fmhc.at(cluster.key());
215  //auto const& hits = hitsFromSlice.at(sliceid);
216  //std::cout<<hits.size()<<std::endl;
217  for (auto const& hit : hits){
218  if (hit->WireID().Plane!=2) continue;
219  std::map<int,double> trkide;
220  std::vector<sim::TrackIDE> TrackIDs = bt_serv->HitToEveTrackIDEs(hit);
221  for(size_t e = 0; e < TrackIDs.size(); ++e){
222  trkide[TrackIDs[e].trackID] += TrackIDs[e].energy;
223  }
224  double maxe = -1;
225  double tote = 0;
226  int TrackID = 0;
227  for (std::map<int,double>::iterator ii = trkide.begin(); ii!=trkide.end(); ++ii){
228  tote += ii->second;
229  if ((ii->second)>maxe){
230  maxe = ii->second;
231  TrackID = ii->first;
232  }
233  }
234  const simb::MCParticle *particle = pi_serv->TrackIdToParticle_P(TrackID);
235  if (particle){
236  ++hitmap0[TrackID];
237  }
238  }
239  }
240  }
241  }
242  int maxhits = -1;
243  int tothits = 0;
244  int TrackID = 0;
245  for (std::map<int,int>::iterator ii = hitmap0.begin(); ii!=hitmap0.end(); ++ii){
246  tothits += ii->second;
247  if ((ii->second)>maxhits){
248  maxhits = ii->second;
249  TrackID = ii->first;
250  }
251  }
252  if (TrackID){
253  double new_completeness = 1.0*maxhits/hitmap[TrackID];
254  double new_purity = 1.0*maxhits/tothits;
255  //const simb::MCParticle *particle = pi_serv->TrackIdToParticle_P(TrackID);
256  //if (particle->PdgCode() == 13) std::cout<<new_completeness<<" "<<new_purity<<std::endl;
257  if (new_completeness*new_purity > completeness[TrackID]*purity[TrackID]){
258  completeness[TrackID] = new_completeness;
259  purity[TrackID] = new_purity;
260  }
261  }
262  }
263 
264  const sim::ParticleList& plist = pi_serv->ParticleList();
265  for( sim::ParticleList::const_iterator ipar = plist.begin(); ipar!=plist.end(); ++ipar){
266  simb::MCParticle *particle = ipar->second;
267  if (particle->Mother() == 0){ //primary particle
268  for (int i = 0; i<6; ++i){
269  if (particle->PdgCode() == pdg[i]){
270  h_den[i]->Fill(particle->P());
271  if (completeness[particle->TrackId()]>0){
272  h_num[i]->Fill(particle->P());
273  //if (i==3) std::cout<<completeness[particle->TrackId()]<<" "<<purity[particle->TrackId()]<<std::endl;
274  if (completeness[particle->TrackId()]>0.5&&
275  purity[particle->TrackId()]>0.5){
276  h_num_good[i]->Fill(particle->P());
277  }
278  }
279  }
280  }
281  }
282  }
283 }
284 
286  // Get geometry.
287  auto const* geo = lar::providerFrom<geo::Geometry>();
288  // Define histogram boundaries (cm).
289  // For now only draw cryostat=0.
290  double minx = 1e9;
291  double maxx = -1e9;
292  double miny = 1e9;
293  double maxy = -1e9;
294  double minz = 1e9;
295  double maxz = -1e9;
296  for (size_t i = 0; i<geo->NTPC(); ++i){
297  double local[3] = {0.,0.,0.};
298  double world[3] = {0.,0.,0.};
299  const geo::TPCGeo &tpc = geo->TPC(i);
300  tpc.LocalToWorld(local,world);
301  if (minx>world[0]-geo->DetHalfWidth(i))
302  minx = world[0]-geo->DetHalfWidth(i);
303  if (maxx<world[0]+geo->DetHalfWidth(i))
304  maxx = world[0]+geo->DetHalfWidth(i);
305  if (miny>world[1]-geo->DetHalfHeight(i))
306  miny = world[1]-geo->DetHalfHeight(i);
307  if (maxy<world[1]+geo->DetHalfHeight(i))
308  maxy = world[1]+geo->DetHalfHeight(i);
309  if (minz>world[2]-geo->DetLength(i)/2.)
310  minz = world[2]-geo->DetLength(i)/2.;
311  if (maxz<world[2]+geo->DetLength(i)/2.)
312  maxz = world[2]+geo->DetLength(i)/2.;
313  }
314 
315  fFidVolXmin = minx + fFidVolCutX;
316  fFidVolXmax = maxx - fFidVolCutX;
317  fFidVolYmin = miny + fFidVolCutY;
318  fFidVolYmax = maxy - fFidVolCutY;
319  fFidVolZmin = minz + fFidVolCutZ;
320  fFidVolZmax = maxz - fFidVolCutZ;
321 
322  std::cout<<"Fiducial volume:"<<"\n"
323  <<fFidVolXmin<<"\t< x <\t"<<fFidVolXmax<<"\n"
324  <<fFidVolYmin<<"\t< y <\t"<<fFidVolYmax<<"\n"
325  <<fFidVolZmin<<"\t< z <\t"<<fFidVolZmax<<"\n";
326 
328 
329  for (int i = 0; i<6; ++i){
330  h_den[i] = tfs->make<TH1D>(Form("h_den_%s",names[i].c_str()), Form("%s;Momentum (GeV/c)", names[i].c_str()), 40, 0, 20);
331  h_num[i] = tfs->make<TH1D>(Form("h_num_%s",names[i].c_str()), Form("%s;Momentum (GeV/c)", names[i].c_str()), 40, 0, 20);
332  h_num_good[i] = tfs->make<TH1D>(Form("h_num_good_%s",names[i].c_str()), Form("%s;Momentum (GeV/c)", names[i].c_str()), 40, 0, 20);
333  h_den[i]->Sumw2();
334  h_num[i]->Sumw2();
335  h_num_good[i]->Sumw2();
336  }
337 }
338 
340 
342 
343  for (int i = 0; i<6; ++i){
344  if (TEfficiency::CheckConsistency(*h_num[i], *h_den[i])){
345  eff[i] = tfs->make<TEfficiency>(*h_num[i], *h_den[i]);
346  eff[i]->SetTitle(names[i].c_str());
347  eff[i]->Write(Form("eff_%s",names[i].c_str()));
348  }
349  if (TEfficiency::CheckConsistency(*h_num_good[i], *h_den[i])){
350  eff_good[i] = tfs->make<TEfficiency>(*h_num_good[i], *h_den[i]);
351  eff_good[i]->SetTitle((names[i]+", completeness>0.5, purity>0.5").c_str());
352  eff_good[i]->Write(Form("eff_good_%s",names[i].c_str()));
353  }
354  }
355 }
357 
358  double x = vertex[0];
359  double y = vertex[1];
360  double z = vertex[2];
361 
362  if (x>fFidVolXmin && x<fFidVolXmax&&
363  y>fFidVolYmin && y<fFidVolYmax&&
364  z>fFidVolZmin && z<fFidVolZmax)
365  return true;
366  else
367  return false;
368 }
369 
intermediate_table::iterator iterator
const TLorentzVector & Position(const int i=0) const
Definition: MCParticle.h:219
int PdgCode() const
Definition: MCParticle.h:212
int CCNC() const
Definition: MCNeutrino.h:148
const simb::MCNeutrino & GetNeutrino() const
Definition: MCTruth.h:77
std::string string
Definition: nybbler.cc:12
std::vector< TrackID > TrackIDs
const simb::MCParticle * TrackIdToParticle_P(int id) const
int Mother() const
Definition: MCParticle.h:213
const simb::MCParticle & Nu() const
Definition: MCNeutrino.h:146
Geometry information for a single TPC.
Definition: TPCGeo.h:38
intermediate_table::const_iterator const_iterator
Cluster finding and building.
EDAnalyzer(fhicl::ParameterSet const &pset)
Definition: EDAnalyzer.h:25
Particle class.
TEfficiency * eff_good[6]
art framework interface to geometry description
int TrackId() const
Definition: MCParticle.h:210
T abs(T value)
const double e
#define DEFINE_ART_MODULE(klass)
Definition: ModuleMacros.h:67
double P(const int i=0) const
Definition: MCParticle.h:234
p
Definition: test.py:223
PFPEfficiency & operator=(PFPEfficiency const &)=delete
PFPEfficiency(fhicl::ParameterSet const &p)
Detector simulation of raw signals on wires.
const sim::ParticleList & ParticleList() const
Declaration of signal hit object.
void analyze(art::Event const &e) override
std::vector< sim::TrackIDE > HitToEveTrackIDEs(detinfo::DetectorClocksData const &clockData, recob::Hit const &hit) const
const TLorentzVector & Momentum(const int i=0) const
Definition: MCParticle.h:220
list x
Definition: train.py:276
bool NeutrinoSet() const
Definition: MCTruth.h:78
void fill_ptr_vector(std::vector< Ptr< T >> &ptrs, H const &h)
Definition: Ptr.h:297
Event generator information.
Definition: MCNeutrino.h:18
LArSoft geometry interface.
Definition: ChannelGeo.h:16
void LocalToWorld(const double *tpc, double *world) const
Transform point from local TPC frame to world frame.
Definition: TPCGeo.h:563
Event finding and building.
bool insideFV(double vertex[4])
vertex reconstruction