All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
DrawSimPhoton3D_tool.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 /// \file DrawSimPhoton3D_tool.cc
3 /// \author T. Usher
4 ////////////////////////////////////////////////////////////////////////
5 
11 
12 #include "nuevdb/EventDisplayBase/View3D.h"
13 #include "nusimdata/SimulationBase/MCParticle.h"
14 
15 #include "art/Framework/Principal/Event.h"
16 #include "art/Framework/Services/Registry/ServiceHandle.h"
17 #include "art/Utilities/ToolMacros.h"
18 #include "messagefacility/MessageLogger/MessageLogger.h"
19 
20 #include "TPolyLine3D.h"
21 
22 // Eigen
23 #include <Eigen/Core>
24 
25 namespace evdb_tool {
26 
27  class DrawSimPhoton3D : public ISim3DDrawer {
28  public:
29  explicit DrawSimPhoton3D(const fhicl::ParameterSet& pset);
30 
32 
33  void Draw(const art::Event&, evdb::View3D*) const override;
34 
35  private:
36  void DrawRectangularBox(evdb::View3D*,
37  const Eigen::Vector3f&,
38  const Eigen::Vector3f&,
39  int,
40  int,
41  int) const;
42  };
43 
44  //----------------------------------------------------------------------
45  // Constructor.
46  DrawSimPhoton3D::DrawSimPhoton3D(const fhicl::ParameterSet& pset)
47  {
48  // fNumPoints = pset.get< int>("NumPoints", 1000);
49  // fFloatBaseline = pset.get<bool>("FloatBaseline", false);
50 
51  return;
52  }
53 
55 
56  void
57  DrawSimPhoton3D::Draw(const art::Event& evt, evdb::View3D* view) const
58  {
59  art::ServiceHandle<evd::SimulationDrawingOptions> drawOpt;
60 
61  // If the option is turned off, there's nothing to do
62  if (!drawOpt->fShowSimPhotonInfo) return;
63 
64  // Recover a handle to the collection of MCParticles
65  // We need these so we can determine the offset (if any)
66  art::Handle<std::vector<simb::MCParticle>> mcParticleHandle;
67 
68  evt.getByLabel(drawOpt->fG4ModuleLabel, mcParticleHandle);
69 
70  if (!mcParticleHandle.isValid()) return;
71 
72  // Create a mapping between track ID's and MCParticles
73  using TrackToMcParticleMap = std::map<int, const simb::MCParticle*>;
74 
75  TrackToMcParticleMap trackToMcParticleMap;
76 
77  for (const auto& mcParticle : *mcParticleHandle)
78  trackToMcParticleMap[mcParticle.TrackId()] = &mcParticle;
79 
80  // Now recover the simphotons
81  art::Handle<std::vector<sim::SimPhotons>> simPhotonsHandle;
82 
83  evt.getByLabel(drawOpt->fSimPhotonLabel, simPhotonsHandle);
84 
85  if (simPhotonsHandle.isValid() && simPhotonsHandle->size() > 0) {
86  mf::LogDebug("SimPhoton3DDrawer")
87  << "Starting loop over " << simPhotonsHandle->size() << " SimPhotons, " << std::endl;
88 
89  // Get the detector properties, clocks...
90  art::ServiceHandle<geo::Geometry> geom;
91  art::ServiceHandle<evd::ColorDrawingOptions> cst;
92 
93  // First step is to create a map between MCParticle and SimEnergyDeposit objects...
94  using MCPartToOnePhotonMap =
95  std::map<const simb::MCParticle*, std::vector<const sim::OnePhoton*>>;
96  using ChanToMCPartToOnePhotonMap = std::map<int, MCPartToOnePhotonMap>;
97 
98  ChanToMCPartToOnePhotonMap chanToMCPartToOnePhotonMap;
99 
100  // Go through the SimEnergyDeposits and populate the map
101  for (const auto& simPhoton : *simPhotonsHandle) {
102  MCPartToOnePhotonMap& mcPartToOnePhotonMap =
103  chanToMCPartToOnePhotonMap[simPhoton.OpChannel()];
104 
105  for (const auto& onePhoton : simPhoton) {
106  TrackToMcParticleMap::const_iterator trackMCItr =
107  trackToMcParticleMap.find(onePhoton.MotherTrackID);
108 
109  if (trackMCItr == trackToMcParticleMap.end()) continue;
110 
111  mcPartToOnePhotonMap[trackMCItr->second].push_back(&onePhoton);
112  }
113  }
114 
115  // Mapping of energy deposited per channel...
116  std::map<int, float> channelToEnergyMap;
117 
118  // Keep track of mininum and maximum
119  float maxEnergy = std::numeric_limits<float>::lowest();
120  float minEnergy = std::numeric_limits<float>::max();
121 
122  // Go through everything and get cenergy desposited per channel...
123  for (const auto& chanToMCPartToOnePhoton : chanToMCPartToOnePhotonMap) {
124  float totalE(0.);
125 
126  // Go through all contributors to this channel
127  for (const auto& mcPartToOnePhoton : chanToMCPartToOnePhoton.second) {
128  // Current scheme will ignore displacement in time... need to come back to this at some point...
129  // // The first task we need to take on is to find the offset for the energy deposit
130  // // This is for the case of "out of time" particles... (e.g. cosmic rays)
131  // double g4Ticks(detClocks->TPCG4Time2Tick(mcPartToOnePhoton.first->T())-theDetector->TriggerOffset());
132  // double xOffset(0.);
133  // double xPosMinTick(0.);
134  // double xPosMaxTick(std::numeric_limits<double>::max());
135 
136  for (const auto& onePhoton : mcPartToOnePhoton.second) {
137  // Eigen::Vector3f point(onePhoton->InitialPosition.X(),onePhoton->InitialPosition.Y(),onePhoton->InitialPosition.Z());
138  //
139  // std::cout << " - Initial: " << onePhoton->InitialPosition.X() << "/" << onePhoton->InitialPosition.Y() << "/" << onePhoton->InitialPosition.Z() << ", final : " //<< onePhoton->FinalLocalPosition.X() << "/" << onePhoton->FinalLocalPosition.Y() << "/" << onePhoton->FinalLocalPosition.Z() << std::endl;
140  //
141  // // If we have cosmic rays then we need to get the offset which allows translating from
142  // // when they were generated vs when they were tracked.
143  // // Note that this also explicitly checks that they are in a TPC volume
144  // try
145  // {
146  // geo::TPCID tpcID = geom->PositionToTPCID(geo::Point_t(point[0],point[1],point[2]));
147  //
148  // if (tpcID.Cryostat == geo::CryostatID::InvalidID || tpcID.TPC == geo::TPCID::InvalidID) continue;
149  //
150  // geo::PlaneID planeID(tpcID,0);
151  //
152  // xPosMinTick = theDetector->ConvertTicksToX(0,planeID);
153  // xPosMaxTick = theDetector->ConvertTicksToX(theDetector->NumberTimeSamples(),planeID);
154  // xOffset = theDetector->ConvertTicksToX(g4Ticks, planeID) - xPosMinTick;
155  //
156  // if (xPosMaxTick < xPosMinTick) std::swap(xPosMinTick,xPosMaxTick);
157  // }
158  // catch(...) {continue;}
159 
160  // Recover the deposited energy
161  totalE += onePhoton->Energy;
162  }
163  }
164 
165  channelToEnergyMap[chanToMCPartToOnePhoton.first] = totalE;
166 
167  maxEnergy = std::max(maxEnergy, totalE);
168  minEnergy = std::min(minEnergy, totalE);
169  }
170 
171  // Get the scale factor from energy deposit range
172  float yzWidthScale(1. / (maxEnergy - minEnergy));
173  float energyDepositScale(
174  (cst->fRecoQHigh[geo::kCollection] - cst->fRecoQLow[geo::kCollection]) * yzWidthScale);
175 
176  // Go through the channels and draw the objects
177  for (const auto& channelToEnergy : channelToEnergyMap) {
178  // Recover the color index based on energy
179  float widthFactor =
180  0.95 * std::max(float(0.), std::min(float(1.), yzWidthScale* channelToEnergy.second));
181  float energyFactor =
182  cst->fRecoQLow[geo::kCollection] + energyDepositScale * channelToEnergy.second;
183 
184  // Recover the position for this channel
185  const geo::OpDetGeo& opHitGeo = geom->OpDetGeoFromOpChannel(channelToEnergy.first);
186  const geo::Point_t& opHitPos = opHitGeo.GetCenter();
187  float xWidth = 0.01;
188  float zWidth = widthFactor * opHitGeo.HalfW();
189  float yWidth = widthFactor * opHitGeo.HalfH();
190 
191  // Get widths of box to draw
192  Eigen::Vector3f coordsLo(
193  opHitPos.X() - xWidth, opHitPos.Y() - yWidth, opHitPos.Z() - zWidth);
194  Eigen::Vector3f coordsHi(
195  opHitPos.X() + xWidth, opHitPos.Y() + yWidth, opHitPos.Z() + zWidth);
196 
197  int energyColorIdx = cst->CalQ(geo::kCollection).GetColor(energyFactor);
198 
199  DrawRectangularBox(view, coordsLo, coordsHi, energyColorIdx, 1, 1);
200  }
201  }
202 
203  return;
204  }
205 
206  void
208  const Eigen::Vector3f& coordsLo,
209  const Eigen::Vector3f& coordsHi,
210  int color,
211  int width,
212  int style) const
213  {
214  TPolyLine3D& top = view->AddPolyLine3D(5, color, width, style);
215  top.SetPoint(0, coordsLo[0], coordsHi[1], coordsLo[2]);
216  top.SetPoint(1, coordsHi[0], coordsHi[1], coordsLo[2]);
217  top.SetPoint(2, coordsHi[0], coordsHi[1], coordsHi[2]);
218  top.SetPoint(3, coordsLo[0], coordsHi[1], coordsHi[2]);
219  top.SetPoint(4, coordsLo[0], coordsHi[1], coordsLo[2]);
220 
221  TPolyLine3D& side = view->AddPolyLine3D(5, color, width, style);
222  side.SetPoint(0, coordsHi[0], coordsHi[1], coordsLo[2]);
223  side.SetPoint(1, coordsHi[0], coordsLo[1], coordsLo[2]);
224  side.SetPoint(2, coordsHi[0], coordsLo[1], coordsHi[2]);
225  side.SetPoint(3, coordsHi[0], coordsHi[1], coordsHi[2]);
226  side.SetPoint(4, coordsHi[0], coordsHi[1], coordsLo[2]);
227 
228  TPolyLine3D& side2 = view->AddPolyLine3D(5, color, width, style);
229  side2.SetPoint(0, coordsLo[0], coordsHi[1], coordsLo[2]);
230  side2.SetPoint(1, coordsLo[0], coordsLo[1], coordsLo[2]);
231  side2.SetPoint(2, coordsLo[0], coordsLo[1], coordsHi[2]);
232  side2.SetPoint(3, coordsLo[0], coordsHi[1], coordsHi[2]);
233  side2.SetPoint(4, coordsLo[0], coordsHi[1], coordsLo[2]);
234 
235  TPolyLine3D& bottom = view->AddPolyLine3D(5, color, width, style);
236  bottom.SetPoint(0, coordsLo[0], coordsLo[1], coordsLo[2]);
237  bottom.SetPoint(1, coordsHi[0], coordsLo[1], coordsLo[2]);
238  bottom.SetPoint(2, coordsHi[0], coordsLo[1], coordsHi[2]);
239  bottom.SetPoint(3, coordsLo[0], coordsLo[1], coordsHi[2]);
240  bottom.SetPoint(4, coordsLo[0], coordsLo[1], coordsLo[2]);
241 
242  return;
243  }
244 
245  DEFINE_ART_CLASS_TOOL(DrawSimPhoton3D)
246 }
void Draw(const art::Event &, evdb::View3D *) const override
walls no bottom
Definition: selectors.fcl:105
void DrawRectangularBox(evdb::View3D *, const Eigen::Vector3f &, const Eigen::Vector3f &, int, int, int) const
void GetCenter(double *xyz, double localz=0.0) const
Definition: OpDetGeo.cxx:40
def style
Definition: util.py:237
walls no top
Definition: selectors.fcl:105
The color scales used by the event display.
double HalfW() const
Definition: OpDetGeo.cxx:71
Simulation objects for optical detectors.
double HalfH() const
Definition: OpDetGeo.cxx:79
TCEvent evt
Definition: DataStructs.cxx:8
ROOT::Math::PositionVector3D< ROOT::Math::Cartesian3D< double >, ROOT::Math::GlobalCoordinateSystemTag > Point_t
Type for representation of position in physical 3D space.
Definition: geo_vectors.h:184
art framework interface to geometry description
DrawSimPhoton3D(const fhicl::ParameterSet &pset)
Signal from collection planes.
Definition: geo_types.h:146