LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
DrawSimPhoton3D_tool.cc
Go to the documentation of this file.
1 
11 
14 
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:
37  const Eigen::Vector3f&,
38  const Eigen::Vector3f&,
39  int,
40  int,
41  int) const;
42  };
43 
44  //----------------------------------------------------------------------
45  // Constructor.
47  {
48  // fNumPoints = pset.get< int>("NumPoints", 1000);
49  // fFloatBaseline = pset.get<bool>("FloatBaseline", false);
50 
51  return;
52  }
53 
55 
57  {
59 
60  // If the option is turned off, there's nothing to do
61  if (!drawOpt->fShowSimPhotonInfo) return;
62 
63  // Recover a handle to the collection of MCParticles
64  // We need these so we can determine the offset (if any)
66 
67  evt.getByLabel(drawOpt->fG4ModuleLabel, mcParticleHandle);
68 
69  if (!mcParticleHandle.isValid()) return;
70 
71  // Create a mapping between track ID's and MCParticles
72  using TrackToMcParticleMap = std::map<int, const simb::MCParticle*>;
73 
74  TrackToMcParticleMap trackToMcParticleMap;
75 
76  for (const auto& mcParticle : *mcParticleHandle)
77  trackToMcParticleMap[mcParticle.TrackId()] = &mcParticle;
78 
79  // Now recover the simphotons
81 
82  evt.getByLabel(drawOpt->fSimPhotonLabel, simPhotonsHandle);
83 
84  if (simPhotonsHandle.isValid() && simPhotonsHandle->size() > 0) {
85  mf::LogDebug("SimPhoton3DDrawer")
86  << "Starting loop over " << simPhotonsHandle->size() << " SimPhotons, " << std::endl;
87 
88  // Get the detector properties, clocks...
91 
92  // First step is to create a map between MCParticle and SimEnergyDeposit objects...
93  using MCPartToOnePhotonMap =
94  std::map<const simb::MCParticle*, std::vector<const sim::OnePhoton*>>;
95  using ChanToMCPartToOnePhotonMap = std::map<int, MCPartToOnePhotonMap>;
96 
97  ChanToMCPartToOnePhotonMap chanToMCPartToOnePhotonMap;
98 
99  // Go through the SimEnergyDeposits and populate the map
100  for (const auto& simPhoton : *simPhotonsHandle) {
101  MCPartToOnePhotonMap& mcPartToOnePhotonMap =
102  chanToMCPartToOnePhotonMap[simPhoton.OpChannel()];
103 
104  for (const auto& onePhoton : simPhoton) {
106  trackToMcParticleMap.find(onePhoton.MotherTrackID);
107 
108  if (trackMCItr == trackToMcParticleMap.end()) continue;
109 
110  mcPartToOnePhotonMap[trackMCItr->second].push_back(&onePhoton);
111  }
112  }
113 
114  // Mapping of energy deposited per channel...
115  std::map<int, float> channelToEnergyMap;
116 
117  // Keep track of mininum and maximum
118  float maxEnergy = std::numeric_limits<float>::lowest();
119  float minEnergy = std::numeric_limits<float>::max();
120 
121  // Go through everything and get cenergy desposited per channel...
122  for (const auto& chanToMCPartToOnePhoton : chanToMCPartToOnePhotonMap) {
123  float totalE(0.);
124 
125  // Go through all contributors to this channel
126  for (const auto& mcPartToOnePhoton : chanToMCPartToOnePhoton.second) {
127  // Current scheme will ignore displacement in time... need to come back to this at some point...
128  // // The first task we need to take on is to find the offset for the energy deposit
129  // // This is for the case of "out of time" particles... (e.g. cosmic rays)
130  // double g4Ticks(detClocks->TPCG4Time2Tick(mcPartToOnePhoton.first->T())-theDetector->TriggerOffset());
131  // double xOffset(0.);
132  // double xPosMinTick(0.);
133  // double xPosMaxTick(std::numeric_limits<double>::max());
134 
135  for (const auto& onePhoton : mcPartToOnePhoton.second) {
136  // Eigen::Vector3f point(onePhoton->InitialPosition.X(),onePhoton->InitialPosition.Y(),onePhoton->InitialPosition.Z());
137  //
138  // std::cout << " - Initial: " << onePhoton->InitialPosition.X() << "/" << onePhoton->InitialPosition.Y() << "/" << onePhoton->InitialPosition.Z() << ", final : " //<< onePhoton->FinalLocalPosition.X() << "/" << onePhoton->FinalLocalPosition.Y() << "/" << onePhoton->FinalLocalPosition.Z() << std::endl;
139  //
140  // // If we have cosmic rays then we need to get the offset which allows translating from
141  // // when they were generated vs when they were tracked.
142  // // Note that this also explicitly checks that they are in a TPC volume
143  // try
144  // {
145  // geo::TPCID tpcID = geom->PositionToTPCID(geo::Point_t(point[0],point[1],point[2]));
146  //
147  // if (tpcID.Cryostat == geo::CryostatID::InvalidID || tpcID.TPC == geo::TPCID::InvalidID) continue;
148  //
149  // geo::PlaneID planeID(tpcID,0);
150  //
151  // xPosMinTick = theDetector->ConvertTicksToX(0,planeID);
152  // xPosMaxTick = theDetector->ConvertTicksToX(theDetector->NumberTimeSamples(),planeID);
153  // xOffset = theDetector->ConvertTicksToX(g4Ticks, planeID) - xPosMinTick;
154  //
155  // if (xPosMaxTick < xPosMinTick) std::swap(xPosMinTick,xPosMaxTick);
156  // }
157  // catch(...) {continue;}
158 
159  // Recover the deposited energy
160  totalE += onePhoton->Energy;
161  }
162  }
163 
164  channelToEnergyMap[chanToMCPartToOnePhoton.first] = totalE;
165 
166  maxEnergy = std::max(maxEnergy, totalE);
167  minEnergy = std::min(minEnergy, totalE);
168  }
169 
170  // Get the scale factor from energy deposit range
171  float yzWidthScale(1. / (maxEnergy - minEnergy));
172  float energyDepositScale(
173  (cst->fRecoQHigh[geo::kCollection] - cst->fRecoQLow[geo::kCollection]) * yzWidthScale);
174 
175  // Go through the channels and draw the objects
176  for (const auto& channelToEnergy : channelToEnergyMap) {
177  // Recover the color index based on energy
178  float widthFactor =
179  0.95 * std::max(float(0.), std::min(float(1.), yzWidthScale * channelToEnergy.second));
180  float energyFactor =
181  cst->fRecoQLow[geo::kCollection] + energyDepositScale * channelToEnergy.second;
182 
183  // Recover the position for this channel
184  const geo::OpDetGeo& opHitGeo = geom->OpDetGeoFromOpChannel(channelToEnergy.first);
185  const geo::Point_t& opHitPos = opHitGeo.GetCenter();
186  float xWidth = 0.01;
187  float zWidth = widthFactor * opHitGeo.HalfW();
188  float yWidth = widthFactor * opHitGeo.HalfH();
189 
190  // Get widths of box to draw
191  Eigen::Vector3f coordsLo(
192  opHitPos.X() - xWidth, opHitPos.Y() - yWidth, opHitPos.Z() - zWidth);
193  Eigen::Vector3f coordsHi(
194  opHitPos.X() + xWidth, opHitPos.Y() + yWidth, opHitPos.Z() + zWidth);
195 
196  int energyColorIdx = cst->CalQ(geo::kCollection).GetColor(energyFactor);
197 
198  DrawRectangularBox(view, coordsLo, coordsHi, energyColorIdx, 1, 1);
199  }
200  }
201 
202  return;
203  }
204 
206  const Eigen::Vector3f& coordsLo,
207  const Eigen::Vector3f& coordsHi,
208  int color,
209  int width,
210  int style) const
211  {
212  TPolyLine3D& top = view->AddPolyLine3D(5, color, width, style);
213  top.SetPoint(0, coordsLo[0], coordsHi[1], coordsLo[2]);
214  top.SetPoint(1, coordsHi[0], coordsHi[1], coordsLo[2]);
215  top.SetPoint(2, coordsHi[0], coordsHi[1], coordsHi[2]);
216  top.SetPoint(3, coordsLo[0], coordsHi[1], coordsHi[2]);
217  top.SetPoint(4, coordsLo[0], coordsHi[1], coordsLo[2]);
218 
219  TPolyLine3D& side = view->AddPolyLine3D(5, color, width, style);
220  side.SetPoint(0, coordsHi[0], coordsHi[1], coordsLo[2]);
221  side.SetPoint(1, coordsHi[0], coordsLo[1], coordsLo[2]);
222  side.SetPoint(2, coordsHi[0], coordsLo[1], coordsHi[2]);
223  side.SetPoint(3, coordsHi[0], coordsHi[1], coordsHi[2]);
224  side.SetPoint(4, coordsHi[0], coordsHi[1], coordsLo[2]);
225 
226  TPolyLine3D& side2 = view->AddPolyLine3D(5, color, width, style);
227  side2.SetPoint(0, coordsLo[0], coordsHi[1], coordsLo[2]);
228  side2.SetPoint(1, coordsLo[0], coordsLo[1], coordsLo[2]);
229  side2.SetPoint(2, coordsLo[0], coordsLo[1], coordsHi[2]);
230  side2.SetPoint(3, coordsLo[0], coordsHi[1], coordsHi[2]);
231  side2.SetPoint(4, coordsLo[0], coordsHi[1], coordsLo[2]);
232 
233  TPolyLine3D& bottom = view->AddPolyLine3D(5, color, width, style);
234  bottom.SetPoint(0, coordsLo[0], coordsLo[1], coordsLo[2]);
235  bottom.SetPoint(1, coordsHi[0], coordsLo[1], coordsLo[2]);
236  bottom.SetPoint(2, coordsHi[0], coordsLo[1], coordsHi[2]);
237  bottom.SetPoint(3, coordsLo[0], coordsLo[1], coordsHi[2]);
238  bottom.SetPoint(4, coordsLo[0], coordsLo[1], coordsLo[2]);
239 
240  return;
241  }
242 
244 }
#define DEFINE_ART_CLASS_TOOL(tool)
Definition: ToolMacros.h:42
void DrawRectangularBox(evdb::View3D *, const Eigen::Vector3f &, const Eigen::Vector3f &, int, int, int) const
art::InputTag fG4ModuleLabel
module label producing sim::SimChannel objects
intermediate_table::const_iterator const_iterator
int GetColor(double x) const
Definition: ColorScale.cxx:126
Particle class.
std::vector< double > fRecoQHigh
high edge of ADC values for drawing raw digits
std::vector< double > fRecoQLow
low edge of ADC values for drawing raw digits
bool isValid() const noexcept
Definition: Handle.h:203
The color scales used by the event display.
double HalfW() const
Definition: OpDetGeo.cxx:52
TPolyLine3D & AddPolyLine3D(int n, int c, int w, int s)
Definition: View3D.cxx:105
bool fShowSimPhotonInfo
Display SimPhoton info in 3D display.
Simulation objects for optical detectors.
art::InputTag fSimPhotonLabel
and for SimPhotons
const evdb::ColorScale & CalQ(geo::SigType_t st) const
geo::Point_t const & GetCenter() const
Definition: OpDetGeo.h:72
std::size_t color(std::string const &procname)
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:180
bool getByLabel(std::string const &label, std::string const &instance, Handle< PROD > &result) const
double HalfH() const
Definition: OpDetGeo.cxx:60
MaybeLogger_< ELseverityLevel::ELsev_success, false > LogDebug
A collection of 3D drawable objects.
TCEvent evt
Definition: DataStructs.cxx:8
void Draw(const art::Event &, evdb::View3D *) const override
OpDetGeo const & OpDetGeoFromOpChannel(unsigned int OpChannel) const
Returns the geo::OpDetGeo object for the given channel number.
art framework interface to geometry description
DrawSimPhoton3D(const fhicl::ParameterSet &pset)
Signal from collection planes.
Definition: geo_types.h:152