TCShowerAnalysis_module.cc
Go to the documentation of this file.
1 // -------------------------------------------------
2 // tcshower analysis tree
3 //
4 // Author: Rory Fitzpatrick (roryfitz@umich.edu)
5 // Created: 7/16/18
6 // -------------------------------------------------
7 
8 // Framework includes
13 #include "art_root_io/TFileService.h"
14 #include "canvas/Persistency/Common/FindManyP.h"
15 #include "fhiclcpp/ParameterSet.h"
16 
25 
26 #include "TTree.h"
27 
28 constexpr int kMaxShowers = 1000; // maximum number of showers
29 
30 namespace shower {
31 
33  public:
34  explicit TCShowerAnalysis(fhicl::ParameterSet const& pset);
35 
36  private:
37  void beginJob() override;
38  void analyze(const art::Event& evt) override;
39 
40  void reset();
41 
42  void truthMatcher(detinfo::DetectorClocksData const& clockData,
44  std::vector<art::Ptr<recob::Hit>> shower_hits,
45  const simb::MCParticle*& MCparticle,
46  double& Efrac,
47  double& Ecomplet);
48 
49  TTree* fTree;
50  int run;
51  int subrun;
52  int event;
56  int nshws; // number of showers
57  int shwid[kMaxShowers]; // recob::Shower::ID()
58  float shwdcosx[kMaxShowers]; // shower direction cosin
61  float shwstartx[kMaxShowers]; // shower start position (cm)
64  double shwdedx[kMaxShowers][2]; // shower dE/dx of the initial track
65  // measured on the 3 plane (MeV/cm)
66  int shwbestplane[kMaxShowers]; // recommended plane for energy and dE/dx
67  // information
68 
71 
76 
78 
79  }; // class TCShowerAnalysis
80 
81 } // shower
82 
83 // -------------------------------------------------
84 
86  : EDAnalyzer(pset)
87  , fHitModuleLabel(pset.get<std::string>("HitModuleLabel", "trajcluster"))
88  , fShowerModuleLabel(pset.get<std::string>("ShowerModuleLabel", "tcshower"))
89  , fGenieGenModuleLabel(pset.get<std::string>("GenieGenModuleLabel", "generator"))
90  , fDigitModuleLabel(pset.get<std::string>("DigitModuleLabel", "largeant"))
91  , fCalorimetryAlg(pset.get<fhicl::ParameterSet>("CalorimetryAlg"))
92 {} // TCShowerTemplateMaker
93 
94 // -------------------------------------------------
95 
96 void
98 {
99 
101 
102  fTree = tfs->make<TTree>("tcshowerana", "tcshowerana");
103  fTree->Branch("run", &run, "run/I");
104  fTree->Branch("subrun", &subrun, "subrun/I");
105  fTree->Branch("event", &event, "event/I");
106 
107  fTree->Branch("nuPDG_truth", &nuPDG_truth, "nuPDG_truth/I");
108  fTree->Branch("ccnc_truth", &ccnc_truth, "ccnc_truth/I");
109  fTree->Branch("mode_truth", &mode_truth, "mode_truth/I");
110 
111  fTree->Branch("nshws", &nshws, "nshws/I");
112  fTree->Branch("shwid", shwid, "shwid[nshws]/I");
113  fTree->Branch("shwdcosx", shwdcosx, "shwdcosx[nshws]/F");
114  fTree->Branch("shwdcosy", shwdcosy, "shwdcosy[nshws]/F");
115  fTree->Branch("shwdcosz", shwdcosz, "shwdcosz[nshws]/F");
116  fTree->Branch("shwstartx", shwstartx, "shwstartx[nshws]/F");
117  fTree->Branch("shwstarty", shwstarty, "shwstarty[nshws]/F");
118  fTree->Branch("shwstartz", shwstartz, "shwstartz[nshws]/F");
119  fTree->Branch("shwdedx", shwdedx, "shwdedx[nshws][2]/D");
120  fTree->Branch("shwbestplane", shwbestplane, "shwbestplane[nshws]/I");
121 
122  fTree->Branch("highestHitsPDG", &highestHitsPDG, "highestHitsPDG/I");
123  fTree->Branch("highestHitsFrac", &highestHitsFrac, "highestHitsFrac/D");
124 
125 } // beginJob
126 
127 // -------------------------------------------------
128 
129 void
131 {
132 
133  run = evt.run();
134  subrun = evt.subRun();
135  event = evt.id().event();
136 
138  std::vector<art::Ptr<recob::Hit>> hitlist;
139  if (evt.getByLabel(fHitModuleLabel, hitListHandle)) art::fill_ptr_vector(hitlist, hitListHandle);
140 
142  std::vector<art::Ptr<sim::SimChannel>> simchanlist;
143  if (evt.getByLabel(fDigitModuleLabel, scListHandle))
144  art::fill_ptr_vector(simchanlist, scListHandle);
145 
146  art::Handle<std::vector<recob::Shower>> showerListHandle;
147  std::vector<art::Ptr<recob::Shower>> showerlist;
148  if (evt.getByLabel(fShowerModuleLabel, showerListHandle))
149  art::fill_ptr_vector(showerlist, showerListHandle);
150 
151  art::Handle<std::vector<simb::MCTruth>> mctruthListHandle;
152  std::vector<art::Ptr<simb::MCTruth>> mclist;
153  if (evt.getByLabel(fGenieGenModuleLabel, mctruthListHandle))
154  art::fill_ptr_vector(mclist, mctruthListHandle);
155 
156  art::FindManyP<recob::Hit> shwfm(showerListHandle, evt, fShowerModuleLabel);
157 
158  //shower information
159  if (showerListHandle.isValid()) {
160  nshws = showerlist.size();
161 
162  for (int i = 0; i < std::min(int(showerlist.size()), kMaxShowers); ++i) {
163  shwid[i] = showerlist[i]->ID();
164  shwdcosx[i] = showerlist[i]->Direction().X();
165  shwdcosy[i] = showerlist[i]->Direction().Y();
166  shwdcosz[i] = showerlist[i]->Direction().Z();
167  shwstartx[i] = showerlist[i]->ShowerStart().X();
168  shwstarty[i] = showerlist[i]->ShowerStart().Y();
169  shwstartz[i] = showerlist[i]->ShowerStart().Z();
170  for (size_t j = 0; j < (showerlist[i]->dEdx()).size(); ++j) {
171  shwdedx[i][j] = showerlist[i]->dEdx()[j];
172  }
173  shwbestplane[i] = showerlist[i]->best_plane();
174  }
175 
176  } // shower info
177 
178  auto const clockData = art::ServiceHandle<detinfo::DetectorClocksService const>()->DataFor(evt);
179 
180  if (mclist.size()) {
181  art::Ptr<simb::MCTruth> mctruth = mclist[0];
182  if (mctruth->NeutrinoSet()) {
183 
184  nuPDG_truth = mctruth->GetNeutrino().Nu().PdgCode();
185  ccnc_truth = mctruth->GetNeutrino().CCNC();
186  mode_truth = mctruth->GetNeutrino().Mode();
187 
188  if (showerlist.size()) { // only looks at the first shower since this is
189  // for tcshower
190  std::vector<art::Ptr<recob::Hit>> showerhits = shwfm.at(0);
191  // get shower truth info
192  const simb::MCParticle* particle;
193  double tmpEfrac = 0.0;
194  double tmpEcomplet = 0;
195  truthMatcher(clockData, hitlist, showerhits, particle, tmpEfrac, tmpEcomplet);
196  if (particle) {
197  std::cout << "shower pdg: " << particle->PdgCode() << " efrac " << tmpEfrac << std::endl;
198 
199  highestHitsPDG = particle->PdgCode();
200  highestHitsFrac = tmpEfrac;
201  }
202  }
203  }
204  }
205 
206  fTree->Fill();
207 
208 } // analyze
209 
210 // -------------------------------------------------
211 
212 void
214 {
215 
216  run = -99999;
217  subrun = -99999;
218  event = -99999;
219 
220  nuPDG_truth = -99999;
221  ccnc_truth = -99999;
222  mode_truth = -99999;
223 
224  nshws = 0;
225  for (int i = 0; i < kMaxShowers; ++i) {
226  shwid[i] = -99999;
227  shwdcosx[i] = -99999;
228  shwdcosy[i] = -99999;
229  shwdcosz[i] = -99999;
230  shwstartx[i] = -99999;
231  shwstarty[i] = -99999;
232  shwstartz[i] = -99999;
233  for (int j = 0; j < 2; ++j) {
234  shwdedx[i][j] = -99999;
235  }
236  shwbestplane[i] = -99999;
237  }
238 
239  highestHitsPDG = -99999;
240  highestHitsFrac = -99999;
241 
242 } // reset
243 
244 // -------------------------------------------------
245 
246 void
249  std::vector<art::Ptr<recob::Hit>> shower_hits,
250  const simb::MCParticle*& MCparticle,
251  double& Efrac,
252  double& Ecomplet)
253 {
254 
255  MCparticle = 0;
256  Efrac = 1.0;
257  Ecomplet = 0;
258 
261  std::map<int, double> trkID_E;
262  for (size_t j = 0; j < shower_hits.size(); ++j) {
263  art::Ptr<recob::Hit> hit = shower_hits[j];
264  // For know let's use collection plane to look at the shower reconstruction
265  if (hit->View() != 1) continue;
266  std::vector<sim::TrackIDE> TrackIDs = bt_serv->HitToEveTrackIDEs(clockData, hit);
267  for (size_t k = 0; k < TrackIDs.size(); k++) {
268  if (trkID_E.find(std::abs(TrackIDs[k].trackID)) == trkID_E.end())
269  trkID_E[std::abs(TrackIDs[k].trackID)] = 0;
270  trkID_E[std::abs(TrackIDs[k].trackID)] += TrackIDs[k].energy;
271  }
272  }
273  double max_E = -999.0;
274  double total_E = 0.0;
275  int TrackID = -999;
276  double partial_E = 0.0;
277 
278  if (!trkID_E.size()) return; // Ghost shower???
279  for (std::map<int, double>::iterator ii = trkID_E.begin(); ii != trkID_E.end(); ++ii) {
280  total_E += ii->second;
281  if ((ii->second) > max_E) {
282  partial_E = ii->second;
283  max_E = ii->second;
284  TrackID = ii->first;
285  }
286  }
287  MCparticle = pi_serv->TrackIdToParticle_P(TrackID);
288 
289  Efrac = partial_E / total_E;
290 
291  // completeness
292  double totenergy = 0;
293  for (size_t k = 0; k < all_hits.size(); ++k) {
294  art::Ptr<recob::Hit> hit = all_hits[k];
295  std::vector<sim::TrackIDE> TrackIDs = bt_serv->HitToEveTrackIDEs(clockData, hit);
296  for (size_t l = 0; l < TrackIDs.size(); ++l) {
297  if (std::abs(TrackIDs[l].trackID) == TrackID) { totenergy += TrackIDs[l].energy; }
298  }
299  }
300  Ecomplet = partial_E / totenergy;
301 
302 } // truthMatcher
303 
intermediate_table::iterator iterator
int PdgCode() const
Definition: MCParticle.h:212
int CCNC() const
Definition: MCNeutrino.h:148
double shwdedx[kMaxShowers][2]
const simb::MCNeutrino & GetNeutrino() const
Definition: MCTruth.h:77
TCShowerAnalysis(fhicl::ParameterSet const &pset)
std::string string
Definition: nybbler.cc:12
std::vector< TrackID > TrackIDs
const simb::MCParticle * TrackIdToParticle_P(int id) const
void truthMatcher(detinfo::DetectorClocksData const &clockData, std::vector< art::Ptr< recob::Hit >> all_hits, std::vector< art::Ptr< recob::Hit >> shower_hits, const simb::MCParticle *&MCparticle, double &Efrac, double &Ecomplet)
const simb::MCParticle & Nu() const
Definition: MCNeutrino.h:146
struct vector vector
STL namespace.
calo::CalorimetryAlg fCalorimetryAlg
geo::View_t View() const
View for the plane of the hit.
Definition: Hit.h:232
EDAnalyzer(fhicl::ParameterSet const &pset)
Definition: EDAnalyzer.h:25
static QStrList * l
Definition: config.cpp:1044
bool isValid() const noexcept
Definition: Handle.h:191
decltype(auto) constexpr size(T &&obj)
ADL-aware version of std::size.
Definition: StdUtils.h:92
T abs(T value)
bool getByLabel(std::string const &label, std::string const &instance, Handle< PROD > &result) const
Definition: DataViewImpl.h:633
#define DEFINE_ART_MODULE(klass)
Definition: ModuleMacros.h:67
constexpr int kMaxShowers
SubRunNumber_t subRun() const
Definition: DataViewImpl.cc:78
RunNumber_t run() const
Definition: DataViewImpl.cc:71
Detector simulation of raw signals on wires.
Declaration of signal hit object.
T min(sqlite3 *const db, std::string const &table_name, std::string const &column_name)
Definition: statistics.h:55
void analyze(const art::Event &evt) override
Contains all timing reference information for the detector.
std::vector< sim::TrackIDE > HitToEveTrackIDEs(detinfo::DetectorClocksData const &clockData, recob::Hit const &hit) const
EventNumber_t event() const
Definition: EventID.h:116
bool NeutrinoSet() const
Definition: MCTruth.h:78
TCEvent evt
Definition: DataStructs.cxx:7
auto const & get(AssnsNode< L, R, D > const &r)
Definition: AssnsNode.h:115
void fill_ptr_vector(std::vector< Ptr< T >> &ptrs, H const &h)
Definition: Ptr.h:297
int Mode() const
Definition: MCNeutrino.h:149
EventID id() const
Definition: Event.cc:34
QTextStream & endl(QTextStream &s)
Event finding and building.