LArSoft  v10_04_05
Liquid Argon Software toolkit - https://larsoft.org/
MCRecoEdep.cxx
Go to the documentation of this file.
1 //
3 // MCRecoEdep source
4 //
6 
10 
16 
17 #include "MCRecoEdep.h"
18 
19 #include <iostream>
20 #include <map>
21 #include <utility>
22 #include <vector>
23 
24 namespace sim {
25 
26  namespace details {
27  std::map<geo::PlaneID, size_t> createPlaneIndexMap()
28  {
29  auto const& wireReadoutGeom = art::ServiceHandle<geo::WireReadout const>()->Get();
30  std::map<geo::PlaneID, size_t> m;
31  size_t i = 0;
32  for (auto const& pid : wireReadoutGeom.Iterate<geo::PlaneID>()) {
33  m[pid] = i;
34  i++;
35  }
36  return m;
37  }
38  }
39 
40  //##################################################################
42  //##################################################################
43  {
44  _debug_mode = pset.get<bool>("DebugMode");
45  _save_mchit = pset.get<bool>("SaveMCHit");
46  }
47 
48  const std::vector<sim::MCEdep>& MCRecoEdep::GetEdepArrayAt(size_t edep_index) const
49  {
50  if (edep_index >= _mc_edeps.size())
51  throw cet::exception(__FUNCTION__) << Form("Track ID %zu not found!", edep_index);
52  return _mc_edeps.at(edep_index);
53  }
54 
55  std::vector<sim::MCEdep>& MCRecoEdep::__GetEdepArray__(unsigned int track_id)
56  {
57  if (ExistTrack(track_id)) return _mc_edeps.at((*_track_index.find(track_id)).second);
58  _track_index.insert(std::pair<unsigned int, size_t>(track_id, _mc_edeps.size()));
59  _mc_edeps.push_back(std::vector<sim::MCEdep>());
60  return (*(_mc_edeps.rbegin()));
61  }
62 
63  void MCRecoEdep::MakeMCEdep(const std::vector<sim::SimChannel>& schArray)
64  {
65  _mc_edeps.clear();
66  _track_index.clear();
67 
68  auto const& wireReadoutGeom = art::ServiceHandle<geo::WireReadout const>()->Get();
69 
70  // Key map to identify a unique particle energy deposition point
71  std::map<std::pair<UniquePosition, unsigned int>, int> hit_index_m;
72 
73  auto pindex = details::createPlaneIndexMap();
74 
75  if (_debug_mode) std::cout << "Processing " << schArray.size() << " channels..." << std::endl;
76  // Loop over channels
77  for (size_t i = 0; i < schArray.size(); ++i) {
78 
79  // Get data to loop over
80  auto const& sch = schArray[i];
81  const auto& sch_map(sch.TDCIDEMap());
82  // Channel
83  UInt_t ch = sch.Channel();
84  // Loop over ticks
85  for (auto tdc_iter = sch_map.begin(); tdc_iter != sch_map.end(); ++tdc_iter) {
86  // Loop over IDEs
87  for (auto const& ide : (*tdc_iter).second) {
88 
89  int track_id = ide.trackID;
90  if (track_id < 0) track_id = track_id * (-1);
91  unsigned int real_track_id = track_id;
92 
93  UniquePosition pos(ide.x, ide.y, ide.z);
94 
95  int hit_index = -1;
96  auto key = std::make_pair(pos, real_track_id);
97  auto hit_index_track_iter = hit_index_m.find(key);
98  if (hit_index_track_iter == hit_index_m.end()) {
99  int new_hit_index = __GetEdepArray__(real_track_id).size();
100  hit_index_m[key] = new_hit_index;
101  }
102  else {
103  hit_index = (*hit_index_track_iter).second;
104  }
105  auto const pid = wireReadoutGeom.ChannelToWire(ch)[0].planeID();
106  auto const channel_id = pindex[pid];
107  double charge = ide.numElectrons;
108  if (hit_index < 0) {
109  // This particle energy deposition is never recorded so far. Create a new Edep
110  __GetEdepArray__(real_track_id)
111  .emplace_back(pos, pid, pindex.size(), ide.energy, charge, channel_id);
112  }
113  else {
114  // Append charge to the relevant edep (@ hit_index)
115  MCEdep& edep = __GetEdepArray__(real_track_id).at(hit_index);
116  edep.deps[channel_id].charge += charge;
117  edep.deps[channel_id].energy += ide.energy;
118  }
119  } // end looping over ides in this tick
120  } // end looping over ticks in this channel
121  } // end looping over channels
122 
123  if (_debug_mode) {
124  std::cout << Form(" Collected %zu particles' energy depositions...", _mc_edeps.size())
125  << std::endl;
126  }
127  }
128 
129  void MCRecoEdep::MakeMCEdep(const std::vector<sim::SimEnergyDeposit>& sedArray)
130  {
131  _mc_edeps.clear();
132  _track_index.clear();
133 
134  auto const& wireReadoutGeom = art::ServiceHandle<geo::WireReadout const>()->Get();
136 
137  // Key map to identify a unique particle energy deposition point
138  std::map<std::pair<UniquePosition, unsigned int>, int> hit_index_m;
139 
140  auto pindex = details::createPlaneIndexMap();
141 
142  if (_debug_mode)
143  std::cout << "Processing " << sedArray.size() << " energy deposits..." << std::endl;
144  // Loop over channels
145  for (size_t i = 0; i < sedArray.size(); ++i) {
146 
147  // Get data to loop over
148  auto const& sed = sedArray[i];
149 
150  // David Caratelli: much of the code below is taken from the module:
151  // https://cdcvs.fnal.gov/redmine/projects/larsim/repository/revisions/develop/entry/larsim/ElectronDrift/SimDriftElectrons_module.cc
152 
153  // given this SimEnergyDeposit, find the TPC channel information "xyz" is the
154  // position of the energy deposit in world coordinates. Note that the units of
155  // distance in sim::SimEnergyDeposit are supposed to be cm.
156  auto const mp = sed.MidPoint();
157  // From the position in world coordinates, determine the cryostat and tpc. If
158  // somehow the step is outside a tpc (e.g., cosmic rays in rock) just move on to the
159  // next one.
160  unsigned int cryostat = 0;
161  try {
162  geom->PositionToCryostatID(mp);
163  }
164  catch (cet::exception& e) {
165  mf::LogWarning("SimDriftElectrons") << "step " // << energyDeposit << "\n"
166  << "cannot be found in a cryostat\n"
167  << e;
168  continue;
169  }
170  unsigned int tpc = 0;
171  try {
172  geom->PositionToTPCID(mp);
173  }
174  catch (cet::exception& e) {
175  mf::LogWarning("SimDriftElectrons") << "step " // << energyDeposit << "\n"
176  << "cannot be found in a TPC\n"
177  << e;
178  continue;
179  }
180  geo::TPCID const tpcid{cryostat, tpc};
181 
182  // Define charge drift direction: driftcoordinate (x, y or z) and driftsign
183  // (positive or negative). Also define coordinates perpendicular to drift direction.
184 
185  // make a collection of electrons for each plane
186  for (auto const& planeid : wireReadoutGeom.Iterate<geo::PlaneID>()) {
187 
188  // grab the nearest channel to the fDriftClusterPos position
189  // David Caratelli, comment begin:
190  // NOTE: the below code works only when the drift coordinate is indeed in x (i.e. 0th coordinate)
191  // see code linked above for a much more careful treatment of the coordinate system
192  // David Caratelli, comment end.
193  raw::ChannelID_t ch;
194  try {
195  ch = wireReadoutGeom.NearestChannel(mp, planeid);
196  }
197  catch (cet::exception& e) {
198  mf::LogWarning("SimDriftElectrons") << "step " // << energyDeposit << "\n"
199  << "nearest wire not in TPC\n"
200  << e;
201  continue;
202  }
203 
204  int track_id = sed.TrackID();
205 
206  if (track_id < 0) track_id = track_id * (-1);
207  unsigned int real_track_id = track_id;
208 
209  UniquePosition pos(mp.X(), mp.Y(), mp.Z());
210 
211  int hit_index = -1;
212  auto key = std::make_pair(pos, real_track_id);
213  auto hit_index_track_iter = hit_index_m.find(key);
214  if (hit_index_track_iter == hit_index_m.end()) {
215  int new_hit_index = __GetEdepArray__(real_track_id).size();
216  hit_index_m[key] = new_hit_index;
217  }
218  else {
219  hit_index = (*hit_index_track_iter).second;
220  }
221  auto const pid = wireReadoutGeom.ChannelToWire(ch)[0].planeID();
222  auto const channel_id = pindex[pid];
223  double charge = sed.NumElectrons();
224  if (hit_index < 0) {
225  // This particle energy deposition is never recorded so far. Create a new Edep
226  __GetEdepArray__(real_track_id)
227  .emplace_back(pos, pid, pindex.size(), sed.Energy(), charge, channel_id);
228  }
229  else {
230  // Append charge to the relevant edep (@ hit_index)
231  MCEdep& edep = __GetEdepArray__(real_track_id).at(hit_index);
232  edep.deps[channel_id].charge += charge;
233  edep.deps[channel_id].energy += sed.Energy();
234  }
235  } // end looping over planes
236  } // end looping over SimEnergyDeposits
237 
238  if (_debug_mode) {
239  std::cout << Form(" Collected %zu particles' energy depositions...", _mc_edeps.size())
240  << std::endl;
241  }
242  }
243 
244  void MCRecoEdep::MakeMCEdep(const std::vector<sim::SimEnergyDepositLite>& sedArray)
245  {
246  // Create a substitute array of sim::SimEnergyDeposit to avoid duplicating code...
247  // Note that this makes use of the explicit conversion operator defined in
248  // SimEnergyDepositLite class. Information will be partial. Most notably for
249  // MakeMCEdep, charge (numElectrons) will be 0.
250  std::vector<sim::SimEnergyDeposit> new_sedArray(sedArray.begin(), sedArray.end());
251  MakeMCEdep(new_sedArray);
252  }
253 
254 }
void MakeMCEdep(const std::vector< sim::SimChannel > &schArray)
Definition: MCRecoEdep.cxx:63
The data type to uniquely identify a Plane.
Definition: geo_types.h:364
std::map< geo::PlaneID, size_t > createPlaneIndexMap()
Definition: MCRecoEdep.cxx:27
cout<< "Opened file "<< fin<< " ixs= "<< ixs<< endl;if(ixs==0) hhh=(TH1F *) fff-> Get("h1")
Definition: AddMC.C:8
const std::vector< sim::MCEdep > & GetEdepArrayAt(size_t edep_index) const
Returns a vector of MCEdep object at the given index.
Definition: MCRecoEdep.cxx:48
Access the description of the physical detector geometry.
MCRecoEdep(fhicl::ParameterSet const &pset)
Default constructor with fhicl parameters.
Definition: MCRecoEdep.cxx:41
T get(std::string const &key) const
Definition: ParameterSet.h:314
The data type to uniquely identify a TPC.
Definition: geo_types.h:306
Double_t edep
Definition: macro.C:13
Monte Carlo Simulation.
CryostatID PositionToCryostatID(Point_t const &point) const
Returns the ID of the cryostat at specified location.
std::vector< sim::MCEdep > & __GetEdepArray__(unsigned int track_id)
Definition: MCRecoEdep.cxx:55
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
std::vector< deposit > deps
Definition: MCRecoEdep.h:82
unsigned int ChannelID_t
Type representing the ID of a readout channel.
Definition: RawTypes.h:28
Float_t e
Definition: plot.C:35
second_as<> second
Type of time stored in seconds, in double precision.
Definition: spacetime.h:82
TPCID PositionToTPCID(Point_t const &point) const
Returns the ID of the TPC at specified location.
art framework interface to geometry description
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
Encapsulate the construction of a single detector plane .