LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
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
14 #include "art_root_io/TFileService.h"
16 #include "fhiclcpp/ParameterSet.h"
17 
26 
27 #include "TTree.h"
28 
29 constexpr int kMaxShowers = 1000; // maximum number of showers
30 
31 namespace shower {
32 
34  public:
35  explicit TCShowerAnalysis(fhicl::ParameterSet const& pset);
36 
37  private:
38  void beginJob() override;
39  void analyze(const art::Event& evt) override;
40 
41  void reset();
42 
43  void truthMatcher(detinfo::DetectorClocksData const& clockData,
45  std::vector<art::Ptr<recob::Hit>> shower_hits,
46  const simb::MCParticle*& MCparticle,
47  double& Efrac,
48  double& Ecomplet);
49 
50  TTree* fTree;
51  int run;
52  int subrun;
53  int event;
57  int nshws; // number of showers
58  int shwid[kMaxShowers]; // recob::Shower::ID()
59  float shwdcosx[kMaxShowers]; // shower direction cosin
62  float shwstartx[kMaxShowers]; // shower start position (cm)
65  double shwdedx[kMaxShowers][2]; // shower dE/dx of the initial track
66  // measured on the 3 plane (MeV/cm)
67  int shwbestplane[kMaxShowers]; // recommended plane for energy and dE/dx
68  // information
69 
72 
73  std::string fHitModuleLabel;
74  std::string fShowerModuleLabel;
75  std::string fGenieGenModuleLabel;
76  std::string fDigitModuleLabel;
77 
79 
80  }; // class TCShowerAnalysis
81 
82 } // shower
83 
84 // -------------------------------------------------
85 
87  : EDAnalyzer(pset)
88  , fHitModuleLabel(pset.get<std::string>("HitModuleLabel", "trajcluster"))
89  , fShowerModuleLabel(pset.get<std::string>("ShowerModuleLabel", "tcshower"))
90  , fGenieGenModuleLabel(pset.get<std::string>("GenieGenModuleLabel", "generator"))
91  , fDigitModuleLabel(pset.get<std::string>("DigitModuleLabel", "largeant"))
92  , fCalorimetryAlg(pset.get<fhicl::ParameterSet>("CalorimetryAlg"))
93 {} // TCShowerTemplateMaker
94 
95 // -------------------------------------------------
96 
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 
130 {
131 
132  run = evt.run();
133  subrun = evt.subRun();
134  event = evt.id().event();
135 
137  std::vector<art::Ptr<recob::Hit>> hitlist;
138  if (evt.getByLabel(fHitModuleLabel, hitListHandle)) art::fill_ptr_vector(hitlist, hitListHandle);
139 
141  std::vector<art::Ptr<sim::SimChannel>> simchanlist;
142  if (evt.getByLabel(fDigitModuleLabel, scListHandle))
143  art::fill_ptr_vector(simchanlist, scListHandle);
144 
145  art::Handle<std::vector<recob::Shower>> showerListHandle;
146  std::vector<art::Ptr<recob::Shower>> showerlist;
147  if (evt.getByLabel(fShowerModuleLabel, showerListHandle))
148  art::fill_ptr_vector(showerlist, showerListHandle);
149 
150  art::Handle<std::vector<simb::MCTruth>> mctruthListHandle;
151  std::vector<art::Ptr<simb::MCTruth>> mclist;
152  if (evt.getByLabel(fGenieGenModuleLabel, mctruthListHandle))
153  art::fill_ptr_vector(mclist, mctruthListHandle);
154 
155  art::FindManyP<recob::Hit> shwfm(showerListHandle, evt, fShowerModuleLabel);
156 
157  //shower information
158  if (showerListHandle.isValid()) {
159  nshws = showerlist.size();
160 
161  for (int i = 0; i < std::min(int(showerlist.size()), kMaxShowers); ++i) {
162  shwid[i] = showerlist[i]->ID();
163  shwdcosx[i] = showerlist[i]->Direction().X();
164  shwdcosy[i] = showerlist[i]->Direction().Y();
165  shwdcosz[i] = showerlist[i]->Direction().Z();
166  shwstartx[i] = showerlist[i]->ShowerStart().X();
167  shwstarty[i] = showerlist[i]->ShowerStart().Y();
168  shwstartz[i] = showerlist[i]->ShowerStart().Z();
169  for (size_t j = 0; j < (showerlist[i]->dEdx()).size(); ++j) {
170  shwdedx[i][j] = showerlist[i]->dEdx()[j];
171  }
172  shwbestplane[i] = showerlist[i]->best_plane();
173  }
174 
175  } // shower info
176 
177  auto const clockData = art::ServiceHandle<detinfo::DetectorClocksService const>()->DataFor(evt);
178 
179  if (mclist.size()) {
180  art::Ptr<simb::MCTruth> mctruth = mclist[0];
181  if (mctruth->NeutrinoSet()) {
182 
183  nuPDG_truth = mctruth->GetNeutrino().Nu().PdgCode();
184  ccnc_truth = mctruth->GetNeutrino().CCNC();
185  mode_truth = mctruth->GetNeutrino().Mode();
186 
187  if (showerlist.size()) { // only looks at the first shower since this is
188  // for tcshower
189  std::vector<art::Ptr<recob::Hit>> showerhits = shwfm.at(0);
190  // get shower truth info
191  const simb::MCParticle* particle;
192  double tmpEfrac = 0.0;
193  double tmpEcomplet = 0;
194  truthMatcher(clockData, hitlist, showerhits, particle, tmpEfrac, tmpEcomplet);
195  if (particle) {
196  std::cout << "shower pdg: " << particle->PdgCode() << " efrac " << tmpEfrac << std::endl;
197 
198  highestHitsPDG = particle->PdgCode();
199  highestHitsFrac = tmpEfrac;
200  }
201  }
202  }
203  }
204 
205  fTree->Fill();
206 
207 } // analyze
208 
209 // -------------------------------------------------
210 
212 {
213 
214  run = -99999;
215  subrun = -99999;
216  event = -99999;
217 
218  nuPDG_truth = -99999;
219  ccnc_truth = -99999;
220  mode_truth = -99999;
221 
222  nshws = 0;
223  for (int i = 0; i < kMaxShowers; ++i) {
224  shwid[i] = -99999;
225  shwdcosx[i] = -99999;
226  shwdcosy[i] = -99999;
227  shwdcosz[i] = -99999;
228  shwstartx[i] = -99999;
229  shwstarty[i] = -99999;
230  shwstartz[i] = -99999;
231  for (int j = 0; j < 2; ++j) {
232  shwdedx[i][j] = -99999;
233  }
234  shwbestplane[i] = -99999;
235  }
236 
237  highestHitsPDG = -99999;
238  highestHitsFrac = -99999;
239 
240 } // reset
241 
242 // -------------------------------------------------
243 
246  std::vector<art::Ptr<recob::Hit>> shower_hits,
247  const simb::MCParticle*& MCparticle,
248  double& Efrac,
249  double& Ecomplet)
250 {
251 
252  MCparticle = 0;
253  Efrac = 1.0;
254  Ecomplet = 0;
255 
258  std::map<int, double> trkID_E;
259  for (size_t j = 0; j < shower_hits.size(); ++j) {
260  art::Ptr<recob::Hit> hit = shower_hits[j];
261  // For know let's use collection plane to look at the shower reconstruction
262  if (hit->View() != 1) continue;
263  std::vector<sim::TrackIDE> TrackIDs = bt_serv->HitToEveTrackIDEs(clockData, hit);
264  for (size_t k = 0; k < TrackIDs.size(); k++) {
265  if (trkID_E.find(std::abs(TrackIDs[k].trackID)) == trkID_E.end())
266  trkID_E[std::abs(TrackIDs[k].trackID)] = 0;
267  trkID_E[std::abs(TrackIDs[k].trackID)] += TrackIDs[k].energy;
268  }
269  }
270  double max_E = -999.0;
271  double total_E = 0.0;
272  int TrackID = -999;
273  double partial_E = 0.0;
274 
275  if (!trkID_E.size()) return; // Ghost shower???
276  for (std::map<int, double>::iterator ii = trkID_E.begin(); ii != trkID_E.end(); ++ii) {
277  total_E += ii->second;
278  if ((ii->second) > max_E) {
279  partial_E = ii->second;
280  max_E = ii->second;
281  TrackID = ii->first;
282  }
283  }
284  MCparticle = pi_serv->TrackIdToParticle_P(TrackID);
285 
286  Efrac = partial_E / total_E;
287 
288  // completeness
289  double totenergy = 0;
290  for (size_t k = 0; k < all_hits.size(); ++k) {
291  art::Ptr<recob::Hit> hit = all_hits[k];
292  std::vector<sim::TrackIDE> TrackIDs = bt_serv->HitToEveTrackIDEs(clockData, hit);
293  for (size_t l = 0; l < TrackIDs.size(); ++l) {
294  if (std::abs(TrackIDs[l].trackID) == TrackID) { totenergy += TrackIDs[l].energy; }
295  }
296  }
297  Ecomplet = partial_E / totenergy;
298 
299 } // truthMatcher
300 
intermediate_table::iterator iterator
SubRunNumber_t subRun() const
Definition: Event.cc:35
int PdgCode() const
Definition: MCParticle.h:213
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::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)
Declaration of signal hit object.
const simb::MCParticle & Nu() const
Definition: MCNeutrino.h:146
constexpr auto abs(T v)
Returns the absolute value of the argument.
STL namespace.
calo::CalorimetryAlg fCalorimetryAlg
geo::View_t View() const
View for the plane of the hit.
Definition: Hit.h:276
EDAnalyzer(fhicl::ParameterSet const &pset)
Definition: EDAnalyzer.cc:6
bool isValid() const noexcept
Definition: Handle.h:203
decltype(auto) constexpr size(T &&obj)
ADL-aware version of std::size.
Definition: StdUtils.h:101
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
Definition: DumpUtils.h:289
#define DEFINE_ART_MODULE(klass)
Definition: ModuleMacros.h:65
parameter set interface
constexpr int kMaxShowers
Detector simulation of raw signals on wires.
decltype(auto) get(T &&obj)
ADL-aware version of std::to_string.
Definition: StdUtils.h:120
bool getByLabel(std::string const &label, std::string const &instance, Handle< PROD > &result) const
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
object containing MC truth information necessary for making RawDigits and doing back tracking ...
EventNumber_t event() const
Definition: EventID.h:116
bool NeutrinoSet() const
Definition: MCTruth.h:78
TCEvent evt
Definition: DataStructs.cxx:8
void fill_ptr_vector(std::vector< Ptr< T >> &ptrs, H const &h)
Definition: Ptr.h:306
RunNumber_t run() const
Definition: Event.cc:29
int Mode() const
Definition: MCNeutrino.h:149
EventID id() const
Definition: Event.cc:23
Event finding and building.