QwAnalysis
QwTreeLine.cc
Go to the documentation of this file.
1 /**
2  * \file QwTreeLine.cc
3  * \brief Definition of the one-dimensional track stubs
4  *
5  * \author Wouter Deconinck <wdconinc@mit.edu>
6  * \author Jie Pan <jpan@jlab.org>
7  * \date Sun May 24 11:05:29 CDT 2009
8  */
9 
10 #include "QwTreeLine.h"
12 
13 // System headers
14 #include <cmath>
15 
16 // Qweak headers
17 #include "QwHit.h"
18 #include "QwHitPattern.h"
19 #include "QwHitContainer.h"
20 
21 
22 /// Default constructor
24 {
25  // Initialize
26  Initialize();
27 }
28 
29 
30 /// Constructor with tree search results
31 QwTreeLine::QwTreeLine(int _a_beg, int _a_end, int _b_beg, int _b_end)
32 {
33  // Initialize
34  Initialize();
35 
36  // Tree search
37  a_beg = _a_beg;
38  a_end = _a_end;
39  b_beg = _b_beg;
40  b_end = _b_end;
41 }
42 
43 
44 /// Constructor with offset and slope
45 QwTreeLine::QwTreeLine(double offset, double slope)
46 {
47  // Initialize
48  Initialize();
49 
50  // Offset and slope
51  fOffset = offset;
52  fSlope = slope;
53 }
54 
55 /// Copy constructor
57 : VQwTrackingElement(that)
58 {
59  // Initialize
60  Initialize();
61 
62  // Copy object
63  *this = that;
64 }
65 
66 /// Copy constructor
68 : VQwTrackingElement(*that)
69 {
70  // Initialize
71  Initialize();
72 
73  // Null pointer
74  if (that == 0) return;
75 
76  // Copy object
77  *this = *that;
78 }
79 
80 
81 /**
82  * Delete the tree line and the lists of hits depending on it
83  */
85 {
86  // Delete the hits in this treeline
87  for (int i = 0; i < 2 * MAX_LAYERS; ++i) {
88 
89  if (fHits[i]) delete fHits[i];
90  fHits[i] = 0;
91  }
92 
93  DeleteHits();
94  // No recursive delete of the next pointer is done here
95 }
96 
97 
98 /**
99  * Perform object initialization
100  */
102 {
103  // Clear the list of hits
104  ClearHits();
105 
106  // Reset the void and used flags
107  fIsVoid = false; // treeline is not void yet
108  fIsUsed = false; // treeline is not part of a partial track yet
109 
110  // Tree search
111  a_beg = 0;
112  a_end = 0;
113  b_beg = 0;
114  b_end = 0;
115 
116  next = 0; // no next element yet in linked-list
117 
118  fOffset = fSlope = 0.0;
119  fChi = 0.0;
120 
121  for (int i = 0; i < 3; i++)
122  fCov[i] = 0.0;
123 
124  fNumHits = 0;
125  fNumMiss = 0;
126 
127  for (int i = 0; i < 2 * MAX_LAYERS; i++) {
128  fHits[i] = 0;
129  fHashArray[i] = 0;
130  }
131 
132  fAverageResidual = 0;
133 
135 }
136 
137 
138 /**
139  * Assignment operator
140  */
142 {
143  if (this == &that) return *this;
144 
146 
148 
149  fOffset = that.fOffset;
150  fSlope = that.fSlope;
151  fChi = that.fChi;
153  for (size_t i = 0; i < 3; i++)
154  fCov[i] = that.fCov[i];
155 
156  a_beg = that.a_beg;
157  a_end = that.a_end;
158  b_beg = that.b_beg;
159  b_end = that.b_end;
160 
161  fNumHits = that.fNumHits;
162  fNumMiss = that.fNumMiss;
163 
164  fR3Offset = that.fR3Offset;
165  fR3FirstWire = that.fR3FirstWire;
166  fR3LastWire = that.fR3LastWire;
167 
168  SetPackage(that.GetPackage());
169  SetRegion(that.GetRegion());
170  SetPlane(that.GetPlane());
171  SetDirection(that.GetDirection());
172 
173  next = 0;
174 
175  // Copy the hits
176  for (int i = 0; i < 2 * MAX_LAYERS; i++) {
177 
178  fHashArray[i] = that.fHashArray[i];
179 
180  if (that.fHits[i]) {
181  this->fHits[i] = new QwHit(that.fHits[i]);
182  }
183  }
184 
185  // Copy hits
186  ClearHits();
187  AddHitList(that.fQwHits);
188 
189  return *this;
190 }
191 
192 
193 // Clear the list of hits
195 {
196  fQwHits.clear();
197  fNQwHits = 0;
198 }
199 
200 // Delete the hits in the list
202 {
203  for (size_t i = 0; i < fQwHits.size(); i++)
204  delete fQwHits.at(i);
205  ClearHits();
206 }
207 
208 // Delete a single hit
209 void QwTreeLine::DeleteHit(const size_t i)
210 {
211  if (fQwHits.at(i)) {
212  delete fQwHits.at(i);
213  fQwHits.erase(fQwHits.begin()+i);
214  fNQwHits--;
215  }
216 }
217 
218 // Add a single hit
219 void QwTreeLine::AddHit(const QwHit* hit)
220 {
221  if (hit) fQwHits.push_back(new QwHit(hit));
222  fNQwHits++;
223 }
224 
225 // Add a list of hits
226 void QwTreeLine::AddHitList(const std::vector<QwHit*> &hitlist)
227 {
228  for (std::vector<QwHit*>::const_iterator hit = hitlist.begin();
229  hit != hitlist.end(); hit++)
230  AddHit(*hit);
231 }
232 
233 // Get the hits from the TClonesArray to a QwHitContainer
235 {
236  if (fNQwHits == 0 || i >= fNQwHits)
237  return 0;
238  else
239  return fQwHits.at(i);
240 }
241 
242 // Get the hits from the TClonesArray to a QwHitContainer (const version)
243 const QwHit* QwTreeLine::GetHit(int i) const
244 {
245  if (fNQwHits == 0 || i >= fNQwHits)
246  return 0;
247  else
248  return fQwHits.at(i);
249 }
250 
251 
252 /**
253  * Determine the chi^2 for a tree line, weighted by the number of hits.
254  *
255  * @return Weighted chi^2
256  */
258 {
259  double weight;
260  // NOTE Added +1 to get this to work if fNumHits == fNumMiss (region 2 cosmics)
261  if (fNumHits >= fNumMiss)
262  weight = (double) (fNumHits + fNumMiss + 1)
263  / (fNumHits - fNumMiss + 1);
264  else {
265  QwMessage << "miss = " << fNumMiss << ", hits = " << fNumHits << QwLog::endl;
266  return 100000.0; // This is bad...
267  }
268  return weight * fChi;
269 }
270 
271 /**
272  * Determine the hit with the smallest drift distance, i.e. a first order
273  * estimate of the crossing of the track with the central wire plane.
274  * @param offset Optional offset to the position
275  * @return Hit with smallest drift distance
276  */
278 {
279  double best_position = 9999.9;
280  int best_hit = 0;
281  // Get the best measured hit in the back
282  for (int hit = 0; hit < GetNumberOfHits(); hit++) {
283  double position = fabs(GetHit(hit)->GetDriftPosition() - offset);
284  if (position < best_position) {
285  best_position = position;
286  best_hit = hit;
287  }
288  }
289  return GetHit(best_hit);
290 }
291 
292 /**
293  * Calculate average residual of this partial track over all treelines
294  * @return Average residual
295  */
297 {
298  int numHits = 0;
299  double sumResiduals = 0.0;
300  // loop over hits
301  for (Int_t i = 0; i < GetNumberOfHits(); i++) {
302  const QwHit* hit = GetHit(i);
303  if (hit->IsUsed()) {
304  sumResiduals += hit->GetTreeLineResidual();
305  numHits++;
306  }
307  } // end of loop over hits
308  fAverageResidual = sumResiduals / numHits;
309  return fAverageResidual;
310 }
311 
312 
313 
314 /**
315  * Print the tree line in a linked list
316  */
317 void QwTreeLine::Print(const Option_t* options) const {
318  if (!this) return;
319  std::cout << *this << std::endl;
320  if (next) next->Print(options);
321 }
322 
323 
324 /**
325  * Print the valid tree lines in a linked list
326  */
328  if (!this) return;
329  if (this->IsValid()) std::cout << *this << std::endl;
330  next->PrintValid();
331 }
332 
333 
334 /**
335  * Stream some info about the tree line
336  * @param stream Stream as lhs of the operator
337  * @param tl Tree line as rhs of the operator
338  * @return Stream as result of the operator
339  */
340 std::ostream& operator<< (std::ostream& stream, const QwTreeLine& tl) {
341  stream << "tl: ";
342  if (tl.a_beg + tl.a_end + tl.b_beg + tl.b_end != 0) {
343  stream << tl.a_beg << "," << tl.a_end << " -- ";
344  stream << tl.b_beg << "," << tl.b_end << " ";
345  }
346  if (tl.GetRegion() != kRegionIDNull) { // treeline has geometry identification
347  stream << "(" << tl.GetRegion() << "/" << "?UD"[tl.GetPackage()];
348  stream << "/" << "?xyuvrq"[tl.GetDirection()];
349  if (tl.GetPlane() > 0)
350  stream << "/" << tl.GetPlane() << ")";
351  else
352  stream << ")";
353  }
354  if (tl.fChi > 0.0) { // treeline has been fitted
355  stream << "; fOffset = " << tl.fOffset/Qw::cm << " cm";
356  stream << ", fSlope = " << tl.fSlope;
357  stream << ", fResidual = " << tl.fAverageResidual/Qw::cm << " cm";
358  stream << ", fChi = " << tl.fChi;
359  stream << "; hits (" << tl.fQwHits.size() << "):";
360  for (size_t hit = 0; hit < tl.fQwHits.size(); hit++)
361  stream << " " << tl.fQwHits.at(hit)->GetPlane() << ":" << tl.fQwHits.at(hit)->GetElement();
362  }
363  if (tl.IsVoid()) stream << " (void)";
364  return stream;
365 }
366 
367 void QwTreeLine::SetMatchingPattern(std::vector<int>& box)
368 {
369  std::vector<int>::iterator iter = box.begin();
370  while (iter != box.end())
371  fMatchingPattern.push_back(*iter++);
372 }
373 
374 std::pair<double,double> QwTreeLine::CalculateDistance(int row,double width,unsigned int bins,double resolution)
375 {
376  std::pair<double,double> boundary(0,0);
377  int bin = fMatchingPattern.at(row);
378 
379  double dx = width / bins, lower = 0, upper = 0;
380  bin += 1;
381  if (bin <= (int) (bins/2)) bin = bins - bin + 1;
382  lower = (bin - 1) * dx - width / 2 - resolution;
383  upper = bin * dx - width / 2 + resolution;
384  boundary.first = lower;
385  boundary.second = upper;
386 
387  return boundary;
388 }
389 
double fChi
chi squared(?)
Definition: QwTreeLine.h:215
#define QwMessage
Predefined log drain for regular messages.
Definition: QwLog.h:50
void SetPlane(int plane)
Set the plane number.
int fHashArray[2 *MAX_LAYERS]
///&lt; all hits that satisfy road requirement
Definition: QwTreeLine.h:226
std::ostream & operator<<(std::ostream &out, const QwColor &color)
Output stream operator which uses the enum-to-escape-code mapping.
Definition: QwColor.h:153
double fOffset
track offset
Definition: QwTreeLine.h:213
void SetMatchingPattern(std::vector< int > &box)
Set the matching pattern.
Definition: QwTreeLine.cc:367
bool fIsUsed
has been used (part of parttrack)
Definition: QwTreeLine.h:207
void DeleteHits()
Delete the hits in the list.
Definition: QwTreeLine.cc:201
int fR3Offset
offset of demultiplexed group of 8
Definition: QwTreeLine.h:228
Int_t GetNumberOfHits() const
Get the number of hits.
Definition: QwTreeLine.h:109
const Bool_t & IsUsed() const
Definition: QwHit.h:101
bool fIsVoid
has been found void
Definition: QwTreeLine.h:206
void SetRegion(EQwRegionID region)
Set the region.
QwHit * GetBestWireHit(double offset=0.0)
Get the hit with the smallest drift distance.
Definition: QwTreeLine.cc:277
double fAverageResidual
///&lt; link to next list element
Definition: QwTreeLine.h:235
std::vector< QwHit * > fQwHits
List of hits in this tree line.
Definition: QwTreeLine.h:58
double fCov[3]
covariance matrix of offset and slope
Definition: QwTreeLine.h:216
double GetChiWeight()
Get the weighted chi^2.
Definition: QwTreeLine.cc:257
double fSlope
track slope
Definition: QwTreeLine.h:214
void SetPackage(EQwDetectorPackage package)
Set the package.
int fR3LastWire
first and last wire in group of 8
Definition: QwTreeLine.h:229
void AddHitList(const std::vector< QwHit * > &fQwHits)
Add a list of hits.
Definition: QwTreeLine.cc:226
Definition of the hit patterns used in the tracking tree search.
EQwRegionID GetRegion() const
Get the region.
int GetPlane() const
Get the plane number.
VQwTrackingElement & operator=(const VQwTrackingElement &that)
Assignment operator.
QwHit * GetHit(int i=0)
Get a specific hit.
Definition: QwTreeLine.cc:234
Draft skeleton for the decoding-to-QTR interface class.
const Double_t & GetTreeLineResidual() const
Definition: QwHit.h:97
void Print(const Option_t *options=0) const
Definition: QwTreeLine.cc:317
int b_end
bin in last layer
Definition: QwTreeLine.h:219
void PrintValid()
Definition: QwTreeLine.cc:327
int fNumHits
number of hits on this treeline
Definition: QwTreeLine.h:221
void Initialize()
Initialization.
Definition: QwTreeLine.cc:101
Definition of the one-dimensional track stubs.
bool IsVoid() const
Is this tree line void?
Definition: QwTreeLine.h:87
void SetDirection(EQwDirectionID direction)
Set the direction.
std::vector< int > fMatchingPattern
Definition: QwTreeLine.h:212
One-dimensional (u, v, or x) track stubs and associated hits.
Definition: QwTreeLine.h:51
int fNumMiss
number of planes without hits
Definition: QwTreeLine.h:222
std::pair< double, double > CalculateDistance(int row, double width, unsigned int bins, double error)
calculate the upper and lower bound of the drift distance give the row number
Definition: QwTreeLine.cc:374
QwTreeLine()
Default constructor.
Definition: QwTreeLine.cc:23
static std::ostream & endl(std::ostream &)
End of the line.
Definition: QwLog.cc:299
void DeleteHit(const size_t i)
Delete a single hit.
Definition: QwTreeLine.cc:209
QwTreeLine & operator=(const QwTreeLine &treeline)
Assignment operator.
Definition: QwTreeLine.cc:141
ClassImp(QwF1TDC)
void AddHit(const QwHit *hit)
Add a single hit.
Definition: QwTreeLine.cc:219
virtual ~QwTreeLine()
Destructor.
Definition: QwTreeLine.cc:84
int fR3FirstWire
Definition: QwTreeLine.h:229
bool IsValid() const
Is this tree line valid?
Definition: QwTreeLine.h:90
QwTreeLine * next
Definition: QwTreeLine.h:231
QwHit * fHits[2 *MAX_LAYERS]
Definition: QwTreeLine.h:224
Hit structure uniquely defining each hit.
Definition: QwHit.h:43
#define MAX_LAYERS
Definition: globals.h:8
int a_end
bin in first layer
Definition: QwTreeLine.h:218
EQwDirectionID GetDirection() const
Get the direction.
Int_t fNQwHits
Number of hits in this tree line.
Definition: QwTreeLine.h:56
double CalculateAverageResidual()
Calculate the average residuals.
Definition: QwTreeLine.cc:296
void ClearHits()
Clear the list of hits without deleting.
Definition: QwTreeLine.cc:194
EQwDetectorPackage GetPackage() const
Get the package.
static const double cm
Length units: base unit is mm.
Definition: QwUnits.h:61
Virtual base class for all tracking elements.