LArSoft  v07_13_02
Liquid Argon Software toolkit - http://larsoft.org/
Cluster3D.cxx
Go to the documentation of this file.
1 //
3 // \brief Definition of 3D cluster object for LArSoft
4 //
5 // \author usher@slac.stanford.edu
6 //
8 
9 #include <iostream>
10 #include <iomanip>
11 
14 
16 
17 namespace reco{
18 
19 ClusterHit2D::ClusterHit2D() : m_statusBits(0),
20  m_docaToAxis(9999.),
21  m_arcLenToPoca(0.),
22  m_xPosition(0.),
23  m_timeTicks(0.),
24  m_hit(nullptr) {}
25 
26 ClusterHit2D::ClusterHit2D(unsigned statusBits,
27  float doca,
28  float poca,
29  float xPosition,
30  float timeTicks,
31  const recob::Hit& hit) :
32  m_statusBits(statusBits),
33  m_docaToAxis(doca),
34  m_arcLenToPoca(poca),
35  m_xPosition(xPosition),
36  m_timeTicks(timeTicks),
37  m_hit(&hit) {}
38 
39 
40 std::ostream& operator<< (std::ostream& o, const ClusterHit2D& c)
41 {
42  o << c.getHit();
43 
44  return o;
45 }
46 
47 bool operator < (const ClusterHit2D & a, const ClusterHit2D & b)
48 {
49  return a.getHit() < b.getHit();
50 }
51 
52 
53 ClusterHit3D::ClusterHit3D() : m_id(std::numeric_limits<size_t>::max()),
54  m_statusBits(0),
55  m_position{0.,0.,0.},
56  m_totalCharge(0.),
57  m_avePeakTime(-1.),
58  m_deltaPeakTime(0.),
59  m_sigmaPeakTime(0.),
60  m_hitChiSquare(0.),
61  m_docaToAxis(0.),
62  m_arclenToPoca(0.)
63 {
64  m_hitDelTSigVec.clear();
65  m_wireIDVector.clear();
66  m_hitVector.clear();
67 
68  m_hitDelTSigVec.resize(3, 0.);
69  m_wireIDVector.resize(3, geo::WireID());
70  m_hitVector.resize(3, NULL);
71 }
72 
74  unsigned int statusBits,
75  const float* position,
76  float totalCharge,
77  float avePeakTime,
78  float deltaPeakTime,
79  float sigmaPeakTime,
80  float hitChiSquare,
81  float docaToAxis,
82  float arclenToPoca,
83  const ClusterHit2DVec& hitVec,
84  const std::vector<float>& hitDelTSigVec,
85  const std::vector<geo::WireID>& wireIDs) :
86  m_id(id),
87  m_statusBits(statusBits),
88  m_position{position[0],position[1],position[2]},
89  m_totalCharge(totalCharge),
90  m_avePeakTime(avePeakTime),
91  m_deltaPeakTime(deltaPeakTime),
92  m_sigmaPeakTime(sigmaPeakTime),
93  m_hitChiSquare(hitChiSquare),
94  m_docaToAxis(docaToAxis),
95  m_arclenToPoca(arclenToPoca),
96  m_hitDelTSigVec(hitDelTSigVec),
97  m_wireIDVector(wireIDs)
98 {
99  m_hitVector.resize(3,NULL);
100  std::copy(hitVec.begin(),hitVec.end(),m_hitVector.begin());
101 }
102 
104 {
105  m_id = toCopy.m_id;
106  m_statusBits = toCopy.m_statusBits;
107  m_position[0] = toCopy.m_position[0];
108  m_position[1] = toCopy.m_position[1];
109  m_position[2] = toCopy.m_position[2];
110  m_totalCharge = toCopy.m_totalCharge;
111  m_avePeakTime = toCopy.m_avePeakTime;
115  m_docaToAxis = toCopy.m_docaToAxis;
117  m_hitVector = toCopy.m_hitVector;
120 }
121 
123  unsigned int statusBits,
124  const float* position,
125  float totalCharge,
126  float avePeakTime,
127  float deltaPeakTime,
128  float sigmaPeakTime,
129  float hitChiSquare,
130  float docaToAxis,
131  float arclenToPoca,
132  const ClusterHit2DVec& hitVec,
133  const std::vector<float>& hitDelTSigVec,
134  const std::vector<geo::WireID>& wireIDs)
135 {
136  m_id = id;
137  m_statusBits = statusBits;
138  m_position[0] = position[0];
139  m_position[1] = position[1];
140  m_position[2] = position[2];
141  m_totalCharge = totalCharge;
142  m_avePeakTime = avePeakTime;
143  m_deltaPeakTime = deltaPeakTime;
144  m_sigmaPeakTime = sigmaPeakTime;
145  m_hitChiSquare = hitChiSquare;
146  m_docaToAxis = docaToAxis;
147  m_arclenToPoca = arclenToPoca;
148  m_hitVector = hitVec;
149  m_hitDelTSigVec = hitDelTSigVec;
150  m_wireIDVector = wireIDs;
151 
152  return;
153 }
154 
155 void ClusterHit3D::setWireID(const geo::WireID& wid) const
156 {
157  m_wireIDVector[wid.Plane] = wid;
158 }
159 
160 std::ostream& operator<< (std::ostream& o, const ClusterHit3D& c)
161 {
162  o << "ClusterHit3D has " << c.getHits().size() << " hits associated";
163 
164  return o;
165 }
166 
167  //bool operator < (const ClusterHit3D & a, const ClusterHit3D & b)
168  //{
169  // if (a.m_position[2] != b.m_position[2]) return a.m_position[2] < b.m_position[2];
170  // else return a.m_position[0] < b.m_position[0];
171  //}
172 
174  m_svdOK(false),
175  m_numHitsUsed(0),
176  m_eigenValues{0.,0.,0.},
177  m_avePosition{0.,0.,0.},
178  m_aveHitDoca(9999.)
179 {}
180 
181 PrincipalComponents::PrincipalComponents(bool ok, int nHits, const float* eigenValues, const EigenVectors& eigenVecs, const float* avePos, const float aveHitDoca) :
182  m_svdOK(ok),
183  m_numHitsUsed(nHits),
184  m_eigenVectors(eigenVecs),
185  m_aveHitDoca(aveHitDoca)
186 {
187  m_eigenValues[0] = eigenValues[0];
188  m_eigenValues[1] = eigenValues[1];
189  m_eigenValues[2] = eigenValues[2];
190  m_avePosition[0] = avePos[0];
191  m_avePosition[1] = avePos[1];
192  m_avePosition[2] = avePos[2];
193 }
194 
195 void PrincipalComponents::flipAxis(size_t axisDir)
196 {
197  std::vector<float>& axis = m_eigenVectors.at(axisDir);
198 
199  for(auto& val : axis) val *= -1.;
200 
201  return;
202 }
203 
204 std::ostream& operator << (std::ostream & o, const PrincipalComponents& a)
205 {
206  if (a.m_svdOK)
207  {
208  o << std::setiosflags(std::ios::fixed) << std::setprecision(2);
209  o << " PCAxis ID run with " << a.m_numHitsUsed << " space points" << std::endl;
210  o << " - center position: " << std::setw(6) << a.m_avePosition[0] << ", " << a.m_avePosition[1] << ", " << a.m_avePosition[2] << std::endl;
211  o << " - eigen values: " << std::setw(8) << std::right << a.m_eigenValues[0] << ", "
212  << a.m_eigenValues[1] << ", " << a.m_eigenValues[2] << std::endl;
213  o << " - average doca: " << a.m_aveHitDoca << std::endl;
214  o << " - Principle axis: " << std::setw(7) << std::setprecision(4) << a.m_eigenVectors[0][0] << ", " << a.m_eigenVectors[0][1] << ", " << a.m_eigenVectors[0][2] << std::endl;
215  o << " - second axis: " << std::setw(7) << std::setprecision(4) << a.m_eigenVectors[1][0] << ", " << a.m_eigenVectors[1][1] << ", " << a.m_eigenVectors[1][2] << std::endl;
216  o << " - third axis: " << std::setw(7) << std::setprecision(4) << a.m_eigenVectors[2][0] << ", " << a.m_eigenVectors[2][1] << ", " << a.m_eigenVectors[2][2] << std::endl;
217  }
218  else
219  o << " Principal Components Axis is not valid" << std::endl;
220 
221  return o;
222 }
223 
225 {
226  if (a.m_svdOK && b.m_svdOK)
227  return a.m_eigenValues[0] > b.m_eigenValues[0];
228 
229  return false; //They are equal
230 }
231 
232 Cluster3D::Cluster3D() : m_statusBits(0),
233  m_pcaResults(PrincipalComponents()),
234  m_totalCharge(0.),
235  m_startPosition{0.,0.,0.},
236  m_endPosition{0.,0.,0.},
237  m_clusterIdx(0)
238 {}
239 
240 Cluster3D::Cluster3D(unsigned statusBits,
241  const PrincipalComponents& pcaResults,
242  float totalCharge,
243  const float* startPosition,
244  const float* endPosition,
245  int idx) :
246  m_statusBits(statusBits),
247  m_pcaResults(pcaResults),
248  m_totalCharge(totalCharge),
249  m_startPosition{startPosition[0],startPosition[1],startPosition[2]},
250  m_endPosition{endPosition[0],endPosition[1],endPosition[2]},
251  m_clusterIdx(idx)
252  {}
253 
254 //----------------------------------------------------------------------
255 // Addition operator.
256 //
258 {
259 /*
260  // throw exception if the clusters are not from the same plane
261  if( a.View() != this->View() )
262  throw cet::exception("Cluster+operator") << "Attempting to sum clusters from "
263  << "different views is not allowed\n";
264 
265  // check the start and end positions - for now the
266  // smallest wire number means start position, largest means end position
267  std::vector<float> astart(a.StartPos());
268  std::vector<float> aend (a.EndPos() );
269  std::vector<float> start(StartPos());
270  std::vector<float> end (EndPos() );
271  std::vector<float> sigstart(SigmaStartPos());
272  std::vector<float> sigend (SigmaEndPos() );
273 
274  if(astart[0] < fStartPos[0]){
275  start = astart;
276  sigstart = a.SigmaStartPos();
277  }
278 
279  if(aend[0] > fEndPos[0]){
280  end = aend;
281  sigend = a.SigmaEndPos();
282  }
283 
284  //take weighted mean in obtaining average slope and differential charge,
285  //based on total charge each cluster
286  float dtdw = ((this->Charge()*dTdW()) + (a.Charge()*a.dTdW()))/(this->Charge() + a.Charge());
287  float dqdw = ((this->Charge()*dQdW()) + (a.Charge()*a.dQdW()))/(this->Charge() + a.Charge());
288 
289  //hits.sort();//sort the PtrVector to organize Hits of new Cluster
290  float sigdtdw = TMath::Max(SigmadTdW(), a.SigmadTdW());
291  float sigdqdw = TMath::Max(SigmadQdW(), a.SigmadQdW());
292 
293  Cluster sum(//hits,
294  start[0], sigstart[0],
295  start[1], sigstart[1],
296  end[0], sigend[0],
297  end[1], sigend[1],
298  dtdw, sigdtdw,
299  dqdw, sigdqdw,
300  this->Charge() + a.Charge(),
301  this->View(),
302  ID());
303 */
304  //return sum;
305  return a;
306 }
307 
308 //----------------------------------------------------------------------
309 // ostream operator.
310 //
311 std::ostream& operator<< (std::ostream& o, const Cluster3D& c)
312 {
313  o << std::setiosflags(std::ios::fixed) << std::setprecision(2);
314  o << "Cluster ID " << std::setw(5) << std::right << c.getClusterIdx();
315 // << " : View = " << std::setw(3) << std::right << c.View()
316 // << " StartWire = " << std::setw(7) << std::right << c.StartPos()[0]
317 // << " EndWire = " << std::setw(7) << std::right << c.EndPos()[0]
318 // << " StartTime = " << std::setw(9) << std::right << c.StartPos()[1]
319 // << " EndTime = " << std::setw(9) << std::right << c.EndPos()[1]
320 // << " dTdW = " << std::setw(9) << std::right << c.dTdW()
321 // << " dQdW = " << std::setw(9) << std::right << c.dQdW()
322 // << " Charge = " << std::setw(10) << std::right << c.Charge();
323 
324  return o;
325  }
326 
327 
328 //----------------------------------------------------------------------
329 // < operator.
330 //
331 bool operator < (const Cluster3D & a, const Cluster3D & b)
332 {
333 /*
334  if(a.View() != b.View())
335  return a.View() < b.View();
336  if(a.ID() != b. ID())
337  return a.ID() < b.ID();
338  if(a.StartPos()[0] != b.StartPos()[0])
339  return a.StartPos()[0] < b.StartPos()[0];
340  if(a.EndPos()[0] != b.EndPos()[0])
341  return a.EndPos()[0] < b.EndPos()[0];
342 */
343  if (a.getStartPosition()[2] < b.getStartPosition()[2]) return true;
344 
345  return false; //They are equal
346 }
347 
348 //------------------------------------------------------------------------------------------------------------------------------------------
349 
351 {
356  const recob::Hit& hit = clusterHit->getHit();
357 
358  // Need to keep track of stuff so we can form cluster
359  if (hit.WireID().Wire < m_startWire)
360  {
361  m_startWire = hit.WireID().Wire;
362  m_startTime = hit.PeakTimeMinusRMS();
363  m_sigmaStartTime = hit.SigmaPeakTime();
364  }
365 
366  if (hit.WireID().Wire > m_endWire)
367  {
368  m_endWire = hit.WireID().Wire;
369  m_endTime = hit.PeakTimePlusRMS();
370  m_sigmaEndTime = hit.SigmaPeakTime();
371  }
372 
373  m_totalCharge += hit.Integral();
374  m_plane = hit.WireID().Plane;
375  m_view = hit.View();
376 
377  m_hitVector.push_back(clusterHit);
378 
379  return;
380 }
381 
382 }// namespace
383 
void setWireID(const geo::WireID &wid) const
Definition: Cluster3D.cxx:155
bool m_svdOK
SVD Decomposition was successful.
Definition: Cluster3D.h:215
Cluster3D operator+(Cluster3D)
Definition: Cluster3D.cxx:257
size_t m_id
"id" of this hit (useful for indexing)
Definition: Cluster3D.h:189
constexpr auto const & right(const_AssnsIter< L, R, D, Dir > const &a, const_AssnsIter< L, R, D, Dir > const &b)
Definition: AssnsIter.h:112
float m_hitChiSquare
Hit ChiSquare relative to the average time.
Definition: Cluster3D.h:196
void flipAxis(size_t axis)
Definition: Cluster3D.cxx:195
float m_arclenToPoca
arc length along axis to DOCA point
Definition: Cluster3D.h:198
double m_aveHitDoca
Average doca of hits used in PCA.
Definition: Cluster3D.h:220
geo::WireID WireID() const
Initial tdc tick for hit.
Definition: Hit.h:234
Declaration of signal hit object.
float m_deltaPeakTime
Largest delta peak time of associated recob::Hits.
Definition: Cluster3D.h:194
const float * getStartPosition() const
Definition: Cluster3D.h:267
unsigned m_statusBits
Volatile status information of this 3D hit.
Definition: Cluster3D.h:43
STL namespace.
float Integral() const
Integral under the calibrated signal waveform of the hit, in tick x ADC units.
Definition: Hit.h:225
geo::View_t View() const
View for the plane of the hit.
Definition: Hit.h:233
WireID_t Wire
Index of the wire within its plane.
Definition: geo_types.h:313
float m_docaToAxis
DOCA of hit at POCA to associated cluster axis.
Definition: Cluster3D.h:44
friend bool operator<(const ClusterHit2D &a, const ClusterHit2D &b)
Definition: Cluster3D.cxx:47
friend bool operator<(const Cluster3D &a, const Cluster3D &b)
Definition: Cluster3D.cxx:331
float m_sigmaPeakTime
Quad sum of peak time sigmas.
Definition: Cluster3D.h:195
Int_t max
Definition: plot.C:27
const recob::Hit * m_hit
Hit we are augmenting.
Definition: Cluster3D.h:48
float m_avePeakTime
Average peak time of all associated recob::Hits.
Definition: Cluster3D.h:193
float m_arcLenToPoca
arc length to POCA along cluster axis
Definition: Cluster3D.h:45
float m_totalCharge
Total charge in the cluster.
Definition: Cluster3D.h:251
float m_docaToAxis
DOCA to the associated cluster axis.
Definition: Cluster3D.h:197
float m_timeTicks
The time (in ticks) for this hit.
Definition: Cluster3D.h:47
std::vector< geo::WireID > m_wireIDVector
Wire ID&#39;s for the planes making up hit.
Definition: Cluster3D.h:201
const recob::Hit & getHit() const
Definition: Cluster3D.h:73
float m_endPosition[3]
"end" position for cluster
Definition: Cluster3D.h:253
float m_totalCharge
Sum of charges of all associated recob::Hits.
Definition: Cluster3D.h:192
std::vector< std::vector< float > > EigenVectors
Definition: Cluster3D.h:209
PlaneID_t Plane
Index of the plane within its TPC.
Definition: geo_types.h:258
float PeakTimeMinusRMS(float sigmas=+1.) const
Returns a time sigmas RMS away from the peak time.
Definition: Hit.h:240
Detector simulation of raw signals on wires.
float m_eigenValues[3]
Eigen values from SVD decomposition.
Definition: Cluster3D.h:217
std::vector< const reco::ClusterHit2D * > ClusterHit2DVec
Definition: Cluster3D.h:85
void initialize(size_t id, unsigned int statusBits, const float *position, float totalCharge, float avePeakTime, float deltaPeakTime, float sigmaPeakTime, float hitChiSquare, float docaToAxis, float arclenToPoca, const ClusterHit2DVec &hitVec, const std::vector< float > &hitDelTSigVec, const std::vector< geo::WireID > &wireIDVec)
Definition: Cluster3D.cxx:122
unsigned int m_statusBits
Volatile status information of this 3D hit.
Definition: Cluster3D.h:190
Definition of utility objects for use in the 3D clustering for LArSoft.
Definition: Cluster3D.cxx:17
int m_clusterIdx
ID for this cluster.
Definition: Cluster3D.h:254
std::vector< float > m_hitDelTSigVec
Delta t of hit to matching pair / sig.
Definition: Cluster3D.h:200
float SigmaPeakTime() const
Uncertainty for the signal peak, in tick units.
Definition: Hit.h:220
2D representation of charge deposited in the TDC/wire plane
Definition: Hit.h:49
friend bool operator<(const PrincipalComponents &a, const PrincipalComponents &b)
Definition: Cluster3D.cxx:224
EigenVectors m_eigenVectors
The three principle axes.
Definition: Cluster3D.h:218
float m_xPosition
The x coordinate for this hit.
Definition: Cluster3D.h:46
float PeakTimePlusRMS(float sigmas=+1.) const
Returns a time sigmas RMS away from the peak time.
Definition: Hit.h:237
friend std::ostream & operator<<(std::ostream &o, const ClusterHit2D &c)
Definition: Cluster3D.cxx:40
float m_position[3]
position of this hit combination in world coordinates
Definition: Cluster3D.h:191
const ClusterHit2DVec & getHits() const
Definition: Cluster3D.h:158
ClusterHit2DVec m_hitVector
Hits comprising this 3D hit.
Definition: Cluster3D.h:199
int getClusterIdx() const
Definition: Cluster3D.h:269
void UpdateParameters(const reco::ClusterHit2D *hit)
Definition: Cluster3D.cxx:350
friend std::ostream & operator<<(std::ostream &o, const Cluster3D &c)
Definition: Cluster3D.cxx:311
friend std::ostream & operator<<(std::ostream &o, const ClusterHit3D &c)
Definition: Cluster3D.cxx:160
float m_avePosition[3]
Average position of hits fed to PCA.
Definition: Cluster3D.h:219
int m_numHitsUsed
Number of hits in the decomposition.
Definition: Cluster3D.h:216
friend std::ostream & operator<<(std::ostream &o, const PrincipalComponents &a)
Definition: Cluster3D.cxx:204