LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
DrawSimEnergyDeposit3D_tool.cc
Go to the documentation of this file.
1 
14 
17 
22 
23 #include "TPolyMarker3D.h"
24 
25 namespace evdb_tool {
26 
28  public:
29  explicit DrawSimEnergyDeposit3D(const fhicl::ParameterSet& pset);
30 
31  void Draw(const art::Event&, evdb::View3D*) const override;
32 
33  private:
34  void drawMCPartAssociated(const art::Event&, evdb::View3D*) const;
35  void drawAll(const art::Event&, evdb::View3D*) const;
36 
38  };
39 
40  //----------------------------------------------------------------------
41  // Constructor.
43  {
44  fDrawAllSimEnergy = pset.get<bool>("DrawAllSimEnergyDeposits", false);
45  }
46 
48  {
50 
51  // If the option is turned off, there's nothing to do
52  if (!drawOpt->fShowSimEnergyInfo) return;
53 
54  // Split here if drawing all vs drawing MC associated only
56  drawAll(evt, view);
57  else
58  drawMCPartAssociated(evt, view);
59 
60  return;
61  }
62 
64  {
66 
67  // Recover a handle to the collection of MCParticles
68  // We need these so we can determine the offset (if any)
70 
71  evt.getByLabel(drawOpt->fG4ModuleLabel, mcParticleHandle);
72 
73  if (!mcParticleHandle.isValid()) return;
74 
75  // Create a mapping between track ID's and MCParticles
76  using TrackToMcParticleMap = std::map<int, const simb::MCParticle*>;
77 
78  TrackToMcParticleMap trackToMcParticleMap;
79 
80  for (const auto& mcParticle : *mcParticleHandle)
81  trackToMcParticleMap[mcParticle.TrackId()] = &mcParticle;
82 
83  // Now recover the simchannels
84  art::Handle<std::vector<sim::SimEnergyDeposit>> simEnergyDepositHandle;
85 
86  evt.getByLabel(drawOpt->fSimEnergyLabel, simEnergyDepositHandle);
87 
88  auto const clockData = art::ServiceHandle<detinfo::DetectorClocksService const>()->DataFor(evt);
89  auto const detProp =
91 
92  if (simEnergyDepositHandle.isValid() && simEnergyDepositHandle->size() > 0) {
93  mf::LogDebug("SimEnergyDeposit3DDrawer")
94  << "Starting loop over " << simEnergyDepositHandle->size() << " SimEnergyDeposits, "
95  << std::endl;
96 
98 
99  // First step is to create a map between MCParticle and SimEnergyDeposit objects...
100  using MCPartToSimEnergyMap =
101  std::map<const simb::MCParticle*, std::vector<const sim::SimEnergyDeposit*>>;
102 
103  MCPartToSimEnergyMap mcPartToSimEnergyMap;
104 
105  // Go through the SimEnergyDeposits and populate the map
106  for (const auto& simEnergyDeposit : *simEnergyDepositHandle) {
108  trackToMcParticleMap.find(simEnergyDeposit.TrackID());
109 
110  if (trackMCItr == trackToMcParticleMap.end()) continue;
111 
112  mcPartToSimEnergyMap[trackMCItr->second].push_back(&simEnergyDeposit);
113  }
114 
115  // Would like to draw the deposits as markers with colors given by particle id
116  // So we make two passes, first to fill a map with color the key and positions for the markers
117  std::map<int, std::vector<sim::SimEnergyDeposit::Point_t>> colorToPositionMap;
118 
119  // Now we loop through and build the mapping of color to positions
120  for (const auto& mcPartToSimEnergy : mcPartToSimEnergyMap) {
121  // The first task we need to take on is to find the offset for the
122  // energy deposit This is for the case of "out of time" particles...
123  // (e.g. cosmic rays)
124  double g4Ticks(clockData.TPCG4Time2Tick(mcPartToSimEnergy.first->T()) -
125  trigger_offset(clockData));
126  double xOffset(0.);
127  double xPosMinTick(0.);
128  double xPosMaxTick(std::numeric_limits<double>::max());
129 
130  for (const auto& simEnergyDeposit : mcPartToSimEnergy.second) {
131  sim::SimEnergyDeposit::Point_t point = simEnergyDeposit->MidPoint();
132 
133  // If we have cosmic rays then we need to get the offset which allows translating from
134  // when they were generated vs when they were tracked.
135  // Note that this also explicitly checks that they are in a TPC volume
136  try {
137  geo::TPCID tpcID = geom->PositionToTPCID(point);
138  geo::PlaneID planeID(tpcID, 0);
139 
140  xPosMinTick = detProp.ConvertTicksToX(0, planeID);
141  xPosMaxTick = detProp.ConvertTicksToX(detProp.NumberTimeSamples(), planeID);
142  xOffset = detProp.ConvertTicksToX(g4Ticks, planeID) - xPosMinTick;
143 
144  if (xPosMaxTick < xPosMinTick) std::swap(xPosMinTick, xPosMaxTick);
145  }
146  catch (...) {
147  continue;
148  }
149 
150  colorToPositionMap[evd::Style::ColorFromPDG(simEnergyDeposit->PdgCode())].emplace_back(
151  sim::SimEnergyDeposit::Point_t(point.X() + xOffset, point.Y(), point.Z()));
152  }
153  }
154 
155  // Now we can do some drawing
156  for (const auto& pair : colorToPositionMap) {
157  int colorIdx(pair.first);
158  int markerIdx(kFullDotMedium);
159  int markerSize(2);
160 
161  TPolyMarker3D& pm = view->AddPolyMarker3D(1, colorIdx, markerIdx, markerSize);
162 
163  // Import positions into an array
164  std::vector<double> posArrayVec;
165  int hitCount(0);
166 
167  posArrayVec.resize(3 * pair.second.size());
168 
169  for (const auto& point : pair.second) {
170  posArrayVec[3 * hitCount] = point.X();
171  posArrayVec[3 * hitCount + 1] = point.Y();
172  posArrayVec[3 * hitCount + 2] = point.Z();
173  hitCount++;
174  }
175 
176  pm.SetPolyMarker(hitCount, posArrayVec.data(), markerIdx);
177  }
178  }
179 
180  return;
181  }
182 
184  {
186 
187  // NOTE: In this mode we cannot correct the voxel positions for time offsets since we have nothing to offset with
188  // The voxels are drawn in the x,y,z locations given by the SimEnergyDeposit objects
189 
190  // Recover the simchannels
191  art::Handle<std::vector<sim::SimEnergyDeposit>> simEnergyDepositHandle;
192 
193  evt.getByLabel(drawOpt->fSimEnergyLabel, simEnergyDepositHandle);
194 
195  if (simEnergyDepositHandle.isValid() && simEnergyDepositHandle->size() > 0) {
196  mf::LogDebug("SimEnergyDeposit3DDrawer")
197  << "Starting loop over " << simEnergyDepositHandle->size() << " SimEnergyDeposits, "
198  << std::endl;
199 
200  // Get the geometry service and its friends
201  auto const clockData =
203  auto const detProp =
206 
207  // Would like to draw the deposits as markers with colors given by particle id
208  // So we make two passes, first to fill a map with color the key and positions for the markers
209  std::map<int, std::vector<sim::SimEnergyDeposit::Point_t>> colorToPositionMap;
210 
211  // Go through the SimEnergyDeposits and populate the map
212  for (const auto& simEnergyDeposit : *simEnergyDepositHandle) {
213  // If we have cosmic rays then we need to get the offset which allows translating from
214  // when they were generated vs when they were tracked.
215  // Note that this also explicitly checks that they are in a TPC volume
216  try {
217  sim::SimEnergyDeposit::Point_t point = simEnergyDeposit.MidPoint();
218  double depTime = simEnergyDeposit.T();
219  geo::TPCID tpcID = geom->PositionToTPCID(point);
220  geo::PlaneID planeID(tpcID, 0);
221  double g4Ticks = clockData.TPCG4Time2Tick(depTime) - trigger_offset(clockData);
222  double xPosMinTick = detProp.ConvertTicksToX(0, planeID);
223  double xOffset = detProp.ConvertTicksToX(g4Ticks, planeID) - xPosMinTick;
224 
225  colorToPositionMap[evd::Style::ColorFromPDG(simEnergyDeposit.PdgCode())].emplace_back(
226  sim::SimEnergyDeposit::Point_t(point.X() + xOffset, point.Y(), point.Z()));
227  }
228  catch (...) {
229  continue;
230  }
231  }
232 
233  // Now we can do some drawing
234  for (const auto& pair : colorToPositionMap) {
235  int colorIdx(pair.first);
236  int markerIdx(kFullDotMedium);
237  int markerSize(2);
238 
239  TPolyMarker3D& pm = view->AddPolyMarker3D(1, colorIdx, markerIdx, markerSize);
240 
241  // Import positions into an array
242  std::vector<double> posArrayVec;
243  int hitCount(0);
244 
245  posArrayVec.resize(3 * pair.second.size());
246 
247  for (const auto& point : pair.second) {
248  posArrayVec[3 * hitCount] = point.X();
249  posArrayVec[3 * hitCount + 1] = point.Y();
250  posArrayVec[3 * hitCount + 2] = point.Z();
251  hitCount++;
252  }
253 
254  pm.SetPolyMarker(hitCount, posArrayVec.data(), markerIdx);
255  }
256  }
257 
258  return;
259  }
260 
262 }
#define DEFINE_ART_CLASS_TOOL(tool)
Definition: ToolMacros.h:42
The data type to uniquely identify a Plane.
Definition: geo_types.h:463
void drawAll(const art::Event &, evdb::View3D *) const
art::InputTag fG4ModuleLabel
module label producing sim::SimChannel objects
void drawMCPartAssociated(const art::Event &, evdb::View3D *) const
intermediate_table::const_iterator const_iterator
Particle class.
DrawSimEnergyDeposit3D(const fhicl::ParameterSet &pset)
bool isValid() const noexcept
Definition: Handle.h:203
void Draw(const art::Event &, evdb::View3D *) const override
T get(std::string const &key) const
Definition: ParameterSet.h:314
static int ColorFromPDG(int pdgcode)
Definition: Style.cxx:65
The data type to uniquely identify a TPC.
Definition: geo_types.h:381
bool getByLabel(std::string const &label, std::string const &instance, Handle< PROD > &result) const
MaybeLogger_< ELseverityLevel::ELsev_success, false > LogDebug
contains information for a single step in the detector simulation
int trigger_offset(DetectorClocksData const &data)
A collection of 3D drawable objects.
TCEvent evt
Definition: DataStructs.cxx:8
TPCID PositionToTPCID(Point_t const &point) const
Returns the ID of the TPC at specified location.
art framework interface to geometry description
TPolyMarker3D & AddPolyMarker3D(int n, int c, int st, double sz)
Definition: View3D.cxx:75
art::InputTag fSimEnergyLabel
Also for SimEnergyDeposits.