-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSimShowerEnergyDepositExample_module.cc
444 lines (346 loc) · 15.1 KB
/
SimShowerEnergyDepositExample_module.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
//////////////////////////////////////////////////////////////
// Name: SimShowerEnergyDepositExample
// Date: 15 October 2018
// Author: Everybody is an author!
//////////////////////////////////////////////////////////////
#ifndef SimShowerEnergyDepositExample_Module
#define SimShowerEnergyDepositExample_Module
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-variable"
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-but-set-parameter"
// Framework includes
#include "art/Framework/Core/EDAnalyzer.h"
#include "art/Framework/Core/ModuleMacros.h"
#include "art/Framework/Principal/Event.h"
#include "art/Framework/Principal/Handle.h"
#include "art/Framework/Principal/Run.h"
#include "art/Framework/Principal/SubRun.h"
#include "art/Framework/Services/Registry/ServiceHandle.h"
#include "art/Framework/Services/Optional/TFileService.h"
#include "canvas/Persistency/Common/Ptr.h"
//#include "canvas/Persistency/Common/PtrVector.h"
#include "canvas/Utilities/Exception.h"
#include "fhiclcpp/ParameterSet.h"
#include "messagefacility/MessageLogger/MessageLogger.h"
// NuTools includes
#include "nusimdata/SimulationBase/MCParticle.h"
//#include "nusimdata/SimulationBase/MCTrajectory.h"
// LArSoft includes
#include "larcore/Geometry/Geometry.h"
#include "larcorealg/Geometry/GeometryCore.h"
#include "larcoreobj/SimpleTypesAndConstants/geo_types.h"
//#include "lardata/DetectorInfoServices/DetectorPropertiesService.h"
#include "lardataobj/MCBase/MCShower.h"
#include "lardataobj/Simulation/sim.h"
#include "lardataobj/Simulation/SimChannel.h"
//#include "larsim/MCCheater/BackTrackerService.h"
//#include "larsim/Simulation/LArG4Parameters.h"
// ROOT includes
#include "TTree.h"
// C++ includes
#include <map>
#include <set>
#include <string>
#include <vector>
// type definition of particle maps
typedef std::map< int, art::Ptr< simb::MCParticle > > ParticleMap;
typedef std::map< int, ParticleMap > ShowerParticleMaps;
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// class definition
class SimShowerEnergyDepositExample : public art::EDAnalyzer
{
public:
// standard constructor and destructor for an art module
explicit SimShowerEnergyDepositExample(fhicl::ParameterSet const& pset);
virtual ~SimShowerEnergyDepositExample();
// this method is called once, at the start of the job
virtual void beginJob() override;
// this method is called once, at the start of each run
virtual void beginRun(const art::Run & run) override;
// this method is called once, at the start of each subrun
virtual void beginSubRun(const art::SubRun & subrun) override;
// this method is called once, at the end of the job
virtual void endJob() override;
// this method is called once, at the end of each run
virtual void endRun(const art::Run & run) override;
// this method is called once, at the end of each subrun
virtual void endSubRun(const art::SubRun & subrun) override;
// this method reads in any parameters from the .fcl files
void reconfigure(fhicl::ParameterSet const& pset) override;
// the analyze routine, called once per event
void analyze(art::Event const & event) override;
private:
// parameters read from FHiCL (.fcl) file
std::string simulation_producer_label_;
std::string mcshower_producer_label_;
// pointer to geometry provider
geo::GeometryCore const* geometry_;
// pointer to detector properties
//detinfo::DetectorProperties const* detector_;
// reset once per event
void reset_();
// get particle map
ParticleMap particle_map_(
std::vector< art::Ptr< simb::MCParticle > > const& particle_vector);
// get shower particle maps
ShowerParticleMaps shower_particle_maps_(
ParticleMap const& particle_map,
std::vector< art::Ptr< sim::MCShower > > const& mcshower_vector);
// fill shower particle map
void fill_shower_particle_map_(
int const track_id,
ParticleMap const& particle_map,
ParticleMap & shower_particle_map);
// get energy deposited
double sim_energy_deposited_(
std::set< int > const& track_ids,
std::vector< art::Ptr< sim::SimChannel > > const& simchannel_vector);
// pointers to TTree object
TTree * ttree_;
// variables that will go into the TTree objects
int event_; // number of the event being processed
int run_; // number of the run being processed
int subrun_; // number of the sub-run being processed
};
//-----------------------------------------------------------------------
// constructor
SimShowerEnergyDepositExample::SimShowerEnergyDepositExample(fhicl::ParameterSet const& pset)
:
EDAnalyzer(pset)
{
// reconfigure parameters
this->reconfigure(pset);
// get a pointer to the geometry service provider
geometry_ = &*(art::ServiceHandle<geo::Geometry>());
// get a pointer to the detector properties provider
//detector_ = lar::providerFrom<detinfo::DetectorPropertiesService>();
}
//-----------------------------------------------------------------------
// destructor
SimShowerEnergyDepositExample::~SimShowerEnergyDepositExample() {}
//-----------------------------------------------------------------------
void SimShowerEnergyDepositExample::beginJob()
{
// access art's TFileService
art::ServiceHandle< art::TFileService > tfs;
ttree_ = tfs->make<TTree>("simshowerenergydepositexample", "simshowerenergydepositexample");
ttree_->Branch("event", &event_, "event/I");
ttree_->Branch("run", &run_, "run/I");
ttree_->Branch("subrun", &subrun_, "subrun/I");
}
//-----------------------------------------------------------------------
void SimShowerEnergyDepositExample::beginRun(const art::Run & /*run*/)
{}
//-----------------------------------------------------------------------
void SimShowerEnergyDepositExample::beginSubRun(const art::SubRun & /*subrun*/)
{}
//-----------------------------------------------------------------------
void SimShowerEnergyDepositExample::endJob()
{}
//-----------------------------------------------------------------------
void SimShowerEnergyDepositExample::endRun(const art::Run & /*run*/)
{}
//-----------------------------------------------------------------------
void SimShowerEnergyDepositExample::endSubRun(const art::SubRun & /*subrun*/)
{}
//-----------------------------------------------------------------------
void SimShowerEnergyDepositExample::reconfigure(fhicl::ParameterSet const& pset)
{
// read parameters from the .fcl file
simulation_producer_label_ = pset.get< std::string >("SimulationLabel", "largeant");
mcshower_producer_label_ = pset.get< std::string >("MCShowerLabel", "mcreco");
}
//-----------------------------------------------------------------------
void SimShowerEnergyDepositExample::analyze(art::Event const & event)
{
//-------------------------------------------------------------------
// reset once per event
//-------------------------------------------------------------------
//this->reset_();
//-------------------------------------------------------------------
// get event, run, and subrun numbers
//-------------------------------------------------------------------
event_ = event.id().event();
run_ = event.run();
subrun_ = event.subRun();
//-------------------------------------------------------------------
// get data products
//-------------------------------------------------------------------
// get art::ValidHandle< std::vector< sim::SimChannel > >
auto simchannel_handle = event.getValidHandle< std::vector< sim::SimChannel > >
(simulation_producer_label_);
// fill vector of SimChannel objects
std::vector< art::Ptr< sim::SimChannel > > simchannel_vector;
art::fill_ptr_vector(simchannel_vector, simchannel_handle);
// get art::ValidHandle< std::vector< simb::MCParticle > >
auto particle_handle = event.getValidHandle< std::vector< simb::MCParticle > >
(simulation_producer_label_);
// fill vector of MCParticle objects
std::vector< art::Ptr< simb::MCParticle > > particle_vector;
art::fill_ptr_vector(particle_vector, particle_handle);
// get art::ValidHandle< std::vector< sim::MCShower > >
auto mcshower_handle = event.getValidHandle< std::vector< sim::MCShower > >
(mcshower_producer_label_);
// fill vector of MCShower objects
std::vector< art::Ptr< sim::MCShower > > mcshower_vector;
art::fill_ptr_vector(mcshower_vector, mcshower_handle);
//-------------------------------------------------------------------
// fill particle maps
//-------------------------------------------------------------------
// ParticleMap
auto const particle_map = this->particle_map_(particle_vector);
// ShowerParticleMaps
auto const shower_particle_maps = this->shower_particle_maps_(
particle_map, mcshower_vector);
//-------------------------------------------------------------------
// get energy deposited by shower particles
//-------------------------------------------------------------------
// loop over map of particle maps
for (auto const& shower_particle_maps_iter : shower_particle_maps)
{
// get ancestor shower particle track ID
int const ancestor_track_id = shower_particle_maps_iter.first;
// get ancestor shower particle
// art::Ptr< simb::MCParticle > const ancestor_particle
// = particle_map.at(ancestor_track_id);
// set of track IDs of descendent particles
std::set< int > descendent_track_ids;
// loop over particle maps for descendent particles
for (auto const& particle_map_iter : shower_particle_maps_iter.second)
{
// get track ID of descendent particle
int const descendent_track_id = particle_map_iter.first;
// insert into set of descendent track IDs
descendent_track_ids.insert(descendent_track_id);
} // end loop over particle maps
//-------------------------------------------------------
// this is where you can do something with the total
// visible energy deposited on the TPC wires by the
// electromagnetic shower
//-------------------------------------------------------
// get total visible energy deposited by all descendent particles
double const energy_deposited
= this->sim_energy_deposited_(descendent_track_ids, simchannel_vector);
} // end loop over map of particle maps
//-------------------------------------------------------------------
// fill TTree object
//-------------------------------------------------------------------
ttree_->Fill();
}
//-----------------------------------------------------------------------
void SimShowerEnergyDepositExample::reset_()
{}
//-----------------------------------------------------------------------
ParticleMap SimShowerEnergyDepositExample::particle_map_(
std::vector< art::Ptr< simb::MCParticle > > const& particle_vector)
{
// initialize particle map
ParticleMap particle_map;
// loop over simb::MCParticle objects and fill particle map
for (auto const& particle : particle_vector)
{
// add the address of the MCParticle to the map, with the
// track ID as the key
particle_map[particle->TrackId()] = particle;
} // end loop over simb::MCParticle objects
return particle_map;
}
//-----------------------------------------------------------------------
ShowerParticleMaps SimShowerEnergyDepositExample::shower_particle_maps_(
ParticleMap const& particle_map,
std::vector< art::Ptr< sim::MCShower > > const& mcshower_vector)
{
// initialize shower particle maps
ShowerParticleMaps shower_particle_maps;
// loop over MCShower objects
for (auto const& mcshower : mcshower_vector)
{
// get track ID and particle
int const track_id = mcshower->TrackID();
auto const& particle = particle_map.at(track_id);
// fill shower particle maps
this->fill_shower_particle_map_(
particle->TrackId(), particle_map,
shower_particle_maps[particle->TrackId()]);
} // end loop over MCShower objects
return shower_particle_maps;
}
//-----------------------------------------------------------------------
void SimShowerEnergyDepositExample::fill_shower_particle_map_(
int const track_id,
ParticleMap const& particle_map,
ParticleMap & shower_particle_map)
{
// create iterator for particle map
ParticleMap::const_iterator particle_iter = particle_map.find(track_id);
// return if the end of the particle map is reached
if (particle_iter == particle_map.end()) return;
// pointer to MCParticle object
art::Ptr< simb::MCParticle > particle = (*particle_iter).second;
// get number of daughters of particle
int number_daughters = particle->NumberDaughters();
// add pointer of MCParticle object to the shower particle map
shower_particle_map[track_id] = particle;
// loop over daughter particles and recur
for (int idx = 0; idx < number_daughters; ++idx)
{
// get daughter track ID
int daughter_track_id = particle->Daughter(idx);
// recur
this->fill_shower_particle_map_(
daughter_track_id, particle_map, shower_particle_map);
} // end loop over daughter particles
}
//-----------------------------------------------------------------------
double SimShowerEnergyDepositExample::sim_energy_deposited_(
std::set< int > const& track_ids,
std::vector< art::Ptr< sim::SimChannel > > const& simchannel_vector)
{
double energy_deposited = 0;
// look at all the energy deposited on the TPC wires
// sim::SimChannel
for (auto const& channel : simchannel_vector)
{
// get the numeric ID associated with this channel
// raw::ChannelID_t
auto channel_number = channel->Channel();
// only look at the energy on the collection plane
if (geometry_->SignalType(channel_number) != geo::kCollection)
continue;
// each channel has a map inside it that connects
// a time slice to energy deposits in the detector
// std::map< unsigned short, std::vector< sim::IDE > >
auto const& time_slices = channel->TDCIDEMap();
// for every time slice in this channel:
for (auto const& time_slice : time_slices)
{
// get energy deposits from time slice
// std::vector< sim::IDE >
auto const& energy_deposits = time_slice.second;
// loop through energy deposits
// sim::IDE
for (auto const& energy_deposit : energy_deposits)
{
if (track_ids.find(energy_deposit.trackID) != track_ids.end() and
energy_deposit.trackID != sim::NoParticleId)
{
// add to energy deposited on TPC wires
energy_deposited += energy_deposit.energy;
} // if energy deposited by particle
} // for each energy deposit
} // for each time slice
} // for each SimChannel
return energy_deposited;
}
DEFINE_ART_MODULE(SimShowerEnergyDepositExample)
#pragma GCC diagnostic pop
#pragma GCC diagnostic pop
#pragma GCC diagnostic pop
#pragma GCC diagnostic pop
#endif // SimShowerEnergyDepositExample_module