LArSoft  v10_04_05
Liquid Argon Software toolkit - https://larsoft.org/
OpFlash3DDrawer_tool.cc
Go to the documentation of this file.
1 
16 
18 
24 
25 #include "TPolyLine3D.h"
26 
27 // Eigen
28 #include <Eigen/Core>
29 
30 namespace evdb_tool {
31 
32  class OpFlash3DDrawer : public I3DDrawer {
33  public:
35 
36  void Draw(const art::Event&, evdb::View3D*) const override;
37 
38  private:
40  const Eigen::Vector3f&,
41  const Eigen::Vector3f&,
42  int,
43  int,
44  int) const;
45  };
46 
48  {
50 
51  if (recoOpt->fDrawOpFlashes == 0) return;
52 
53  // Service recovery
54  auto const clock_data =
56  auto const det_prop =
59 
60  std::vector<geo::PlaneID> planeIDVec;
61 
62  planeIDVec.push_back(geo::PlaneID(0, 0, 0));
63  planeIDVec.push_back(geo::PlaneID(0, 1, 0));
64  planeIDVec.push_back(geo::PlaneID(1, 0, 0));
65  planeIDVec.push_back(geo::PlaneID(1, 1, 0));
66 
68 
69  // This seems like a time waster but we want to get the full color scale for all OpHits... so loops away...
70  std::vector<float> opHitPEVec;
71 
72  // This is almost identically the same for loop we will re-excute below... sigh...
73  for (size_t idx = 0; idx < recoOpt->fOpFlashLabels.size(); idx++) {
74  art::InputTag opFlashProducer = recoOpt->fOpFlashLabels[idx];
75 
76  event.getByLabel(opFlashProducer, opFlashHandle);
77 
78  if (!opFlashHandle.isValid()) continue;
79  if (opFlashHandle->size() == 0) continue;
80 
81  // To get associations we'll need an art ptr vector...
83 
84  for (size_t idx = 0; idx < opFlashHandle->size(); idx++)
85  opFlashVec.push_back(art::Ptr<recob::OpFlash>(opFlashHandle, idx));
86 
87  // Recover the associations to op hits
88  art::FindManyP<recob::OpHit> opHitAssnVec(opFlashVec, event, opFlashProducer);
89 
90  if (opHitAssnVec.size() == 0) continue;
91 
92  // Start the loop over flashes
93  for (const auto& opFlashPtr : opFlashVec) {
94  std::cout << "--> opFlash PE: " << opFlashPtr->TotalPE() << ", Time: " << opFlashPtr->Time()
95  << ", width: " << opFlashPtr->TimeWidth() << ", y/w: " << opFlashPtr->YCenter()
96  << "/" << opFlashPtr->YWidth() << ", Z/w: " << opFlashPtr->ZCenter() << "/"
97  << opFlashPtr->ZWidth() << std::endl;
98  // Make some selections...
99  if (opFlashPtr->TotalPE() < recoOpt->fFlashMinPE) continue;
100  if (opFlashPtr->Time() < recoOpt->fFlashTMin) continue;
101  if (opFlashPtr->Time() > recoOpt->fFlashTMax) continue;
102 
103  // Start by going through the associated OpHits
104  const std::vector<art::Ptr<recob::OpHit>>& opHitVec = opHitAssnVec.at(opFlashPtr.key());
105 
106  for (const auto& opHit : opHitVec)
107  opHitPEVec.push_back(opHit->PE());
108  }
109  }
110 
111  // Do we have any flashes and hits?
112  if (!opHitPEVec.empty()) {
113  // Sorting is good for mind and body...
114  std::sort(opHitPEVec.begin(), opHitPEVec.end());
115 
116  float minTotalPE = opHitPEVec.front();
117  float maxTotalPE = opHitPEVec[0.9 * opHitPEVec.size()];
118 
119  // Now we can set the scaling factor for PE
120  float opHitPEScale((cst->fRecoQHigh[geo::kCollection] - cst->fRecoQLow[geo::kCollection]) /
121  (maxTotalPE - minTotalPE));
122 
123  // We are meant to draw the flashes/hits, so loop over the list of input flashes
124  auto const& wireReadoutGeom = art::ServiceHandle<geo::WireReadout const>()->Get();
125  for (size_t idx = 0; idx < recoOpt->fOpFlashLabels.size(); idx++) {
126  art::InputTag opFlashProducer = recoOpt->fOpFlashLabels[idx];
127 
128  event.getByLabel(opFlashProducer, opFlashHandle);
129 
130  if (!opFlashHandle.isValid()) continue;
131  if (opFlashHandle->size() == 0) continue;
132 
133  // To get associations we'll need an art ptr vector...
135 
136  for (size_t idx = 0; idx < opFlashHandle->size(); idx++)
137  opFlashVec.push_back(art::Ptr<recob::OpFlash>(opFlashHandle, idx));
138 
139  // Recover the associations to op hits
140  art::FindManyP<recob::OpHit> opHitAssnVec(opFlashVec, event, opFlashProducer);
141 
142  if (opHitAssnVec.size() == 0) continue;
143 
144  // Start the loop over flashes
145  for (const auto& opFlashPtr : opFlashVec) {
146  // Make some selections...
147  if (opFlashPtr->TotalPE() < recoOpt->fFlashMinPE) continue;
148  if (opFlashPtr->Time() < recoOpt->fFlashTMin) continue;
149  if (opFlashPtr->Time() > recoOpt->fFlashTMax) continue;
150 
151  // Start by going through the associated OpHits
152  const std::vector<art::Ptr<recob::OpHit>> opHitVec = opHitAssnVec.at(opFlashPtr.key());
153 
154  // We use the flash time to give us an x position (for now... will
155  // need a better way eventually)
156  float flashTick = opFlashPtr->Time() / sampling_rate(clock_data) * 1e3 +
157  det_prop.GetXTicksOffset(planeIDVec[idx]);
158  float flashWidth = opFlashPtr->TimeWidth() / sampling_rate(clock_data) * 1e3 +
159  det_prop.GetXTicksOffset(planeIDVec[idx]);
160 
161  // Now convert from time to distance...
162  float flashXpos = det_prop.ConvertTicksToX(flashTick, planeIDVec[idx]);
163  float flashXWid = det_prop.ConvertTicksToX(flashWidth, planeIDVec[idx]);
164 
165  // Loop through the OpHits here
166  for (const auto& opHit : opHitVec) {
167  unsigned int opChannel = opHit->OpChannel();
168  const geo::OpDetGeo& opHitGeo = wireReadoutGeom.OpDetGeoFromOpChannel(opChannel);
169  const geo::Point_t& opHitPos = opHitGeo.GetCenter();
170  float zWidth = opHitGeo.HalfW();
171  float yWidth = opHitGeo.HalfH();
172 
173  Eigen::Vector3f opHitLo(
174  opHitPos.X() - flashXWid, opHitPos.Y() - yWidth, opHitPos.Z() - zWidth);
175  Eigen::Vector3f opHitHi(
176  opHitPos.X() + flashXWid, opHitPos.Y() + yWidth, opHitPos.Z() + zWidth);
177 
178  // Temporary kludge...
179  flashXpos = opHitPos.X();
180 
181  float peFactor = cst->fRecoQLow[geo::kCollection] +
182  opHitPEScale * std::min(maxTotalPE, float(opHit->PE()));
183 
184  int chargeColorIdx = cst->CalQ(geo::kCollection).GetColor(peFactor);
185 
186  DrawRectangularBox(view, opHitLo, opHitHi, chargeColorIdx, 2, 1);
187  }
188 
189  std::cout << " == flashtick: " << flashTick << ", flashwidth: " << flashWidth
190  << ", flashXpos: " << flashXpos << ", wid: " << flashXWid
191  << ", opHitPEScale: " << opHitPEScale << std::endl;
192 
193  Eigen::Vector3f coordsLo(flashXpos - flashXWid,
194  opFlashPtr->YCenter() - opFlashPtr->YWidth(),
195  opFlashPtr->ZCenter() - opFlashPtr->ZWidth());
196  Eigen::Vector3f coordsHi(flashXpos + flashXWid,
197  opFlashPtr->YCenter() + opFlashPtr->YWidth(),
198  opFlashPtr->ZCenter() + opFlashPtr->ZWidth());
199 
200  DrawRectangularBox(view, coordsLo, coordsHi, kRed, 2, 1);
201  }
202  }
203  }
204  }
205 
207  const Eigen::Vector3f& coordsLo,
208  const Eigen::Vector3f& coordsHi,
209  int color,
210  int width,
211  int style) const
212  {
213  TPolyLine3D& top = view->AddPolyLine3D(5, color, width, style);
214  top.SetPoint(0, coordsLo[0], coordsHi[1], coordsLo[2]);
215  top.SetPoint(1, coordsHi[0], coordsHi[1], coordsLo[2]);
216  top.SetPoint(2, coordsHi[0], coordsHi[1], coordsHi[2]);
217  top.SetPoint(3, coordsLo[0], coordsHi[1], coordsHi[2]);
218  top.SetPoint(4, coordsLo[0], coordsHi[1], coordsLo[2]);
219 
220  TPolyLine3D& side = view->AddPolyLine3D(5, color, width, style);
221  side.SetPoint(0, coordsHi[0], coordsHi[1], coordsLo[2]);
222  side.SetPoint(1, coordsHi[0], coordsLo[1], coordsLo[2]);
223  side.SetPoint(2, coordsHi[0], coordsLo[1], coordsHi[2]);
224  side.SetPoint(3, coordsHi[0], coordsHi[1], coordsHi[2]);
225  side.SetPoint(4, coordsHi[0], coordsHi[1], coordsLo[2]);
226 
227  TPolyLine3D& side2 = view->AddPolyLine3D(5, color, width, style);
228  side2.SetPoint(0, coordsLo[0], coordsHi[1], coordsLo[2]);
229  side2.SetPoint(1, coordsLo[0], coordsLo[1], coordsLo[2]);
230  side2.SetPoint(2, coordsLo[0], coordsLo[1], coordsHi[2]);
231  side2.SetPoint(3, coordsLo[0], coordsHi[1], coordsHi[2]);
232  side2.SetPoint(4, coordsLo[0], coordsHi[1], coordsLo[2]);
233 
234  TPolyLine3D& bottom = view->AddPolyLine3D(5, color, width, style);
235  bottom.SetPoint(0, coordsLo[0], coordsLo[1], coordsLo[2]);
236  bottom.SetPoint(1, coordsHi[0], coordsLo[1], coordsLo[2]);
237  bottom.SetPoint(2, coordsHi[0], coordsLo[1], coordsHi[2]);
238  bottom.SetPoint(3, coordsLo[0], coordsLo[1], coordsHi[2]);
239  bottom.SetPoint(4, coordsLo[0], coordsLo[1], coordsLo[2]);
240  }
241 
243 }
#define DEFINE_ART_CLASS_TOOL(tool)
Definition: ToolMacros.h:42
std::vector< art::InputTag > fOpFlashLabels
module labels that produced events
void DrawRectangularBox(evdb::View3D *, const Eigen::Vector3f &, const Eigen::Vector3f &, int, int, int) const
OpFlash3DDrawer(const fhicl::ParameterSet &)
Point_t const & GetCenter() const
Definition: OpDetGeo.h:71
The data type to uniquely identify a Plane.
Definition: geo_types.h:364
void Draw(const art::Event &, evdb::View3D *) const override
cout<< "Opened file "<< fin<< " ixs= "<< ixs<< endl;if(ixs==0) hhh=(TH1F *) fff-> Get("h1")
Definition: AddMC.C:8
int GetColor(double x) const
Definition: ColorScale.cxx:126
double fFlashTMin
Minimal time for a flash to be displayed.
std::vector< double > fRecoQHigh
high edge of ADC values for drawing raw digits
double fFlashTMax
Maximum time for a flash to be displayed.
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:48
TPolyLine3D & AddPolyLine3D(int n, int c, int w, int s)
Definition: View3D.cxx:105
void push_back(Ptr< U > const &p)
Definition: PtrVector.h:435
const evdb::ColorScale & CalQ(geo::SigType_t st) const
double fFlashMinPE
Minimal PE for a flash to be displayed.
Encapsulate the geometry of an optical detector.
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
double HalfH() const
Definition: OpDetGeo.cxx:56
A collection of 3D drawable objects.
double sampling_rate(DetectorClocksData const &data)
Returns the period of the TPC readout electronics clock.
Event finding and building.
Signal from collection planes.
Definition: geo_types.h:148