MCRecoEdep.cxx
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 //
3 // MCRecoEdep source
4 //
5 ////////////////////////////////////////////////////////////////////////
6 
9 
16 
17 #include "MCRecoEdep.h"
18 
19 namespace sim {
20 
21  namespace details {
22  std::map<geo::PlaneID, size_t> createPlaneIndexMap(){
24  std::map<geo::PlaneID, size_t> m;
25  size_t i = 0;
26  for(auto const& pid : geom->IteratePlaneIDs()){
27  m[pid] = i;
28  i++;
29  }
30  return m;
31  }
32  }
33  //const unsigned short MCEdepHit::kINVALID_USHORT = std::numeric_limits<unsigned short>::max();
34 
35  //const short MCEdep::kINVALID_SHORT = std::numeric_limits<short>::max();
36 
37  //##################################################################
39  //##################################################################
40  {
41  _debug_mode = pset.get<bool>("DebugMode");
42  _save_mchit = pset.get<bool>("SaveMCHit");
43  }
44 
45  const std::vector<sim::MCEdep>& MCRecoEdep::GetEdepArrayAt(size_t edep_index) const
46  {
47  if(edep_index >= _mc_edeps.size())
48  throw cet::exception(__FUNCTION__) << Form("Track ID %zu not found!",edep_index);
49  return _mc_edeps.at(edep_index);
50  }
51 
52  std::vector<sim::MCEdep>& MCRecoEdep::__GetEdepArray__(unsigned int track_id)
53  {
54  if(ExistTrack(track_id)) return _mc_edeps.at((*_track_index.find(track_id)).second);
55  _track_index.insert(std::pair<unsigned int,size_t>(track_id,_mc_edeps.size()));
56  _mc_edeps.push_back(std::vector<sim::MCEdep>());
57  return (*(_mc_edeps.rbegin()));
58  }
59 
60  void MCRecoEdep::MakeMCEdep(const std::vector<sim::SimChannel>& schArray)
61  {
62  _mc_edeps.clear();
63  _track_index.clear();
64 
66 // const detinfo::DetectorProperties* detp = lar::providerFrom<detinfo::DetectorPropertiesService>();
67 
68  // Key map to identify a unique particle energy deposition point
69  std::map<std::pair<UniquePosition, unsigned int>, int> hit_index_m;
70 
71  auto pindex = details::createPlaneIndexMap();
72 
73  if(_debug_mode) std::cout<<"Processing "<<schArray.size()<<" channels..."<<std::endl;
74  // Loop over channels
75  for(size_t i=0; i<schArray.size(); ++i) {
76 
77  // Get data to loop over
78  auto const& sch = schArray[i];
79  const auto &sch_map(sch.TDCIDEMap());
80  // Channel
81  UInt_t ch = sch.Channel();
82  // Loop over ticks
83  for(auto tdc_iter = sch_map.begin(); tdc_iter!=sch_map.end(); ++tdc_iter) {
84  // for c2: hit_time is unused
85  //unsigned short hit_time = (*tdc_iter).first;
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 = this->__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 = geom->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  //float charge = ide.numElectrons * detp->ElectronsToADC();
111  this->__GetEdepArray__(real_track_id).emplace_back(pos, pid, pindex.size(), ide.energy, charge, channel_id);
112  } else {
113  // Append charge to the relevant edep (@ hit_index)
114  //float charge = ide.numElectrons * detp->ElectronsToADC();
115  MCEdep &edep = this->__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()) << std::endl;
125  // for c2: disable the entire loop instead of just the print statement
126  //for(auto const& track_id_index : _track_index ) {
127  //auto track_id = track_id_index.first;
128  //auto edep_index = track_id_index.second;
129  // std::cout<< Form(" Track ID: %d ... %zu Edep!", track_id, edep_index) << std::endl;
130  //}
131  std::cout<<std::endl;
132  }
133  }
134 
135  void MCRecoEdep::MakeMCEdep(const std::vector<sim::SimEnergyDeposit>& sedArray)
136  {
137  _mc_edeps.clear();
138  _track_index.clear();
139 
141 // const detinfo::DetectorProperties* detp = lar::providerFrom<detinfo::DetectorPropertiesService>();
142 
143  // Key map to identify a unique particle energy deposition point
144  std::map<std::pair<UniquePosition, unsigned int>, int> hit_index_m;
145 
146  auto pindex = details::createPlaneIndexMap();
147 
148  if(_debug_mode) std::cout<<"Processing "<<sedArray.size()<<" energy deposits..."<<std::endl;
149  // Loop over channels
150  for(size_t i=0; i<sedArray.size(); ++i) {
151 
152  // Get data to loop over
153  auto const& sed = sedArray[i];
154 
155  // David Caratelli:
156  // much of the code below is taken from the module:
157  // https://cdcvs.fnal.gov/redmine/projects/larsim/repository/revisions/develop/entry/larsim/ElectronDrift/SimDriftElectrons_module.cc
158 
159  // given this SimEnergyDeposit, find the TPC channel information
160  // "xyz" is the position of the energy deposit in world
161  // coordinates. Note that the units of distance in
162  // sim::SimEnergyDeposit are supposed to be cm.
163  auto const mp = sed.MidPoint();
164  double const xyz[3] = { mp.X(), mp.Y(), mp.Z() };
165  // From the position in world coordinates, determine the
166  // cryostat and tpc. If somehow the step is outside a tpc
167  // (e.g., cosmic rays in rock) just move on to the next one.
168  unsigned int cryostat = 0;
169  try {
170  geom->PositionToCryostat(xyz, cryostat);
171  }
172  catch(cet::exception &e){
173  mf::LogWarning("SimDriftElectrons") << "step "// << energyDeposit << "\n"
174  << "cannot be found in a cryostat\n"
175  << e;
176  continue;
177  }
178  unsigned int tpc = 0;
179  try {
180  geom->PositionToTPC(xyz, tpc, cryostat);
181  }
182  catch(cet::exception &e){
183  mf::LogWarning("SimDriftElectrons") << "step "// << energyDeposit << "\n"
184  << "cannot be found in a TPC\n"
185  << e;
186  continue;
187  }
188  const geo::TPCGeo& tpcGeo = geom->TPC(tpc, cryostat);
189 
190  //Define charge drift direction: driftcoordinate (x, y or z) and driftsign (positive or negative). Also define coordinates perpendicular to drift direction.
191  // unused int driftcoordinate = std::abs(tpcGeo.DetectDriftDirection())-1; //x:0, y:1, z:2
192 
193  // make a collection of electrons for each plane
194  for(size_t p = 0; p < tpcGeo.Nplanes(); ++p){
195 
196  // grab the nearest channel to the fDriftClusterPos position
197  // David Caratelli, comment begin:
198  // NOTE: the below code works only when the drift coordinate is indeed in x (i.e. 0th coordinate)
199  // see code linked above for a much more careful treatment of the coordinate system
200  // David Caratelli, comment end.
201  raw::ChannelID_t ch;
202  try {
203  ch = geom->NearestChannel(xyz, p, tpc, cryostat);
204  }
205  catch(cet::exception &e){
206  mf::LogWarning("SimDriftElectrons") << "step "// << energyDeposit << "\n"
207  << "nearest wire not in TPC\n"
208  << e;
209  continue;
210  }
211 
212  int track_id = sed.TrackID();
213 
214  if(track_id < 0) track_id = track_id * (-1);
215  unsigned int real_track_id = track_id;
216 
217  UniquePosition pos(xyz[0], xyz[1], xyz[2]);
218 
219  int hit_index = -1;
220  auto key = std::make_pair(pos, real_track_id);
221  auto hit_index_track_iter = hit_index_m.find(key);
222  if(hit_index_track_iter == hit_index_m.end()) {
223  int new_hit_index = this->__GetEdepArray__(real_track_id).size();
224  hit_index_m[key]= new_hit_index;
225  }
226  else {
227  hit_index = (*hit_index_track_iter).second;
228  }
229  auto const pid = geom->ChannelToWire(ch)[0].planeID();
230  auto const channel_id = pindex[pid];
231  double charge = sed.NumElectrons();
232  if(hit_index < 0) {
233  // This particle energy deposition is never recorded so far. Create a new Edep
234  //float charge = ide.numElectrons * detp->ElectronsToADC();
235  this->__GetEdepArray__(real_track_id).emplace_back(pos, pid, pindex.size(), sed.Energy(), charge, channel_id);
236  } else {
237  // Append charge to the relevant edep (@ hit_index)
238  //float charge = ide.numElectrons * detp->ElectronsToADC();
239  MCEdep &edep = this->__GetEdepArray__(real_track_id).at(hit_index);
240  edep.deps[channel_id].charge += charge;
241  edep.deps[channel_id].energy += sed.Energy();
242  }
243  } // end looping over planes
244  }// end looping over SimEnergyDeposits
245 
246  if(_debug_mode) {
247  std::cout<< Form(" Collected %zu particles' energy depositions...",_mc_edeps.size()) << std::endl;
248  // for c2: disable the entire loop instead of just the print statement
249  //for(auto const& track_id_index : _track_index ) {
250  //auto track_id = track_id_index.first;
251  //auto edep_index = track_id_index.second;
252  // std::cout<< Form(" Track ID: %d ... %zu Edep!", track_id, edep_index) << std::endl;
253  //}
254  std::cout<<std::endl;
255  }
256 
257  return;
258  }
259 
260 
261 }
void MakeMCEdep(const std::vector< sim::SimChannel > &schArray)
Definition: MCRecoEdep.cxx:60
CryostatGeo const & PositionToCryostat(geo::Point_t const &point) const
Returns the cryostat at specified location.
unsigned int Nplanes() const
Number of planes in this tpc.
Definition: TPCGeo.h:165
Geometry information for a single TPC.
Definition: TPCGeo.h:38
std::map< geo::PlaneID, size_t > createPlaneIndexMap()
Definition: MCRecoEdep.cxx:22
std::vector< geo::WireID > ChannelToWire(raw::ChannelID_t const channel) const
Returns a list of wires connected to the specified TPC channel.
const std::vector< sim::MCEdep > & GetEdepArrayAt(size_t edep_index) const
Returns a vector of MCEdep object at the given index.
Definition: MCRecoEdep.cxx:45
art framework interface to geometry description
geo::TPCGeo const & PositionToTPC(geo::Point_t const &point) const
Returns the TPC at specified location.
IteratorBox< plane_id_iterator,&GeometryCore::begin_plane_id,&GeometryCore::end_plane_id > IteratePlaneIDs() const
Enables ranged-for loops on all plane IDs of the detector.
MCRecoEdep(fhicl::ParameterSet const &pset)
Default constructor with fhicl parameters.
Definition: MCRecoEdep.cxx:38
const double e
def key(type, name=None)
Definition: graph.py:13
T get(std::string const &key) const
Definition: ParameterSet.h:271
p
Definition: test.py:223
Code to link reconstructed objects back to the MC truth information.
std::vector< sim::MCEdep > & __GetEdepArray__(unsigned int track_id)
Definition: MCRecoEdep.cxx:52
contains information for a single step in the detector simulation
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
std::vector< deposit > deps
Definition: MCRecoEdep.h:84
Access the description of detector geometry.
TPCGeo const & TPC(unsigned int const tpc=0, unsigned int const cstat=0) const
Returns the specified TPC.
unsigned int ChannelID_t
Type representing the ID of a readout channel.
Definition: RawTypes.h:28
raw::ChannelID_t NearestChannel(geo::Point_t const &worldLoc, geo::PlaneID const &planeid) const
Returns the ID of the channel nearest to the specified position.
second_as<> second
Type of time stored in seconds, in double precision.
Definition: spacetime.h:85
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
QTextStream & endl(QTextStream &s)
Encapsulate the construction of a single detector plane.