QwAnalysis
QwTrackingTreeSort.cc
Go to the documentation of this file.
1 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
2 //
3 // C++ Interface: QwTrackingTreeSort
4 //
5 // Description:
6 //
7 //
8 // Modified by: Wouter Deconinck <wdconinc@mit.edu>, (C) 2008
9 //
10 // Jie Pan <jpan@jlab.org>, Sun May 24 14:29:42 CDT 2009
11 //
12 // Copyright: See COPYING file that comes with this distribution
13 //
14 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
15 
16 /*! \class QwTrackingTreeSort
17 
18  \file QwTrackingTreeSort.cc
19 
20  $Date: Sun May 24 14:29:42 CDT 2009 $
21 
22  \brief This module is used to identify good track segments versus ghost tracks/hits.
23  */
24 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
25 
26 #include <cstdio>
27 #include <cstdlib>
28 #include <cassert>
29 #include <cstring>
30 
31 #include "QwTrackingTreeSort.h"
32 
33 #include "QwDetectorInfo.h"
34 
35 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
36 
37 /**
38  * Initializes the module responsible for sorting tracks according to chi^2
39  */
41 {
42  fDebug = 0; // Debug level
43 
44  doubletrack = 0.2;
45  good = 2;
46 }
47 
48 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
49 
51 {
52 }
53 
54 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
55 
56 /* ======================================================================
57  * checks for connected lines on the connectivity array
58  * ====================================================================== */
60  char *ca,
61  int *array,
62  int *isvoid,
63  char size,
64  int idx)
65 {
66  int ret = 0;
67  idx *= size;
68  for (int j = 0; j < size; j++) {
69  if (array[j+idx] && (!ca || ca[j]) && isvoid[j] != true)
70  ret++;
71  }
72  return ret;
73 }
74 
75 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
76 
78  char *ca,
79  int *array,
80  int *isvoid,
81  char size,
82  int idx)
83 {
84  memset (ca, 0, size);
85  ca[idx] = 1;
86  for (int i = 0; i < size; i++) {
87  if (ca[i]) {
88  for (int j = i+1; j < size; j++) {
89  if (array[j+i*size] && isvoid[j] == false )
90  ca[j] = 1;
91  }
92  }
93  }
94  return 0;
95 }
96 
97 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
98 
100  char *ca,
101  int *array,
102  int *isvoid,
103  double *chia,
104  int size,
105  int idx)
106 {
107  int besti = idx, bestj = -1;
108  double bestchi = chia[idx], bestdchi;
109 
110  for (int j = idx+1; j < size; j++) { /* search for the best single-track */
111  if (! ca[j])
112  continue;
113  if (chia[j] < bestchi) {
114  besti = j;
115  bestchi = chia[j];
116  }
117  }
118 
119  bestdchi = (bestchi) * (2 + doubletrack);// this will allow a double track, with the 2nd best chi
120  //to be up to (doubletrack)% larger than the best chi.
121 
122  for (int i = idx; i < size; i++) { /* is there a double track ? */
123  if (! ca[i])
124  continue;
125  for (int j = i+1; j < size; j++) {
126  if (! ca[j])
127  continue;
128  if (array[i*size+j]) // if it's two tracks sharing a bunch of wires, don't worry about it
129  continue;
130  if (chia[j] + chia[i] < bestdchi) { // but if there's two separate tracks, with good chi, then it's a double track
131  besti = i;
132  bestj = j;
133  bestdchi = chia[j]+chia[i];
134  }
135  }
136  }
137 
138  for (int i = idx; i < size; i++) {
139  if (! ca[i])
140  continue;
141  if (i == besti || i == bestj || besti == -1) {
142  isvoid[i] = good;//good
143  }
144  else if (isvoid[i] == false) {
145  if ( (besti >= 0 && array[i*size+besti] ) ||
146  (bestj >= 0 && array[i*size+bestj] ) ) {
147  isvoid[i] = true;
148  }
149  }
150  }
151 }
152 
153 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
154 
156  char *ca,
157  int *array,
158  int *isvoid,
159  int size,
160  int idx)
161 {
162  int i, max = 0, c;
163  bool old;
164 
165  old = isvoid[idx];
166  isvoid[idx] = false;
167 
168  for(i = 0; i < size; i++ ) {
169  if( isvoid[i] != true ) {
170  c = connectiv( ca, array, isvoid, size, i);
171  if( c > max )
172  max = c;
173  }
174  }
175  isvoid[idx] = old;
176  return max;
177 }
178 
179 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
180 
182  char *ca,
183  int *array,
184  int *isvoid,
185  double *chia,
186  int size,
187  int idx)
188 {
189  int besti = -1;
190  double bestchi = 1e8, oworst = 0.0;
191  double chi;
192 
193  for (int i = idx; i < size; i++) {
194  if (! ca[i])
195  continue;
196  chi = chia[i];
197  if (isvoid[i] != true) {
198 
199  if (oworst < chi)
200  oworst = chi;
201  continue;
202  }
203  if (globalconnectiv (ca, array, isvoid, size, i) > 2)
204  continue;
205 
206  if (bestchi > chi) {
207  besti = i;
208  bestchi = chi;
209  }
210  }
211  if (besti >= 0 && (3.0 > bestchi || oworst + 3.0 > bestchi)) {
212  isvoid[besti] = good; // good
213  return 1;
214  }
215  return 0;
216 }
217 
218 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
219 
221 {
222  // Get lists of treelines in these tracks
223  const std::vector<QwTreeLine*> tl1 = track1->GetListOfTreeLines();
224  const std::vector<QwTreeLine*> tl2 = track2->GetListOfTreeLines();
225 
226  // Map direction to treeline (assumes one treeline per direction)
227  std::map<EQwDirectionID,QwTreeLine*> tl1map, tl2map;
228  for (size_t i = 0; i < tl1.size(); i++)
229  tl1map[tl1[i]->GetDirection()] = tl1[i];
230  for (size_t i = 0; i < tl2.size(); i++)
231  tl2map[tl2[i]->GetDirection()] = tl2[i];
232 
233  // Count common wires for the partial track
234  int common = 0;
235  for (EQwDirectionID dir = kDirectionX; dir <= kDirectionV; dir++) {
236  // Check whether entries exist for this direction
237  if (tl1map.count(dir) == 0) continue;
238  if (tl2map.count(dir) == 0) continue;
239  // Count common wires for these treelines
240  common += rcCommonWires (tl1map[dir], tl2map[dir]);
241  }
242  // Determine average assuming 3 directions
243  common /= 3;
244  return common;
245 }
246 
247 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
248 
249 /* This function simply counts the number of common wires
250 shared between two treelines. The only output is the integer
251 return value
252 */
254 {
255  //################
256  // DECLARATIONS #
257  //################
258  int common, total;
259 
260  //##################
261  //DEFINE VARIABLES #
262  //##################
263  common = total = 0;
264  std::vector<QwHit*> hits1 = line1->GetListOfHits();
265  std::vector<QwHit*> hits2 = line2->GetListOfHits();
266 
267  //##############################################
268  //Count the wires shared between the treelines #
269  //##############################################
270  int i1 = 0, i2 = 0;
271  for ( ; i1 < line1->GetNumberOfHits() && i2 < line2->GetNumberOfHits() ; ) {
272  if (hits1[i1]->GetElement() == hits2[i2]->GetElement()) {
273  if (hits1[i1]->IsUsed() && hits2[i2]->IsUsed())
274  common++;
275  i1++;
276  i2++;
277  total++;
278  }
279  else if (hits1[i1]->GetElement() > hits2[i2]->GetElement()) {
280  i2++;
281  total++;
282  }
283  else if (hits1[i1]->GetElement() < hits2[i2]->GetElement()) {
284  i1++;
285  total++;
286  }
287  }
288  total += line1->GetNumberOfHits() - i1 + line2->GetNumberOfHits() - i2;
289 
290  //Check which line has more hits used
291  // total = total1 > total2 ? total2 : total1;
292 
293  if (! total)
294  return 0;
295 
296  // Get a ratio and multiply it to return an integer
297  return (10000 * common / total + 50 ) / 100;
298  // if 8 common out of 8, then this = 100
299 }
300 
301 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
302 
303 /*------------------------------------------------------------------------*//*!
304 
305  \brief Counts the number of common wires shared between two tree lines.
306 
307  The return value is the an integer score between 0 and 100, where 100 means
308  that all wires are common. One tree line as subset of the other will result
309  in a score of 100. The tree lines are not modified by this function.
310 
311 *//*-------------------------------------------------------------------------*/
313  const QwTreeLine *treeline1, ///< first tree line
314  const QwTreeLine *treeline2) ///< second tree line
315 {
316  // Get the lists of hits associated with the two tree lines
317  const QwHit* const* hits1 = treeline1->fHits;
318  const QwHit* const* hits2 = treeline2->fHits;
319 
320  // A two-bit pattern indicates on which treeline we should advance in the
321  // next iteration of the search. This assumes that the detectors are ordered.
322  int fw = 3;
323  // E.g. fw = (decimal) 3 = (binary) 11: this means that we should advance on
324  // both treeline 1 and treeline 2.
325 
326  int common = 0; // number of common hits
327  int total1 = 0, total2 = 0; // total number of hits on the tree lines
328 
329  // Infinite loop over the entries in both lists
330  int i1 = -1, i2 = -1;
331  for (;;) {
332 
333  // Advance on tree line 1
334  if (fw & 1) {
335  i1++;
336  // Advance until we reach the end of the list or find a hit
337  for ( ; i1 < DLAYERS*MAXHITPERLINE && hits1[i1]; i1++)
338  if (hits1[i1]->IsUsed()) {
339  total1++;
340  break;
341  }
342  }
343 
344  // Advance on tree line 2
345  if (fw & 2) {
346  i2++;
347  // Advance until we reach the end of the list or find a hit
348  for ( ; i2 < DLAYERS*MAXHITPERLINE && hits2[i2]; i2++)
349  if (hits2[i2]->IsUsed()) {
350  total2++;
351  break;
352  }
353  }
354 
355  // End condition: if we reach the end of the hits in either line
356  // either because we reach the maximum, or because we read a null hit
357  if (i1 == DLAYERS * MAXHITPERLINE || ! hits1[i1]
358  || i2 == DLAYERS * MAXHITPERLINE || ! hits2[i2])
359  break;
360 
361  // Now that we have a hit in tree line 1 and 2, determine the detector ID
362  int id1 = hits1[i1]->GetDetectorInfo()->GetPlane();
363  int id2 = hits2[i2]->GetDetectorInfo()->GetPlane();
364  // If the ID in treeline 1 is lower, advance on treeline 1
365  if (id1 < id2)
366  fw = 1;
367  // If the ID in treeline 2 is lower, advance on treeline 2
368  else if (id1 > id2)
369  fw = 2;
370  // If both IDs are the same, check whether also the same wires were hit
371  else {
372  if (hits1[i1]->GetElement() == hits2[i2]->GetElement())
373  common++; // This is a common hit! (disregarding L/R ambiguity)
374  // and then advance on both treelines
375  fw = 3;
376  }
377 
378  } // end of infinite loop
379 
380 
381  // Determine the smallest number of used hits for the two treelines
382  int total = total1 > total2 ? total2 : total1;
383  // and return 0 if there was a treeline without any used hits
384  if (total == 0) return 0;
385 
386  // else return a value between 0 and 100
387  return (10000 * common / total + 50 ) / 100;
388 }
389 
390 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
391 
392 /*------------------------------------------------------------------------*//*!
393 
394  \brief The best (by chi^2) treelines are select
395 
396 *//*-------------------------------------------------------------------------*/
398  QwTreeLine *treelinelist, ///< list of tree lines
399  EQwRegionID region) ///< region
400 {
401  // Maximum allowed chi value (was 20000.0)
402  double maxchi = 35000.0;
403 
404 
405  /* Reduce the number of treelines
406  * - by removing treelines with high chi values
407  * - by reducing the maximum allowed chi^2 value if necessary
408  */
409  int index = 0;
410  int iteration = 0;
411  int nTooManyTreeLines = 0;
412  do {
413  double local_maxchi = 0.0;
414  double local_minchi = maxchi;
415 
416  // Keep track of the number of iterations
417  ++iteration;
418 
419  index = 0;
420  // Loop over the list of treelines
421  for (QwTreeLine* treeline = treelinelist;
422  treeline; treeline = treeline->next) {
423 
424  // If we have been doing this for too long already, give up already
425  if (iteration > 100 ) {
426  if (fDebug) {
427  cout << *treeline;
428  cout << "... void because too many treelines already." << endl;
429  }
430  treeline->SetVoid();
431  nTooManyTreeLines++;
432 
433  // Otherwise consider valid treelines
434  } else if (treeline->IsValid()) {
435  // Get weighted chi
436  double chi = treeline->GetChiWeight();
437 
438  // Discard the treeline if chi is too large
439  if (chi > maxchi) {
440  if (fDebug) {
441  cout << *treeline;
442  cout << "... void because chi^2 = " << chi << " above " << maxchi << endl;
443  }
444  treeline->SetVoid();
445 
446  // Otherwise consider this treeline
447  } else {
448  // Keep track of smallest and largest chi value
449  if (chi > local_maxchi) {
450  local_maxchi = chi;
451  }
452  if (chi < local_minchi) {
453  local_minchi = chi;
454  }
455  index++;
456  }
457  }
458  } // end of loop over the list of tree lines
459 
460  // Reduce search range to two thirds of range found
461  maxchi = local_minchi + (local_maxchi - local_minchi) * 0.66;
462  // until we have fewer track
463  } while (index > 30 );
464  // Number of treelines
465  int nTreeLines = index;
466 
467  // Skip this event if we had no or too many tree lines.
468  if (nTooManyTreeLines != 0) {
469  if (fDebug) std::cout << "Skipping event, too many treelines." << std::endl;
470  return 0;
471  }
472  if (nTreeLines == 0) {
473  if (fDebug) std::cout << "Skipping event, no good treelines." << std::endl;
474  return 0;
475  }
476  if (fDebug) cout << "Number of treelines with good chi: " << nTreeLines << endl;
477 
478 
479  /* Now add the valid treelines to new lists */
480 
481  // Reserve memory for the lists of treelines
482  char* connarr = (char*) malloc (nTreeLines);
483  int* isvoid = (int*) malloc (nTreeLines * sizeof(int));
484  double* chi = (double*) malloc (nTreeLines * sizeof(double));
485  int* array = (int*) malloc (nTreeLines * nTreeLines * sizeof(int));
486  QwTreeLine **tlarr = (QwTreeLine**) malloc (nTreeLines * sizeof(QwTreeLine*));
487 
488  // Loop over the treelines and store valid treelines in new list
489  index = 0;
490  for (QwTreeLine* treeline = treelinelist;
491  treeline; treeline = treeline->next) {
492  if (treeline->IsValid()) {
493  tlarr[index] = treeline;
494  isvoid[index] = treeline->IsVoid();
495  chi[index] = treeline->GetChiWeight();
496  index++;
497  }
498  } // end of loop over treelines
499 
500 
501  /* Build the graph array:
502  * for every accepted tree line, store in a matrix which two tree lines
503  * shares at least one quarter of the hit wires with eachother.
504  *
505  * E.g. for three tree lines where tl1 and tl3 share enough hits:
506  * | 0 0 1 |
507  * | 0 0 0 |
508  * | 1 0 0 |
509  *
510  * The matrix is stored in serialized form.
511  */
512  if (region == kRegionID3) {
513  for (int i = 0; i < nTreeLines; i++) {
514  array[i * nTreeLines + i] = false; // diagonals are set to false
515  for (int j = i+1; j < nTreeLines; j++) {
516  int common = rcCommonWires_r3 (tlarr[i], tlarr[j]);
517  array[i * nTreeLines + j] = array[j * nTreeLines + i] = (common > 25);
518  }
519  }
520  } else { /* region == kRegionID2 */
521  for (int i = 0; i < nTreeLines; i++) {
522  array[i * nTreeLines + i] = false;
523  for (int j = i+1; j < nTreeLines; j++) {
524  int common = rcCommonWires (tlarr[i], tlarr[j]);
525  array[i * nTreeLines + j] = array[j * nTreeLines + i] = (common > 100);
526  }
527  }
528  }
529 
530  /* --------------------------------------------------------------------
531  * check connectivity (?)
532  * -------------------------------------------------------------------- */
533  for (int i = 0; i < nTreeLines; ) {
534  if (isvoid[i] == false ) {
535  int bestconn = connectiv (0, array, isvoid, nTreeLines, i);
536  if (bestconn > 0) {
537  if (connectarray (connarr, array, isvoid, nTreeLines, i)) continue;
538  bestunconnected (connarr, array, isvoid, chi, nTreeLines, i);
539  } else {
540  isvoid[i] = good; // good
541  }
542  } else
543  i++;
544  }
545  for (int i = 0; i < nTreeLines; i++) {
546  if (isvoid[i] == true) {
547  if (connectiv (0, array, isvoid, nTreeLines, i)) {
548  connectarray (connarr, array, isvoid, nTreeLines, i);
549  bestconnected (connarr, array, isvoid, chi, nTreeLines, i);
550  }
551  }
552  }
553  for (int i = 0; i < nTreeLines; i++) {
554  if (isvoid[i] != true) {
555  tlarr[i]->SetValid();
556  } else {
557  if (fDebug) {
558  cout << *tlarr[i];
559  cout << "... void for some reason." << endl;
560  }
561  tlarr[i]->SetVoid();
562  }
563  }
564 
565  // Free malloc'ed arrays
566  free(chi);
567  free(connarr);
568  free(array);
569  free(isvoid);
570  free(tlarr);
571 
572  return 0;
573 }
574 
575 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
576 
577 int QwTrackingTreeSort::rcPartConnSort (std::vector<QwPartialTrack*> parttracklist)
578 {
579  char *connarr;
580  int *array;
581  QwPartialTrack **ptarr, *parttrack;
582  int *isvoid;
583  double *chia, chi, maxch = 2000.0, nmaxch, nminch;
584  /* ------------------------------------------------------------------
585  * find the number of used QwPartialTracks
586  * ------------------------------------------------------------------ */
587 
588  int rep = 0;
589  int idx = 0;
590  do { /* filter out high chi2 if needed */
591  rep++;
592  idx = 0;
593  nmaxch = 0.0;
594  nminch = maxch;
595  for (size_t pt = 0; pt < parttracklist.size(); pt++) {
596  parttrack = parttracklist[pt];
597  if (parttrack->fIsVoid == false ) {
598  chi = parttrack->GetChiWeight();
599  if (chi > maxch) {
600  if (fDebug) {
601  cout << *parttrack;
602  cout << "... void because chi^2 too high" << endl;
603  }
604  parttrack->fIsVoid = true;
605  } else {
606  if (chi > nmaxch) {
607  nmaxch = chi;
608  }
609  if (chi < nminch) {
610  nminch = chi;
611  }
612  idx++;
613  }
614  }
615  }
616  maxch = nminch + (nmaxch - nminch) * 0.66;
617  } while (idx > 30 && rep < 10);
618 
619 
620  int num = idx;
621 
622  if (! num)
623  return 0;
624 
625  //the following mallocs replaced Qmallocs
626  connarr = (char *)malloc( num );
627  isvoid = (int *)malloc( num * sizeof(int));
628  chia = (double *)malloc( num * sizeof(double));
629  array = (int*) malloc(num * num * sizeof(int));
630  ptarr = (QwPartialTrack **)malloc( sizeof(QwPartialTrack*)*num);
631 
632  if (! ptarr || ! array) {
633  fprintf(stderr,"Cannot Allocate Sort Array for %d PartialTracks\n",num);
634  abort();
635  }
636 
637  /* ----------------------------------------------------------------------
638  * find the used parttracks
639  * ---------------------------------------------------------------------- */
640 
641  for (size_t pt = 0, idx = 0; pt < parttracklist.size(); pt++) {
642  parttrack = parttracklist[pt];
643  if (parttrack->fIsVoid == false) {
644  ptarr[idx] = parttrack;
645  isvoid[idx] = parttrack->fIsVoid;
646  chia[idx] = parttrack->GetChiWeight();
647  idx++;
648  }
649  }
650 
651  /* ----------------------------------------------------------------------
652  * build the graph array
653  * ---------------------------------------------------------------------- */
654 
655  for (int i = 0; i < num; i++) {
656  array[i * num + i] = false;
657  for (int j = i+1; j < num; j++) {
658  array[i * num + j] = array[j * num + i] =
659  (rcPTCommonWires(ptarr[i], ptarr[j]) > 25);
660  }
661  }
662 
663  /* --------------------------------------------------------------------
664  * check connectivity
665  * -------------------------------------------------------------------- */
666 
667  for (int i = 0; i < num; ) {
668  if (isvoid[i] == false) {
669  int bestconn = connectiv( 0, array, isvoid, num, i);
670  if (bestconn > 0) {
671  if (connectarray(connarr, array, isvoid, num, i))
672  continue;
673 
674  bestunconnected (connarr, array, isvoid, chia, num, i);
675 
676  } else
677  isvoid[i] = good;//good
678  } else
679  i++;
680  }
681 
682  for (int i = 0; i < num; i++) {
683  if (isvoid[i] != true) {
684  ptarr[i]->fIsVoid = false;
685  } else
686  ptarr[i]->fIsVoid = true;
687  }
688 
689  // Free malloc'ed arrays
690  free(chia);
691  free(connarr);
692  free(array);
693  free(isvoid);
694  free(ptarr);
695 
696  return 0;
697 }
698 
699 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
int rcCommonWires(const QwTreeLine *line1, const QwTreeLine *line2)
Counts the number of common wires shared between two tree lines.
int connectarray(char *ca, int *array, int *isvoid, char size, int idx)
const std::vector< QwHit * > & GetListOfHits() const
Get the list of hits.
Definition: QwTreeLine.h:115
Int_t GetNumberOfHits() const
Get the number of hits.
Definition: QwTreeLine.h:109
int GetPlane() const
int connectiv(char *ca, int *array, int *isvoid, char size, int idx)
int rcTreeConnSort(QwTreeLine *head, EQwRegionID region)
The best (by chi^2) treelines are select.
#define DLAYERS
Definition: globals.h:5
void SetVoid(const bool isvoid=true)
Definition: QwTreeLine.h:88
#define MAXHITPERLINE
Definition: globals.h:12
void bestunconnected(char *ca, int *array, int *isvoid, double *chia, int size, int idx)
EQwRegionID
Definition: QwTypes.h:16
void SetValid(const bool isvoid=false)
Definition: QwTreeLine.h:91
int rcPartConnSort(std::vector< QwPartialTrack * > head)
Bool_t fIsVoid
marked as being void
bool IsVoid() const
Is this tree line void?
Definition: QwTreeLine.h:87
One-dimensional (u, v, or x) track stubs and associated hits.
Definition: QwTreeLine.h:51
int rcPTCommonWires(const QwPartialTrack *track1, const QwPartialTrack *track2)
const QwDetectorInfo * GetDetectorInfo() const
Get the detector info pointer.
EQwDirectionID
Definition: QwTypes.h:41
int bestconnected(char *ca, int *array, int *isvoid, double *chia, int size, int idx)
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
double GetChiWeight() const
int globalconnectiv(char *ca, int *array, int *isvoid, int size, int idx)
Contains the straight part of a track in one region only.
int rcCommonWires_r3(const QwTreeLine *line1, const QwTreeLine *line2)
const std::vector< QwTreeLine * > & GetListOfTreeLines() const
Get the list of tree lines.
static const double c
Physical constants.
Definition: QwUnits.h:118