LArSoft  v06_85_00
Liquid Argon Software toolkit - http://larsoft.org/
SpacePointHit3DBuilder_tool.cc
Go to the documentation of this file.
1 
8 // Framework Includes
10 #include "cetlib/search_path.h"
11 #include "cetlib/cpu_timer.h"
13 
15 
16 // LArSoft includes
22 #include "larevt/CalibrationDBI/Interface/ChannelStatusService.h"
23 #include "larevt/CalibrationDBI/Interface/ChannelStatusProvider.h"
24 
25 // std includes
26 #include <string>
27 #include <functional>
28 #include <iostream>
29 #include <memory>
30 
31 //------------------------------------------------------------------------------------------------------------------------------------------
32 // implementation follows
33 
34 namespace lar_cluster3d {
35 
39 class SpacePointHit3DBuilder : virtual public IHit3DBuilder
40 {
41 public:
47  explicit SpacePointHit3DBuilder(fhicl::ParameterSet const &pset);
48 
53 
54  void configure(const fhicl::ParameterSet&) override;
55 
62  void Hit3DBuilder(const art::Event &evt, reco::HitPairList& hitPairList, RecobHitToPtrMap&) const override;
63 
67  float getTimeToExecute(IHit3DBuilder::TimeValues index) const override {return m_timeVector.at(index);}
68 
69 private:
70 
71  using Hit2DVector = std::vector<reco::ClusterHit2D>;
72 
77 
79  mutable std::vector<float> m_timeVector;
80 
81  // Get instances of the primary data structures needed
83 
84  const detinfo::DetectorProperties* m_detector; //< Pointer to the detector properties
85 };
86 
88 {
89  this->configure(pset);
90 }
91 
92 //------------------------------------------------------------------------------------------------------------------------------------------
93 
95 {
96 }
97 
98 //------------------------------------------------------------------------------------------------------------------------------------------
99 
101 {
102  m_spacePointTag = pset.get<art::InputTag>("SpacePointTag");
103  m_enableMonitoring = pset.get<bool> ("EnableMonitoring", true);
104 
105  m_detector = lar::providerFrom<detinfo::DetectorPropertiesService>();
106 }
107 
108 void SpacePointHit3DBuilder::Hit3DBuilder(const art::Event& evt, reco::HitPairList& hitPairList, RecobHitToPtrMap& recobHitToArtPtrMap) const
109 {
110  m_timeVector.resize(NUMTIMEVALUES, 0.);
111 
112  cet::cpu_timer theClockMakeHits;
113 
114  if (m_enableMonitoring) theClockMakeHits.start();
115 
120  // Start by recovering the associations between space points and hits
122  evt.getByLabel(m_spacePointTag, hitSpacePointAssnsHandle);
123 
124  if (!hitSpacePointAssnsHandle.isValid()) return;
125 
126  // First step is to loop through and get a mapping between space points and associated hits
127  // and, importantly, a list of unique hits (and mapping between art ptr and hit)
128  using SpacePointHitVecMap = std::map<const recob::SpacePoint*, std::vector<const recob::Hit*>>;
129  using RecobHitSet = std::set<const recob::Hit*>;
130 
131  SpacePointHitVecMap spacePointHitVecMap;
132  RecobHitSet recobHitSet;
133 
134  for(auto& assnPair : *hitSpacePointAssnsHandle)
135  {
136  const art::Ptr<recob::SpacePoint> spacePoint = assnPair.second;
137  const art::Ptr<recob::Hit>& recobHit = assnPair.first;
138 
139  spacePointHitVecMap[spacePoint.get()].push_back(recobHit.get());
140  recobHitSet.insert(recobHit.get());
141  recobHitToArtPtrMap[recobHit.get()] = recobHit;
142  }
143 
144  // We'll want to correct the hit times for the plane offsets
145  // (note this is already taken care of when converting to position)
146  std::map<size_t, double> planeOffsetMap;
147 
148  planeOffsetMap[0] = 0.;
149  planeOffsetMap[1] = m_detector->GetXTicksOffset(1, 0, 0)-m_detector->GetXTicksOffset(0, 0, 0);
150  planeOffsetMap[2] = m_detector->GetXTicksOffset(2, 0, 0)-m_detector->GetXTicksOffset(0, 0, 0);
151 
152  // We need temporary mapping from recob::Hit's to our 2D hits
153  using RecobHitTo2DHitMap = std::map<const recob::Hit*,const reco::ClusterHit2D*>;
154 
155  RecobHitTo2DHitMap recobHitTo2DHitMap;
156 
157  // Set the size of the container for our hits
158  m_clusterHit2DMasterVec.clear();
159  m_clusterHit2DMasterVec.reserve(recobHitSet.size());
160 
161  // Now go throught the list of unique hits and create the 2D hits we'll use
162  for(auto& recobHit : recobHitSet)
163  {
164  const geo::WireID& hitWireID(recobHit->WireID());
165 
166  double hitPeakTime(recobHit->PeakTime() - planeOffsetMap[hitWireID.Plane]);
167  double xPosition(m_detector->ConvertTicksToX(recobHit->PeakTime(), hitWireID.Plane, hitWireID.TPC, hitWireID.Cryostat));
168 
169  m_clusterHit2DMasterVec.emplace_back(0, 0., 0., xPosition, hitPeakTime, *recobHit);
170 
171  recobHitTo2DHitMap[recobHit] = &m_clusterHit2DMasterVec.back();
172  }
173 
174  // Now we can go through the space points and build our 3D hits
175  for(auto& pointPair : spacePointHitVecMap)
176  {
177  const recob::SpacePoint* spacePoint = pointPair.first;
178  const std::vector<const recob::Hit*>& recobHitVec = pointPair.second;
179 
180  if (recobHitVec.size() != 3)
181  {
182  std::cout << "************>>>>>> do not have 3 hits associated to space point! " << recobHitVec.size() << " ***************" << std::endl;
183  continue;
184  }
185 
186  std::vector<const reco::ClusterHit2D*> hit2DVec(recobHitVec.size());
187 
188  for(const auto& recobHit : recobHitVec)
189  {
190  const reco::ClusterHit2D* hit2D = recobHitTo2DHitMap.at(recobHit);
191 
192  hit2DVec[hit2D->getHit().WireID().Plane] = hit2D;
193  }
194 
195  // Weighted average, delta, sigmas, chisquare, kitchen sink, refrigerator for beer, etc.
196  float avePeakTime(0.);
197  float weightSum(0.);
198  float sigmaPeakTime(0.);
199 
200  for(const auto& hit2D : hit2DVec)
201  {
202  float hitSigma = hit2D->getHit().RMS();
203  float weight = 1. / (hitSigma * hitSigma);
204 
205  avePeakTime += weight * hit2D->getTimeTicks();
206  weightSum += weight;
207  sigmaPeakTime += hitSigma * hitSigma;
208  }
209 
210  avePeakTime /= weightSum;
211  sigmaPeakTime = std::sqrt(sigmaPeakTime);
212 
213  // Now form the hit chi square
214  float hitChiSquare(0.);
215 
216  for(const auto& hit2D : hit2DVec)
217  {
218  float hitSigma = hit2D->getHit().RMS();
219 
220  hitChiSquare += (hit2D->getTimeTicks() - avePeakTime) / (hitSigma * hitSigma);
221  }
222 
223  // The x position is a weighted sum but the y-z position is simply the average
224  float position[] = { float(spacePoint->XYZ()[0]), float(spacePoint->XYZ()[1]), float(spacePoint->XYZ()[2])};
225  float totalCharge = hit2DVec[0]->getHit().Integral() + hit2DVec[1]->getHit().Integral() + hit2DVec[2]->getHit().Integral();
226 
227  reco::ClusterHit2DVec hitVector;
228 
229  hitVector.resize(3,NULL);
230 
231  // Make sure we have the hits
232  hitVector.at(hit2DVec[0]->getHit().WireID().Plane) = hit2DVec[0];
233  hitVector.at(hit2DVec[1]->getHit().WireID().Plane) = hit2DVec[1];
234  hitVector.at(hit2DVec[2]->getHit().WireID().Plane) = hit2DVec[2];
235 
236  // And get the wire IDs
237  std::vector<geo::WireID> wireIDVec = {geo::WireID(0,0,geo::kU,0), geo::WireID(0,0,geo::kV,0), geo::WireID(0,0,geo::kW,0)};
238 
239  for(const auto& hit : hitVector)
240  {
241  wireIDVec[hit->getHit().WireID().Plane] = hit->getHit().WireID();
242 
243  if (hit->getStatusBits() & reco::ClusterHit2D::USEDINTRIPLET) hit->setStatusBit(reco::ClusterHit2D::SHAREDINTRIPLET);
244 
245  hit->setStatusBit(reco::ClusterHit2D::USEDINTRIPLET);
246  }
247 
248  unsigned int statusBits(0x7);
249 
250  // For compiling at the moment
251  std::vector<float> hitDelTSigVec = {0.,0.,0.};
252 
253  hitDelTSigVec[0] = std::fabs(hitVector[0]->getTimeTicks() - 0.5 * (hitVector[1]->getTimeTicks() + hitVector[2]->getTimeTicks()));
254  hitDelTSigVec[1] = std::fabs(hitVector[1]->getTimeTicks() - 0.5 * (hitVector[2]->getTimeTicks() + hitVector[0]->getTimeTicks()));
255  hitDelTSigVec[2] = std::fabs(hitVector[2]->getTimeTicks() - 0.5 * (hitVector[0]->getTimeTicks() + hitVector[1]->getTimeTicks()));
256 
257  float deltaPeakTime = *std::min_element(hitDelTSigVec.begin(),hitDelTSigVec.end());
258 
259  // Create the 3D cluster hit
260  hitPairList.emplace_back(new reco::ClusterHit3D(0,
261  statusBits,
262  position,
263  totalCharge,
264  avePeakTime,
265  deltaPeakTime,
266  sigmaPeakTime,
267  hitChiSquare,
268  0.,
269  0.,
270  hitVector,
271  hitDelTSigVec,
272  wireIDVec));
273  }
274 
275  if (m_enableMonitoring)
276  {
277  theClockMakeHits.stop();
278 
279  m_timeVector[BUILDTHREEDHITS] = theClockMakeHits.accumulated_real_time();
280  }
281 
282  mf::LogDebug("Cluster3D") << ">>>>> 3D hit building done, found " << hitPairList.size() << " 3D Hits" << std::endl;
283 
284  return;
285 }
286 
287 //------------------------------------------------------------------------------------------------------------------------------------------
288 //------------------------------------------------------------------------------------------------------------------------------------------
289 
291 } // namespace lar_cluster3d
const detinfo::DetectorProperties * m_detector
#define DEFINE_ART_CLASS_TOOL(tool)
Definition: ToolMacros.h:45
art::InputTag m_spacePointTag
Data members to follow.
Planes which measure V.
Definition: geo_types.h:77
geo::WireID WireID() const
Initial tdc tick for hit.
Definition: Hit.h:234
float getTimeToExecute(IHit3DBuilder::TimeValues index) const override
If monitoring, recover the time to execute a particular function.
Declaration of signal hit object.
std::vector< reco::ClusterHit2D > Hit2DVector
std::list< std::unique_ptr< reco::ClusterHit3D >> HitPairList
Definition: Cluster3D.h:319
bool isValid() const
Definition: Handle.h:190
Planes which measure U.
Definition: geo_types.h:76
T get(std::string const &key) const
Definition: ParameterSet.h:231
const recob::Hit & getHit() const
Definition: Cluster3D.h:73
SpacePointHit3DBuilder class definiton.
TimeValues
enumerate the possible values for time checking if monitoring timing
Definition: IHit3DBuilder.h:57
std::map< const recob::Hit *, art::Ptr< recob::Hit >> RecobHitToPtrMap
Defines a structure mapping art representation to internal.
Definition: IHit3DBuilder.h:44
PlaneID_t Plane
Index of the plane within its TPC.
Definition: geo_types.h:258
IHit3DBuilder interface class definiton.
Definition: IHit3DBuilder.h:26
Detector simulation of raw signals on wires.
This provides an art tool interface definition for tools which construct 3D hits used in 3D clusterin...
std::vector< const reco::ClusterHit2D * > ClusterHit2DVec
Definition: Cluster3D.h:85
virtual double ConvertTicksToX(double ticks, int p, int t, int c) const =0
double weight
Definition: plottest35.C:25
const double * XYZ() const
Definition: SpacePoint.h:64
Utility object to perform functions of association.
T const * get() const
Definition: Ptr.h:321
bool getByLabel(std::string const &label, std::string const &productInstanceName, Handle< PROD > &result) const
Definition: DataViewImpl.h:344
SpacePointHit3DBuilder(fhicl::ParameterSet const &pset)
Constructor.
void Hit3DBuilder(const art::Event &evt, reco::HitPairList &hitPairList, RecobHitToPtrMap &) const override
Given a set of recob hits, run DBscan to form 3D clusters.
MaybeLogger_< ELseverityLevel::ELsev_success, false > LogDebug
Planes which measure W (third view for Bo, MicroBooNE, etc).
Definition: geo_types.h:78
recob::tracking::Plane Plane
Definition: TrackState.h:17
art framework interface to geometry description
void configure(const fhicl::ParameterSet &) override
Interface for configuring the particular algorithm tool.
virtual double GetXTicksOffset(int p, int t, int c) const =0