QwAnalysis
QwTrackingTree Class Reference

Creates and manages the treesearch pattern database. More...

#include <QwTrackingTree.h>

+ Inheritance diagram for QwTrackingTree:
+ Collaboration diagram for QwTrackingTree:

Public Member Functions

 QwTrackingTree (unsigned int numlayers)
 Default constructor. More...
 
virtual ~QwTrackingTree ()
 Destructor. More...
 
void SetDebugLevel (const int debuglevel)
 Set the debug level. More...
 
void SetMaxSlope (const double maxslope)
 Set the maximum allowed slope. More...
 
void Print (const Option_t *options=0) const
 Print the full tree and hash table. More...
 
void PrintTree () const
 Print the full tree. More...
 
void PrintHashTable () const
 Print the hash table. More...
 
void SetGeometry (const QwGeometry &geometry)
 
int consistent (treenode *testnode, int level, QwDetectorInfo *detector)
 Determines whether the pattern is geometrically possible. More...
 
treenodeexistent (treenode *node, int hash)
 Search for a node in the search tree. More...
 
treenodenodeexists (nodenode *nd, treenode *tr)
 
void marklin (treenode *father, int level, QwDetectorInfo *detector)
 Recursively generate the treesearch pattern database. More...
 
long writetree (const string &filename, treenode *tn, int levels, int tlayers, double width)
 This function initializes the output file. It then calls the iterative _writetree function to fill the output file. More...
 
QwTrackingTreeRegionreadtree (const string &filename, int levels, int tlayers, double rwidth, bool skipreading)
 
QwTrackingTreeRegioninittree (const string &filename, int levels, int tlayer, double width, QwDetectorInfo *detector, bool regenerate)
 
- Public Member Functions inherited from VQwTrackingElement
 VQwTrackingElement ()
 Default constructor. More...
 
 VQwTrackingElement (const VQwTrackingElement &that)
 
virtual ~VQwTrackingElement ()
 Virtual destructor. More...
 
VQwTrackingElementoperator= (const VQwTrackingElement &that)
 Assignment operator. More...
 
const QwDetectorInfoGetDetectorInfo () const
 Get the detector info pointer. More...
 
void SetDetectorInfo (const QwDetectorInfo *detectorinfo)
 Set the detector info pointer. More...
 
EQwRegionID GetRegion () const
 Get the region. More...
 
void SetRegion (EQwRegionID region)
 Set the region. More...
 
EQwDetectorPackage GetPackage () const
 Get the package. More...
 
void SetPackage (EQwDetectorPackage package)
 Set the package. More...
 
int GetOctant () const
 Get the octant number. More...
 
void SetOctant (int octant)
 Set the octant number. More...
 
EQwDirectionID GetDirection () const
 Get the direction. More...
 
void SetDirection (EQwDirectionID direction)
 Set the direction. More...
 
int GetPlane () const
 Get the plane number. More...
 
void SetPlane (int plane)
 Set the plane number. More...
 
int GetElement () const
 Get the element number. More...
 
void SetElement (int element)
 Set the element number. More...
 
void SetGeometryTo (const VQwTrackingElement &e)
 Copy the geometry info from another object. More...
 

Private Member Functions

int _writetree (treenode *tn, FILE *fp, int32_t tlayers)
 Recursive method for pulling in the concise treesearch search database. More...
 
int _readtree (FILE *file, shorttree *stb, shortnode **father, int32_t tlayers)
 Recursive method to read the concise treesearch database from disk. More...
 
treenode_inittree (int32_t tlayer, QwDetectorInfo *detector)
 Recursive method to initialize and generate the treesearch database. More...
 

Private Attributes

QwGeometry fGeometry
 Detector (or set of detectors) represented by this search tree. More...
 
int fDebug
 Debug level. More...
 
unsigned int fNumLayers
 Number of detector planes. More...
 
unsigned int & fNumPlanes
 Number of planes in the region 2 HDCs. More...
 
unsigned int & fNumWires
 Number of wires in a region 3 VDC group. More...
 
unsigned int fHashSize
 Length of the hash table (as member field) More...
 
double fMaxSlope
 Maximum allowed slope for tracks in this detector. More...
 
int fNumPatterns
 Number of valid patterns in the tree. More...
 
int fRef
 Reference. More...
 
int fMaxRef
 Maximum number of references in the cached tree file. More...
 
int fMaxLevel
 
treenodefFather
 Father node: the main entry point to the tree. More...
 
treenode ** fHashTable
 

Static Private Attributes

static const std::string fgTreeDir
 Name of the tree directory (in $QWSCRATCH), as static member field. More...
 

Additional Inherited Members

- Protected Member Functions inherited from VQwTrackingElement
 ClassDef (VQwTrackingElement, 1)
 
- Protected Attributes inherited from VQwTrackingElement
const QwDetectorInfofDetectorInfo
 
EQwRegionID fRegion
 ///< Detector info pointer More...
 
EQwDetectorPackage fPackage
 Package. More...
 
int fOctant
 Octant number. More...
 
EQwDirectionID fDirection
 Direction. More...
 
int fPlane
 Plane number. More...
 
int fElement
 Element number. More...
 

Detailed Description

Creates and manages the treesearch pattern database.

The QwTrackingTree class contains the code for creating the tree search database.

The pattern database is used to determine whether subsets of hits resemble track segments.

PROGRAM: QTR (Qweak Track Reconstruction) AUTHOR: Burnham Stokes
            bestokes@jlab.org
          ORIGINAL HRC AUTHOR
            Wolfgang Wander
            wwc@hermes.desy.de

MODULE: QwTrackingTree

PURPOSE: This module contains the code for creating the tree search database. The code first attempts to pull the database from disk. But, if the required database is not found, the code will generate it from scratch and save a copy of it on disk.

CONTENTS: (brief description for now)

(01) consistent() - this function valids a possible treeline hit pattern by seeing if the pattern is consistent with a straight line trajectory through a detector with a slope less than or equal to the fMaxSlope parameter.

(02) existent() - this function checks if a possible treeline hit pattern is already included in the tree search database. If so, it returns a pointer to the pattern within the database. Otherwise, it returns 0.

(03) nodeexists() - this function checks if a possible treeline hit pattern is already known to a father. If so, it returns a pointer to the pattern within the tree database. Otherwise, it returns 0.

(05) marklin() - this function generates the treesearch database. For a given father, it generates the 2^(treelayers) possible son hit patterns. Each son pattern is checked to see if it is consistent with a trajectory through the chamber. If it is consistent, it is inserted into the treesearch database and then, by a recursive call to marklin(), its sons are generated.

(07) _inittree() - this function initializes the treesearch database and then calls marklin() to generate the database.

(08) _writetree() - a recursive function for pulling in the concise treesearch search database.

(09) writetree() - this function calls _writetree() to write the long version of the treesearch database to a disk file. Later, readtree() will read back this file to form the concise treesearch database (so-called short tree) used by the treesearch algorithm.

(11) _readtree() - a recursive function (called by readtree()) to read the concise treesearch database (so-called short tree) from disk.

(12) readtree() - this function calls _readtree() to read the concise treesearch database from disk.

(13) inittree() - this function creates the treesearch database for one treeline. It first attempts to read the database from a diskfile. If this fails, it calls _inittree() to generate the treesearch database.

(14) [c'tor] - the main function of this module. This function calls inittree() to generate the tree database for each of the treelines.

Definition at line 57 of file QwTrackingTree.h.

Constructor & Destructor Documentation

QwTrackingTree::QwTrackingTree ( unsigned int  numlayers)

Default constructor.

Initializes the search tree.

This function loops over each detector region, orientation, type, and wire direction to call inittree. It also determines a file name for each case.

Definition at line 143 of file QwTrackingTree.cc.

References QwTracking::treenode::fBit, fDebug, fFather, fHashSize, fHashTable, QwTracking::treenode::fMaxLevel, QwTracking::treenode::fMinLevel, fNumLayers, fNumPatterns, QwTracking::treenode::fRef, QwTracking::treenode::fWidth, HSHSIZ, and QwTracking::treenode::size().

144 : fNumPlanes(numlayers),fNumWires(numlayers)
145 {
146  fDebug = 0; // debug level
147 
148  fNumLayers = numlayers; // Set the number of layers in the search tree
149  // fNumPlanes = fNumLayers = 4 is number of region 2 HDC planes
150  // fNumWires = fNumLayers = 8 is number of region 3 VDC wires per group
151 
152  // Until variable hash table sizes are implemented, the local hash size should
153  // be equal to the value defined in the header.
154  fHashSize = HSHSIZ;
155  fHashTable = new treenode*[fHashSize];
156  for (size_t i = 0; i < fHashSize; i++)
157  fHashTable[i] = 0;
158 
159  // Initialize the QwTrackingTree structure
160  fFather = new treenode(fNumLayers);
161  fFather->fMaxLevel = -1;
162  fFather->fMinLevel = -1;
163  fFather->fWidth = 1;
164  for (unsigned int i = 0; i < fFather->size(); i++) fFather->fBit[i] = 0;
165  fFather->fRef = -1;
166 
167  // Reset the number of patterns generated
168  fNumPatterns = 0;
169 }
treenode * fFather
Father node: the main entry point to the tree.
treenode ** fHashTable
unsigned int & fNumWires
Number of wires in a region 3 VDC group.
int fNumPatterns
Number of valid patterns in the tree.
#define HSHSIZ
Length of the hash table (as header define)
int fMinLevel
Minimum level at which this node is valid.
Definition: treenode.h:79
int fWidth
Width in bins of the hit pattern.
Definition: treenode.h:87
int fRef
Reference of this node when writing to file.
Definition: treenode.h:90
unsigned int fHashSize
Length of the hash table (as member field)
int fDebug
Debug level.
int * fBit
Hit pattern, one bin specified per detector layer.
Definition: treenode.h:84
int fMaxLevel
Maximum level at which this node is valid.
Definition: treenode.h:81
unsigned int & fNumPlanes
Number of planes in the region 2 HDCs.
unsigned int size() const
Get size of the bit array.
Definition: treenode.h:123
A treenode contains the bits that make up a tree pattern.
Definition: treenode.h:63
unsigned int fNumLayers
Number of detector planes.

+ Here is the call graph for this function:

QwTrackingTree::~QwTrackingTree ( )
virtual

Destructor.

Definition at line 173 of file QwTrackingTree.cc.

References QwLog::endl(), fFather, fHashSize, fHashTable, QwTracking::treenode::GetNext(), QwDebug, and QwVerbose.

174 {
175  // Debug information
176  QwDebug << "Deleting QwTrackingTree: " << this << QwLog::endl;
177 
178  // Delete all top links in the hash table
179  QwDebug << "Deleting fHashTable..." << QwLog::endl;
180  for (size_t i = 0; i < fHashSize; i++) {
181  treenode* node = fHashTable[i];
182  while (node) {
183  treenode* node_next = node->GetNext();
184  delete node;
185  node = node_next;
186  }
187  }
188  // Delete hash table itself
189  delete[] fHashTable;
190 
191  // Delete father node
192  QwDebug << "Deleting fFather..." << QwLog::endl;
193  delete fFather;
194 
195  // Report memory statistics
196  if (treenode::GetObjectsAlive() > 0 || nodenode::GetObjectsAlive() > 0) {
197  QwVerbose << "Memory occupied by tree objects (should be close to zero when all trees cleared):" << QwLog::endl;
198  QwVerbose << "- allocated treenode objects: " << treenode::GetObjectsAlive() << QwLog::endl;
199  QwVerbose << "- allocated nodenode objects: " << nodenode::GetObjectsAlive() << QwLog::endl;
200  }
201 }
treenode * fFather
Father node: the main entry point to the tree.
#define QwVerbose
Predefined log drain for verbose messages.
Definition: QwLog.h:55
treenode ** fHashTable
#define QwDebug
Predefined log drain for debugging output.
Definition: QwLog.h:60
unsigned int fHashSize
Length of the hash table (as member field)
treenode * GetNext() const
Get the next node.
Definition: treenode.h:112
static std::ostream & endl(std::ostream &)
End of the line.
Definition: QwLog.cc:299
A treenode contains the bits that make up a tree pattern.
Definition: treenode.h:63

+ Here is the call graph for this function:

Member Function Documentation

treenode * QwTrackingTree::_inittree ( int32_t  tlayer,
QwDetectorInfo detector 
)
private

Recursive method to initialize and generate the treesearch database.

This function performs initilization before calling marklin, the iterative pattern generator. the root treenode is created as the simplest pattern possible, and passed to marklin.

Generate a copy of the father node to start off this tree search database

Clear the hash table

Call the recursive tree generator

Finally, add the father node to the hash table

Definition at line 1153 of file QwTrackingTree.cc.

References QwLog::endl(), fFather, fHashTable, fNumPatterns, marklin(), QwDebug, and QwTracking::treenode::SetNext().

Referenced by inittree().

1156 {
1157  /// Generate a copy of the father node to start off this tree search database
1158  treenode *node = new treenode(fFather);
1159 
1160  /// Clear the hash table
1161  fNumPatterns = 0;
1162  // TODO Replace with delete/new if constructor is not sufficient
1163  memset (fHashTable, 0, sizeof(fHashTable));
1164 
1165  /// Call the recursive tree generator
1166  marklin (node, 0, detector);
1167 
1168  /// Finally, add the father node to the hash table
1169  node->SetNext(fHashTable[0]);
1170  fHashTable[0] = node;
1171 
1172  // Print the number of patterns
1173  QwDebug << "Generated fNumPatterns = " << fNumPatterns << " patterns" << QwLog::endl;
1174 
1175  // Return the node
1176  return node;
1177 }
treenode * fFather
Father node: the main entry point to the tree.
treenode ** fHashTable
int fNumPatterns
Number of valid patterns in the tree.
#define QwDebug
Predefined log drain for debugging output.
Definition: QwLog.h:60
void SetNext(treenode *next)
Set the next node.
Definition: treenode.h:105
static std::ostream & endl(std::ostream &)
End of the line.
Definition: QwLog.cc:299
void marklin(treenode *father, int level, QwDetectorInfo *detector)
Recursively generate the treesearch pattern database.
A treenode contains the bits that make up a tree pattern.
Definition: treenode.h:63

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

int QwTrackingTree::_readtree ( FILE *  file,
shorttree stb,
shortnode **  father,
int32_t  tlayers 
)
private

Recursive method to read the concise treesearch database from disk.

This function reads in the tree pattern database from a file.

It uses the shorttree and shortnode objects in order to reduce memory overhead.

Parameters
fileThe opened file
stbA shorttree
fatherA list of father nodes
tlayersThe number of layers(?)
Returns
Returns negative on error, otherwise number of references read

Go into an infinite loop while reading the file

Read the next record type

  • If we encounter a real pattern, then ...

read in the node(?) information

... and append the patterns to the father's sons

Read in the sons of this node

  • If we encounter a reference, then read in the reference

some error checking

still some error checking

create a new node

and append the alread read-in tree

'ref' to this node.

  • If we encounter an end token, then stop
  • If we encounter something else, then fail

Definition at line 1284 of file QwTrackingTree.cc.

References QwLog::endl(), fMaxRef, fRef, QwError, QwWarning, REALSON, REFSON, QwTracking::shortnode::SetNext(), QwTracking::shortnode::SetTree(), and SONEND.

Referenced by readtree().

1289 {
1290  /// Go into an infinite loop while reading the file
1291  for (;;) {
1292 
1293  /// Read the next record type
1294  int32_t type = fgetc(file);
1295 
1296 
1297  /// \li If we encounter a real pattern, then ...
1298  if (type == REALSON) {
1299 
1300  if (fRef >= fMaxRef) {
1301  QwWarning << "QTR: readtree failed. Rebuilding treefiles." << QwLog::endl
1302  << "More nodes in file than announced in header!" << QwLog::endl;
1303  return -1;
1304  }
1305 
1306  /// read in the node(?) information
1307  int32_t minlevel = 0;
1308  int32_t width = 0;
1309  int32_t bit[tlayers];
1310  for (int i = 0; i < tlayers; i++) bit[i] = 0; // initialize to zero
1311  if (fread(&minlevel, sizeof(int32_t), 1L, file) != 1 ||
1312  fread(&width, sizeof(int32_t), 1L, file) != 1 ||
1313  fread(&bit, sizeof(int32_t) * tlayers, 1L, file) != 1) {
1314  QwWarning << "QTR: readtree failed. Rebuilding treefiles." << QwLog::endl
1315  << "Header could not be read" << QwLog::endl;
1316  return -1;
1317  }
1318 
1319  int32_t ref = fRef;
1320  fRef++;
1321  (stb+ref)->fMinLevel = minlevel;
1322  (stb+ref)->fWidth = width;
1323  for (int i = 0; i < tlayers; i++)
1324  (stb+ref)->fBit[i] = bit[i];
1325 
1326  if (father) { /// ... and append the patterns to the father's sons
1327  shortnode* node = new shortnode();
1328  node->SetTree(stb + ref);
1329  node->SetNext(*father);
1330  (*father) = node;
1331  }
1332 
1333  /// Read in the sons of this node
1334  for (int32_t son = 0; son < 4; son++) {
1335  if (_readtree(file, stb, stb[ref].son + son, tlayers) < 0) {
1336  QwWarning << "An error... don't know what happened..." << QwLog::endl;
1337  return -1;
1338  }
1339  }
1340 
1341 
1342  /// \li If we encounter a reference, then read in the reference
1343  } else if (type == REFSON) {
1344 
1345  int32_t ref;
1346  if (fread (&ref, sizeof(ref), 1L, file) != 1) {
1347  QwWarning << "QTR: readtree failed. Rebuilding treefiles." << QwLog::endl
1348  << "Could not read reference field." << QwLog::endl;
1349  return -1;
1350  }
1351  if (ref >= fRef || ref < 0) { /// some error checking
1352  QwWarning << "QTR: readtree failed. Rebuilding treefiles." << QwLog::endl
1353  << "Reference field contains nonsense." << QwLog::endl;
1354  return -1;
1355  }
1356  if (!father) { /// still some error checking
1357  QwWarning << "QTR: readtree failed. Rebuilding treefiles." << QwLog::endl
1358  << "Father node invalid." << QwLog::endl;
1359  return -1;
1360  }
1361  shortnode* node = new shortnode(); /// create a new node
1362  node->SetTree(stb + ref); /// and append the alread read-in tree
1363  node->SetNext(*father); /// 'ref' to this node.
1364  (*father) = node;
1365 
1366 
1367  /// \li If we encounter an end token, then stop
1368  } else if (type == SONEND) {
1369  break;
1370 
1371 
1372  /// \li If we encounter something else, then fail
1373  } else {
1374  QwError << "Reading cached tree failed, rebuilding tree files." << QwLog::endl;
1375  return -1;
1376  }
1377  }
1378 
1379  return fRef;
1380 }
void SetNext(shortnode *next)
Set the next node.
Definition: shortnode.h:62
#define SONEND
int _readtree(FILE *file, shorttree *stb, shortnode **father, int32_t tlayers)
Recursive method to read the concise treesearch database from disk.
#define REALSON
int fRef
Reference.
#define REFSON
static std::ostream & endl(std::ostream &)
End of the line.
Definition: QwLog.cc:299
void SetTree(shorttree *tree, int ntrees=1)
Set the tree.
Definition: shortnode.h:74
Similar to a nodenode.
Definition: shortnode.h:38
#define QwWarning
Predefined log drain for warnings.
Definition: QwLog.h:45
int fMaxRef
Maximum number of references in the cached tree file.
#define QwError
Predefined log drain for errors.
Definition: QwLog.h:40

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

int QwTrackingTree::_writetree ( treenode tn,
FILE *  fp,
int32_t  tlayers 
)
private

Recursive method for pulling in the concise treesearch search database.

This function iteratively writes the patterns to the database.

Parameters
tnTree node to write to file
fpFile pointer to write to
tlayersNumber of layers
Returns
Number of references written

pattern has never been written

set its reference

and write all pattern data

write the sons of this treenode (and their sons, etc)

set the marker for end of sonlist

else - only write a reference to

a former written pattern

Definition at line 1188 of file QwTrackingTree.cc.

References QwTracking::treenode::fBit, QwTracking::treenode::fMinLevel, QwTracking::treenode::fRef, fRef, QwTracking::treenode::fSon, QwTracking::treenode::fWidth, QwTracking::nodenode::GetTree(), QwTracking::nodenode::next(), REALSON, REFSON, and SONEND.

Referenced by writetree().

1189 {
1190  nodenode* nd;
1191 
1192  if (tn->fRef == -1) {/// pattern has never been written
1193  tn->fRef = fRef++;/// set its reference
1194 
1195  if (fputc (REALSON, fp) == EOF || /// and write all pattern data
1196  fwrite(&tn->fMinLevel, sizeof(int), 1L, fp) != 1 ||
1197  fwrite(&tn->fWidth, sizeof(int), 1L, fp) != 1 ||
1198  fwrite( tn->fBit, sizeof(int), (size_t) tlayers, fp) != (unsigned int)tlayers )
1199  return -1;
1200 
1201  for (int i = 0; i < 4; i++) {
1202  nd = tn->fSon[i];
1203  while (nd) {///write the sons of this treenode (and their sons, etc)
1204  if (_writetree(nd->GetTree(), fp, tlayers) < 0)
1205  return -1;
1206  nd = nd->next();
1207  }
1208  if (fputc (SONEND, fp) == EOF) /// set the marker for end of sonlist
1209  return -1;
1210  }
1211  } else { /// else - only write a reference to
1212  if (fputc (REFSON, fp) == EOF || /// a former written pattern
1213  fwrite (&tn->fRef, sizeof(tn->fRef), 1L, fp) != 1)
1214  return -1;
1215  }
1216  return fRef;
1217 }
#define SONEND
treenode * GetTree() const
Get the tree.
Definition: nodenode.h:66
#define REALSON
int fRef
Reference.
#define REFSON
int fMinLevel
Minimum level at which this node is valid.
Definition: treenode.h:79
int fWidth
Width in bins of the hit pattern.
Definition: treenode.h:87
int fRef
Reference of this node when writing to file.
Definition: treenode.h:90
nodenode * fSon[4]
Each tree has four son nodes.
Definition: treenode.h:95
int * fBit
Hit pattern, one bin specified per detector layer.
Definition: treenode.h:84
nodenode * next() const
Get the next node (non-standard notation)
Definition: nodenode.h:78
int _writetree(treenode *tn, FILE *fp, int32_t tlayers)
Recursive method for pulling in the concise treesearch search database.
A nodenode is used as a pointer which links treenodes to their siblings.
Definition: nodenode.h:42

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

int QwTrackingTree::consistent ( treenode testnode,
int  level,
QwDetectorInfo detector 
)

Determines whether the pattern is geometrically possible.

...

Parameters
testnode
level
detector
Returns

the acceptable limits at the current plane

the position of the left(min) edge of the last layer

the slopes which set the bounds for acceptable hits.

radial offset between upstream and downstream HDC chambers

the left(min) and right(max) edges of the bin at the current plane

dy is decreased by a larger first layer bin

and increased by a larger last layer bin

get the initial bounding slopes

check if the bin in the 3rd layer is within the bounds

this layer is offset

if the hit is out of bounds, cut the pattern

this hit requires the boundaries to be narrowed

check if the bin in the 2nd layer is within the bounds

this layer is not offset

if the hit is out of bounds, cut the pattern

else, this is a good pattern

Definition at line 215 of file QwTrackingTree.cc.

References QwLog::endl(), QwTracking::treenode::fBit, fGeometry, fMaxSlope, fNumLayers, QwDetectorInfo::GetElementSpacing(), QwDetectorInfo::GetNumberOfElements(), QwDetectorInfo::GetPlaneOffset(), QwDetectorInfo::GetRegion(), QwDetectorInfo::GetType(), QwDetectorInfo::GetZPosition(), kRegionID2, kRegionID3, kTypeDriftHDC, kTypeDriftVDC, Qw::m, QwError, and QwWarning.

Referenced by marklin().

219 {
220  //###############
221  // DECLARATIONS #
222  //###############
223 
224  /* For faster access to pattern in tst->bit */
225  int *bitpattern = testnode->fBit;
226 
227  double x0; /* Bitnumber in the first tree-detector,
228  i.e. treelayer 0 */
229  double x3e, x3a; /* Bitnumber in last / last checked layer */
230  double adda, adde;
231  double dze, dza;
232 
233 
234  //###########
235  // REGION 2 #
236  //###########
237  if (detector->GetType() == kTypeDriftHDC && detector->GetRegion() == kRegionID2) {
238  int layer;
239  int templayers = 4;
240  int tlaym1 = templayers - 1;
241  double z[templayers];
242  double binwidth, y0, dy;
243 
244  double xmin, xmax; /// the acceptable limits at the current plane
245  double xf; /// the position of the left(min) edge of the last layer
246  double mL, mR; /// the slopes which set the bounds for acceptable hits.
247  double off; /// radial offset between upstream and downstream HDC chambers
248  double xiL, xiR; /// the left(min) and right(max) edges of the bin at the current plane
249 
250  y0 = binwidth = dy = off = 0.0;
251 
252 
253  // Find the z position of each tree-detector relative to the first tree-detector
254 
255  // Loop through each plane
256  layer = 0;
257  for (std::vector<QwDetectorInfo*>::iterator iter = fGeometry.begin();
258  iter != fGeometry.end() && layer < templayers;
259  iter++, layer++) {
260  QwDetectorInfo* det = *iter;
261 
262  // Get z position of this plane
263  double zv = det->GetZPosition();
264 
265  // Compute the relative position to the upstream plane
266  if (layer > 0) {
267  z[layer] = zv - z[0];
268  if (z[layer] < z[0]) {
269  QwError << "Region 2 planes are out of order" << QwLog::endl;
270  exit(1);
271  }
272  // the offset distance between the first and last planes of this wire direction
273  if(layer == templayers-1)
274  dy = off = fabs (det->GetPlaneOffset()-y0);
275  } else {
276 
277  z[0] = zv;
278  // the binwidth at this level
279  binwidth = det->GetNumberOfElements() * det->GetElementSpacing() / (1 << level);
280  y0=fabs(det->GetPlaneOffset()); // the first plane's radial distance
281  }
282  }
283 
284 
285  // Set the first plane's z position to zero
286  z[0] = 0.0;
287 
288  /* initial setting for the line check using the first and
289  the last tree-detectors */
290  dza = z[tlaym1];
291  x0 = bitpattern[0]; /* Fetch the pattern for 1st tree det */
292  xf = bitpattern[tlaym1]; /* Fetch the pattern for last tree det */
293 
294  /* first check if a straight track through the bins in the
295  first and the last tree-detectors fulfill the max angle
296  condition set in QwOptions */
297  dy -= x0 * binwidth; /// dy is decreased by a larger first layer bin
298  dy += xf * binwidth; /// and increased by a larger last layer bin
299 
300  if (fabs (dy / dza) > fMaxSlope) {
301  return 0;
302  }
303 
304  /* check if all the bits are along a straight line by
305  looping through each pair of outer tree-detectors and
306  seeing if the bins on the enclosed tree-detectors are
307  along a straight line */
308  x0 = bitpattern[0] * binwidth;
309  xf = bitpattern[tlaym1] * binwidth + off;
310  mL = mR = (xf - x0) / z[tlaym1]; /// get the initial bounding slopes
311  layer = 2; /// check if the bin in the 3rd layer is within the bounds
312  xmin = mL * z[layer] + x0;
313  xmax = mR * z[layer] + x0 + binwidth;
314  xiL = bitpattern[layer] * binwidth + off;///this layer is offset
315  xiR = (bitpattern[layer] + 1) * binwidth + off;
316  if (xiL > xmax || xiR < xmin) {
317  return 0; /// if the hit is out of bounds, cut the pattern
318  }
319  if (xiR > xmax) mL = (xiL - x0) / z[layer]; /// this hit requires the boundaries to be narrowed
320  if (xiL < xmin) mR = (xiR - x0) / z[layer];
321  layer = 1; /// check if the bin in the 2nd layer is within the bounds
322  xmin = mL * z[layer] + x0;
323  xmax = mR * z[layer] + x0 + binwidth;
324  xiL = bitpattern[layer] * binwidth; /// this layer is not offset
325  xiR = (bitpattern[layer] + 1) * binwidth;
326  if (xiL > xmax || xiR < xmin) {
327  return 0; /// if the hit is out of bounds, cut the pattern
328  }
329  return 1; /// else, this is a good pattern
330 
331 
332  //###########
333  // REGION 3 #
334  //###########
335  } else if (detector->GetType() == kTypeDriftVDC && detector->GetRegion() == kRegionID3) {
336 
337  int templayers = 8;
338 
339 
340  double xf = 0, zf = 0.0;
341  double z[templayers];
342 
343  // Distance between wires, assumed normalized to one
344  double cellwidth = 1;
345  int firstnonzero = 0;
346 
347  for (int layer = 0; layer < templayers; layer++) {
348  if (bitpattern[layer]) firstnonzero++;
349  if (firstnonzero && ! bitpattern[layer]) templayers = layer + 1;
350  }
351 
352  /* ----- find the z position of each tree-detector relative to
353  the first tree-detector ----- */
354 
355  z[0] = 0;
356  for (int layer = 1; layer < templayers; layer++) {
357  z[layer] = z[layer-1] + cellwidth;
358  }
359 
360  /* Get the layer with the largest bit value (dependent on rules in marklin)*/
361  for (int layer = 0; layer < templayers; layer++) {
362  if (bitpattern[layer] >= xf) {
363  zf = layer;
364  xf = bitpattern[layer];
365  }
366  }
367 
368  /* ----- initial setting for the line check using the first and
369  the last tree-detectors ----- */
370  dze = dza = zf;
371  x0 = bitpattern[0]; /* Fetch the pattern for 1st tree-det. */
372  x3a = x3e = xf; /* Fetch the pattern for last tree-det. */
373  x3e++;
374 
375  /* ----- first check if a straight track through the bins in the
376  first and the last tree-detectors fulfill the max angle
377  condition ----- */
378  double m_min = -((double) fNumLayers - 1) / ((double) (1 << level) - 1);
379  double m_max = -(4.0 - 1.0) / ((double) (1 << level) - 1);
380  double m = -((double) zf) / ((double) (xf - x0));
381 
382  //cout << m_min << " " << m << " " << m_max << endl;
383  if (m < m_min || m > m_max) return 0;
384 
385  /* ----- check if all the bits are along a straight line by
386  looping through each pair of outer tree-detectors and
387  seeing if the bins on the enclosed tree-detectors are
388  along a straight line ----- */
389 
390  /* loop from the back tree-detectors forward */
391  for (int layer = (int) zf - 1; layer > 0; layer--) {
392 
393  adda = (x0 - bitpattern[layer]) * dza + (x3a - x0) * z[layer];
394  if (adda <= -dza || dza <= adda)
395  return 0;
396 
397  adde = (x0 - bitpattern[layer]) * dze + (x3e - x0 - 1) * z[layer];
398  if (adde <= -dze || dze <= adde)
399  return 0;
400 
401  if (layer > 1) {
402  if (adda > 0) {
403  x3e = bitpattern[layer] + 1;
404  dze = z[layer];
405  }
406  if (adde < 0) {
407  x3a = bitpattern[layer];
408  dza = z[layer];
409  }
410  }
411  }
412  return 1;
413 
414 
415  //###########
416  // OR ELSE #
417  //###########
418  } else {
419  QwWarning << "Warning: no support for the creation of this search tree." << QwLog::endl;
420  return 0;
421  }
422 }
static const double m
Definition: QwUnits.h:63
EQwRegionID GetRegion() const
double GetPlaneOffset() const
EQwDetectorType GetType() const
int * fBit
Hit pattern, one bin specified per detector layer.
Definition: treenode.h:84
static std::ostream & endl(std::ostream &)
End of the line.
Definition: QwLog.cc:299
double fMaxSlope
Maximum allowed slope for tracks in this detector.
double GetElementSpacing() const
QwGeometry fGeometry
Detector (or set of detectors) represented by this search tree.
double GetZPosition() const
#define QwWarning
Predefined log drain for warnings.
Definition: QwLog.h:45
int GetNumberOfElements() const
unsigned int fNumLayers
Number of detector planes.
#define QwError
Predefined log drain for errors.
Definition: QwLog.h:40

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

treenode * QwTrackingTree::existent ( treenode node,
int  hash 
)

Search for a node in the search tree.

Starting with the hash value, the node is searched in the search tree. When the bits are identical to an entry in the search tree, that entry is returned. Otherwise, when no match is found, null is returned.

Parameters
nodeNode to search for
hashHash value of the node
Returns
Node in the tree, or null if not found

Definition at line 437 of file QwTrackingTree.cc.

References QwTracking::treenode::fBit, fHashTable, fNumLayers, and QwTracking::treenode::GetNext().

Referenced by marklin().

438 {
439  treenode *walk = fHashTable[hash];
440  while (walk) {
441  if (! memcmp (node->fBit, walk->fBit, fNumLayers * sizeof(node->fBit[0])))
442  return walk; /* found it! */
443  walk = walk->GetNext(); /* nope, so look at the next pattern */
444  }
445  return 0;
446 }
treenode ** fHashTable
treenode * GetNext() const
Get the next node.
Definition: treenode.h:112
int * fBit
Hit pattern, one bin specified per detector layer.
Definition: treenode.h:84
A treenode contains the bits that make up a tree pattern.
Definition: treenode.h:63
unsigned int fNumLayers
Number of detector planes.

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

QwTrackingTreeRegion * QwTrackingTree::inittree ( const string &  filename,
int  levels,
int  tlayer,
double  width,
QwDetectorInfo detector,
bool  regenerate 
)

This function checks whether a pattern database requested by inittree already exists. If not, it will call _inittree to create the database, write it out, then read it in again. To force the generation of new databases, simply remove the old ones from the 'trees' directory. If options are set to create a different level of pattern resolution, this function will automatically create the new databases.

Try to read in an existing database

Generate a new tree database

Write the generated tree to disk for faster access later

Read it in again to get the shorter tree search format

Definition at line 1089 of file QwTrackingTree.cc.

References _inittree(), QwLog::endl(), fMaxLevel, fNumLayers, fNumPatterns, QwError, QwMessage, QwVerbose, readtree(), and writetree().

Referenced by QwTrackingWorker::InitTree().

1096 {
1097 // TODO: This routine assumes that the directory 'trees' exists and doesn't create it itself. (wdconinc)
1098  QwTrackingTreeRegion *trr = 0;
1099  fNumLayers = tlayer;
1100  fMaxLevel = levels + 1;
1101 
1102  if (tlayer == 0) return 0;
1103 
1104  // TODO: I disabled the next part to get past a segfault (wdconinc, 08-Dec-2008)
1105  // (wdc, 29-May-2009) no wonder it segfaults, no malloc/new yet on trr
1106 // cout << "trr->searchable = " << (trr? trr->searchable:-1) << endl;
1107 // if (region == kRegionID3 && (dir == kDirectionX || dir == kDirectionY)) {
1108 // /// region 3 does not have an x or y direction,
1109 // /// so tag them as unsearchable for the treedo function.
1110 // trr->searchable = 0;
1111 // return trr;
1112 // }
1113 
1114  /*! Try to read in an existing database */
1115  QwVerbose << "Attempting to read tree from " << filename << QwLog::endl;
1116  trr = readtree(filename, levels, tlayer, width, regenerate);
1117  if (trr == 0) {
1118 
1119  /// Generate a new tree database
1120  treenode* back = _inittree (tlayer, detector);
1121  if (! back) {
1122  QwError << "Search tree could not be built." << QwLog::endl;
1123  exit(1);
1124  }
1125  QwMessage << " Generated " << fNumPatterns << " patterns" << QwLog::endl;
1126 
1127  /// Write the generated tree to disk for faster access later
1128  if (writetree(filename, back, levels, tlayer, width) < 0) {
1129  QwError << "Search tree could not be written." << QwLog::endl;
1130  exit(1);
1131  }
1132  QwMessage << " Cached in " << filename << QwLog::endl;
1133 
1134  // TODO Here we need to delete something, I think (wdc)
1135 
1136  /// Read it in again to get the shorter tree search format
1137  trr = readtree(filename, levels, tlayer, width, 0);
1138  if (trr == 0) {
1139  QwError << "New tree could not be read." << QwLog::endl;
1140  exit(1);
1141  }
1142  }
1143  return trr;
1144 }
#define QwMessage
Predefined log drain for regular messages.
Definition: QwLog.h:50
A container for the pattern databases for each detector region.
#define QwVerbose
Predefined log drain for verbose messages.
Definition: QwLog.h:55
int fNumPatterns
Number of valid patterns in the tree.
treenode * _inittree(int32_t tlayer, QwDetectorInfo *detector)
Recursive method to initialize and generate the treesearch database.
QwTrackingTreeRegion * readtree(const string &filename, int levels, int tlayers, double rwidth, bool skipreading)
static std::ostream & endl(std::ostream &)
End of the line.
Definition: QwLog.cc:299
long writetree(const string &filename, treenode *tn, int levels, int tlayers, double width)
This function initializes the output file. It then calls the iterative _writetree function to fill th...
A treenode contains the bits that make up a tree pattern.
Definition: treenode.h:63
unsigned int fNumLayers
Number of detector planes.
#define QwError
Predefined log drain for errors.
Definition: QwLog.h:40

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void QwTrackingTree::marklin ( treenode father,
int  level,
QwDetectorInfo detector 
)

Recursively generate the treesearch pattern database.

This recursive function generates the treesearch database. For a given father node, it generates the 2^fNumLayers possible son hit patterns. Each son pattern is checked to see if it is consistent with a trajectory through the detector. If it is consistent, it is inserted into the tree search database and then, by a recursive call to this function, its sons are generated. marklin has different code for the different regions due to the significant differences between them.

Reminder about the bit pattern:

  • there are n levels of bin division, so 8,4,2,1 bins for 4 levels,
  • there are rows corresponding with the HDC planes or VDC wires.

HDC planes (spaces between the 5 levels of bin division) for 16 bins in wire coordinate (e.g. 16 wires) and zero distance resolution

* plane 1: ......|......... ...|.... .|.. |. |
* plane 2: .......|........ ...|.... .|.. |. |
* plane 3: ........|....... ....|... ..|. .| |
* plane 4: .........|...... ....|... ..|. .| |
*

VDC wires (spaces between the 4 levels of bin division) for 8 bins in drift distance and zero distance resolution

* wire 159: |....... |... |. |
* wire 160: .|...... |... |. |
* wire 161: ..|..... .|.. |. |
* wire 162: ...|.... .|.. |. |
* wire 163: .....|.. ..|. .| |
* wire 164: ......|. ...| .| |
* wire 165: .......| ...| .| |
*

When constructing the hit patterns, we start from level 0 (i.e. 1 bin). There are 2^fNumLayers possible hit patterns, in order of generation:

* plane 1: 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0
* plane 2: 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0
* plane 3: 1 1 1 1 0 0 0 0 1 1 1 1 0 0 0 0
* plane 4: 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0
*

The number indicates the bin in this particular level of bin division. For the lowest level 0 there are two bins at every layer. The hit is either in bin 0 or bin 1.

At the next level, there are again 2^fNumLayers possible hit patterns, based on the hit pattern of the previous level. The relation from the hit pattern at the previous level and the 16 binary combinations above to the hit pattern at this level is given by bin at this level = 2^(bin at previous level) - 1 + (combination).

For the level 1 (with 4 bins), and hit pattern 0,0,1,1 at level 0:

* plane 1: e.g. 0 + 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0
* plane 2: 0 + 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0
* plane 3: 1 + 1 1 1 1 0 0 0 0 1 1 1 1 0 0 0 0
* plane 4: 1 + 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0
*

This works out as follows:

* plane 1: 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0
* plane 2: 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0
* plane 3: 3 3 3 3 2 2 2 2 3 3 3 3 2 2 2 2
* plane 4: 3 3 3 3 3 3 3 3 2 2 2 2 2 2 2 2
*

For the combination 1,0,3,2 this can be visualized as:

* plane 1: |. (0) + 1 -> .|.. (1)
* plane 2: |. (0) + 0 -> |... (0)
* plane 3: .| (1) + 1 -> ...| (3)
* plane 4: .| (1) + 0 -> ..|. (2)
*

Clearly, some of the combinations do not correspond to a straight track. The combination 1,0,3,2 is an example. To throw out these invalid tracks we calculate the largest and smallest bin and compare it to the difference between the first and last bin.

Also, the combination 0,0,2,2 is basically identical to 1,1,3,3 up to a shift. They are therefore treated as identical track candidates.

Parameters
fatherFather node
levelLevel of precision
detectorDetector info

Definition at line 553 of file QwTrackingTree.cc.

References consistent(), QwLog::endl(), existent(), QwTracking::treenode::fBit, fHashSize, fHashTable, QwTracking::treenode::fMaxLevel, fMaxLevel, QwTracking::treenode::fMinLevel, fNumLayers, fNumPatterns, fNumPlanes, fNumWires, QwTracking::treenode::fSon, QwTracking::treenode::fWidth, QwDetectorInfo::GetRegion(), QwDetectorInfo::GetType(), kRegionID2, kRegionID3, kTypeDriftHDC, kTypeDriftVDC, Qw::min, nodeexists(), QwError, QwTracking::nodenode::SetNext(), QwTracking::treenode::SetNext(), and QwTracking::nodenode::SetTree().

Referenced by _inittree().

557 {
558  // Local copy of the father node
559  treenode son = *father;
560 
561  // If we have reached the maximum depth of the tree, do nothing.
562  if (level == fMaxLevel) return;
563 
564  //###########
565  // REGION 2 #
566  //###########
567  if (detector->GetRegion() == kRegionID2 && detector->GetType() == kTypeDriftHDC) {
568 
569  // There are four u, v, or x wire planes.
570  fNumPlanes = 4;
571 
572  // Loop through all possible variations of the bit pattern.
573  //
574  // In binary this will run over 1111, 1110, 1101,..., 0010, 0001, 0000,
575  // where each bit position is a plane (here with four planes).
576  int plane_combination = (1 << fNumPlanes); // i.e. 2^fNumPlanes
577  while (plane_combination--) {
578  int min_bin = 1;
579  int max_bin = 0;
580  int offs = 0;
581  int flip = 0;
582  for (unsigned int plane = 0; plane < fNumPlanes; plane++) {
583  // If this plane is active in this combination
584  if (plane_combination & (1 << plane)) {
585  son.fBit[plane] = (father->fBit[plane] << 1) + 1;
586  } else {
587  son.fBit[plane] = (father->fBit[plane] << 1);
588  }
589  // Keep track of minimum and maximum bin at any plane
590  min_bin = (int) std::min (min_bin, son.fBit[plane]);
591  max_bin = (int) std::max (max_bin, son.fBit[plane]);
592  }
593 
594  // Width in bins between first and last planes
595  son.fWidth = son.fBit[fNumPlanes-1] - son.fBit[0];
596 
597  /* Check that the hits on the internal tree-detector planes
598  are enclosed by the hits on the two outer tree-detector
599  planes. If not, the pattern cannot have a straight line
600  put through it, so just stop with it.
601 
602  For example, a straight line cannot be put through the
603  pattern 1 3 2 because the bin for the middle tree-
604  detector (3) is not enclosed by the bins for the two
605  outer detectors (1 and 2). */
606 
607  if (max_bin - min_bin > abs(son.fWidth))
608  continue;
609 
610  /* Compute the offset of this hit pattern and, if non-zero,
611  shift the pattern over by the offset */
612 
613  if (min_bin) { // If there is a non-zero offset, then
614  offs = 1; // set "pattern is offset" flag, and shift down
615  for (unsigned int plane = 0; plane < fNumPlanes; plane++)
616  son.fBit[plane]--; // ... so decrement is sufficient
617  }
618 
619  /* See if the hit pattern is a flipped pattern and, if so,
620  set the "pattern is flipped" flag and flip the pattern */
621 
622  if (son.fWidth < 0) { /* If hit pattern is flippable, then */
623  flip = 2; /* (1) set "pattern is flipped" flag, and */
624  son.fWidth = -son.fWidth; /* (2) flip the hit pattern */
625  for (unsigned int plane = 0; plane < fNumPlanes; plane++)
626  son.fBit[plane] = son.fWidth - son.fBit[plane];
627  }
628 
629  /* Compute the width (in bins) of the hit pattern */
630  son.fWidth++;
631  /* Remember: bins are numbered from 0 to n,
632  so we need to add 1 here to compute the width */
633 
634  /* Look at the other sons of this father to see if this
635  particular son is already known to the father */
636  treenode* sonptr = nodeexists (father->fSon[offs + flip], &son);
637 
638  /* Compute the hash value of this particular son for use
639  with the hash search of the full treesearch database */
640  int hash = (son.fBit[fNumPlanes-1] + son.fBit[1]) % fHashSize;
641 
642  /* initializes the "insert pattern" flag */
643  int insert_hitpattern = 1; /* right now, set this flag to insert it */
644 
645  /* if the hit pattern for this son was not located when
646  the other sons of this father were searched, then look
647  through the entire treesearch database for this
648  particular hit pattern. If the hit pattern is still not
649  found, then consider inserting it into the treesearch
650  database. Otherwise, adjust the treenode with the like
651  hit pattern so that its hit pattern is valid at this
652  level of the treesearch division.
653  */
654  if (! sonptr && 0 == (sonptr = existent (&son, hash))) {
655 
656 
657  /* the pattern is completely unknown. So, now check if
658  it is consistent with a straight line trajectory
659  through the tree-detectors whose slope is within the
660  window set by the QwOptions parameter fMaxSlope. */
661 
662  if (consistent (&son, level+1, detector)) {
663  /* the pattern is consistent, so now insert it into the
664  treesearch database by: */
665  /* 1st: Create space for this new treenode */
666  sonptr = new treenode(son);
667 
668  /* 2nd: Since this treenode has no sons at the moment,
669  zero the son pointers for this treenode */
670  sonptr->fSon[0] = sonptr->fSon[1] =
671  sonptr->fSon[2] = sonptr->fSon[3] = 0;
672 
673  /* 3rd: Since the hit pattern in this treenode is only
674  known to be valid at this level of bin divsion,
675  set the minimum and maximum valid level for this
676  treenode to this level */
677 
678  sonptr->fMaxLevel = sonptr->fMinLevel = level;
679 
680  /* 4th: Update the hash table so that this
681  treenode will be examined during future searches
682  of the entire treesearch database. */
683  sonptr->SetNext(fHashTable[hash]); /* Append the pattern onto the */
684  /* end of the hash table. */
685  fHashTable[hash] = sonptr; /* update the hash table. */
686 
687  fNumPatterns++;
688 
689  /* 5th: Call marklin() recursively to generate the sons of
690  this tree node */
691  marklin (sonptr, level+1, detector);
692 
693  } else {
694 
695  /* the pattern is not consistent with a line, so just
696  reject it. */
697  insert_hitpattern = 0; /* set "insert pattern" flag to not keep it */
698  /*
699  cout << "inconsistent" << endl;
700  for (int k = 0; k < fNumPlanes; k++) {
701  for (int l = 0; l < 2 << level; l++) {
702  if (son.fBit[k] == l)
703  cout << "x ";
704  else
705  cout << "0 ";
706  }
707  cout << endl;
708  }
709  */
710  }
711  /* the pattern was found when the entire database was
712  searched above, so now the matching treenode for it
713  needs to be updated so that it will be valid this level
714  of bin division. */
715 
716  } else if ((sonptr->fMinLevel > level && consistent(&son, level+1, detector))
717  || sonptr->fMaxLevel < level) {
718 
719  /* 1st: Update the levels of the found treenode to
720  include this level */
721  sonptr->fMinLevel = (int) std::min (level, sonptr->fMinLevel);
722  sonptr->fMaxLevel = (int) std::max (level, sonptr->fMaxLevel);
723 
724  fNumPatterns++;
725 
726  /* 2nd: Update the levels of all the sons for this
727  treenode */
728  marklin (sonptr, level+1, detector);
729  }
730 
731  /* Since one of the recursive call to marklin()
732  for building a son's generation could have already
733  inserted the hit pattern for this son into the
734  database, a final check is made to see if the hit
735  pattern is already in the database before actually
736  inserting the treenode into the database */
737  if (insert_hitpattern && /* "insert pattern"
738  flag is set and */
739  ! nodeexists (father->fSon[offs+flip], &son)) { /* final check if hit
740  pattern is already
741  in the database */
742 
743  nodenode* nodptr = new nodenode(); /* create a nodenode */
744  nodptr->SetNext(father->fSon[offs+flip]); /* append it to the son list */
745  nodptr->SetTree(sonptr);
746  father->fSon[offs+flip] = nodptr;
747  }
748 
749  } // end of loop over bins
750 
751  } // end of region 2
752 
753  //###########
754  // REGION 3 #
755  //###########
756  else if (detector->GetRegion() == kRegionID3 && detector->GetType() == kTypeDriftVDC) {
757 
758  // There are 8 wires in each demultiplexed VDC group
759  fNumWires = 8;
760 
761  int offs = 1;
762  int maxs = 0;
763  int flip = 0;
764 
765  int wire_combination = (1 << fNumWires);
766  while (wire_combination--) { // loop through all possibilities
767  for (unsigned int wire = 0; wire < fNumWires; wire++) { // this loop creates each possible pattern
768 
769  if (wire_combination & (1 << wire)) {
770  son.fBit[wire] = (father->fBit[wire] << 1) + 1;
771  } else {
772  son.fBit[wire] = (father->fBit[wire] << 1);
773  }
774  offs = (int) std::min (offs,son.fBit[wire]);
775  maxs = (int) std::max (maxs,son.fBit[wire]);
776  }
777 
778 
779  // Cut patterns in which there are hits that lie outside the road
780  // between the first and last hits, i.e. :
781  // X 0 0 X
782  // 0 X or X 0
783  // 0 X 0 X
784  // X 0 0 X
785  son.fWidth = son.fBit[fNumWires-1] - son.fBit[0];
786 
787  int cutback = 0;
788  int cutflag = 0;
789  for (unsigned int wire = 1; wire < fNumWires; wire++) {
790  if (son.fBit[wire] < son.fBit[wire-1]) { // if the bin decreases
791  if (son.fBit[wire]) // and it's nonzero cut it
792  cutflag++;
793  if (! son.fBit[wire]) { // but if it's zero, make sure it stays zero
794  cutback++;
795  if (cutback == 1) son.fWidth = son.fBit[wire-1] - son.fBit[0];
796  }
797  }
798  if (son.fBit[wire] && cutback)
799  cutflag++;
800  }
801  if (cutflag) {
802  /*
803  cout << "Cut :" ;
804  for (unsigned int wire = 0; wire < fNumWires; wire++)
805  cout << son.fBit[wire] << " " ;
806  cout << endl;*/
807  continue;
808  }
809  if (offs) { /* If there is an offset, so */
810  /*cout << "Offset :" ;
811  for (unsigned int wire = 0; wire < fNumWires; wire++)
812  cout << son.fBit[wire] << " " ;
813  cout << endl;
814  */
815  for (unsigned int wire = 0; wire < fNumWires; wire++) /* shift all hits over this offset */
816  son.fBit[wire]--;
817  }
818  if (son.fWidth < 0) {
819  /*cout << "Flip :" ;
820  for (unsigned int wire = 0; wire < fNumWires; wire++)
821  cout << son.fBit[wire] << " " ;
822  cout << endl;
823  */
824  flip = 2;
825  son.fWidth = -son.fWidth;
826  for (unsigned int wire = 0; wire < fNumWires; wire++)
827  son.fBit[wire] = son.fWidth - son.fBit[wire];
828  }
829  son.fWidth++;
830 
831  treenode* sonptr = nodeexists(father->fSon[offs+flip], &son);
832 
833  int hash = (son.fBit[fNumWires-1] + son.fBit[1]) % fHashSize;
834 
835 
836  /*if(sonptr){for(j=0;j<fNumWires;j++)cout << son.fBit[j] << " " ;cout << "exists" << endl;}
837  else{ for(j=0;j<fNumWires;j++)cout << son.fBit[j] << " " ;cout << endl;}
838  cout << "hash = " << son.fBit[fNumWires-1] << "," << son.fBit[1] << "," << hshsiz << "," << hash << endl;
839  cout << "level : " << level << endl;
840  cout << "bits : " << son.fWidth << endl;*/
841  int insert_hitpattern = 1;
842  if (! sonptr&& 0 == (sonptr = existent(&son, hash))) {
843  if (consistent (&son, level+1, detector)) {
844  //cout << "Adding treenode..." << endl;
845 
846  sonptr = new treenode(son);
847  sonptr->fSon[0] = sonptr->fSon[1] =
848  sonptr->fSon[2] = sonptr->fSon[3] = 0;
849  sonptr->fMaxLevel =
850  sonptr->fMinLevel = level;
851 
852  sonptr->SetNext(fHashTable[hash]);
853  fHashTable[hash] = sonptr;
854 
855  fNumPatterns++;
856 
857  marklin (sonptr, level+1, detector);
858 
859  } else { /*
860 
861  cout << "inconsistent" << endl;
862  for(int k=0;k<fNumWires;k++){
863  for(int l=0;l< 2<<(level);l++){
864  if(son.fBit[k]==l)cout << "x ";
865  else cout << "0 ";
866  }
867  cout << endl;
868  }
869  */
870  insert_hitpattern = 0;
871  }
872  }
873  else if ( (sonptr->fMinLevel > level
874  && consistent(&son, level+1, detector) )
875  || sonptr->fMaxLevel < level) {
876  sonptr->fMinLevel = (int) std::min (level,sonptr->fMinLevel);
877  sonptr->fMaxLevel = (int) std::max (level,sonptr->fMaxLevel);
878 
879  marklin (sonptr, level+1, detector);
880  }
881 
882  if (insert_hitpattern /* "insert pattern" flag is set and */
883  && ! nodeexists (father->fSon[offs+flip], &son)) {
884 
885  nodenode* nodptr = new nodenode(); /* create a nodenode */
886  nodptr->SetNext(father->fSon[offs+flip]); /* append it to the son list */
887  nodptr->SetTree(sonptr);
888  father->fSon[offs+flip] = nodptr;
889  }
890  }
891 
892  } // end of region 3
893 
894  //########
895  // OTHER #
896  //########
897  else {
898 
899  QwError << "What are you doing here?!? Call the software expert now!" << QwLog::endl;
900 
901  int layer_combination = (1 << fNumLayers);
902  while (layer_combination--) {
903  int offs = 1;
904  int maxs = 0;
905  int flip = 0;
906 
907  for (unsigned int layer = 0; layer < fNumLayers; layer++) {
908  //cout << "for("<< layer << "," << fNumLayers << "," <<
909  //father->fBit[layer] << "," << (1<<layer) << "," << layer_combination << ")" << endl;
910 
911 
912  if (layer_combination & (1 << layer)) {
913  son.fBit[layer] = (father->fBit[layer] << 1) + 1;
914  } else {
915  son.fBit[layer] = (father->fBit[layer] << 1);
916  }
917  offs = (int) std::min (offs, son.fBit[layer]);
918  maxs = (int) std::max (maxs, son.fBit[layer]);
919  }
920  son.fWidth = son.fBit[fNumLayers-1] - son.fBit[0];
921  //cout << "(" << maxs << "," << offs << "," << son.fWidth << ")" << endl;
922  if (maxs - offs > abs(son.fWidth)) {
923  //cout << "yes" << endl;
924  continue;
925  }
926 
927  if (offs)
928  for (unsigned int layer = 0; layer < fNumLayers; layer++)
929  son.fBit[layer]--;
930 
931  if (son.fWidth < 0) {
932  flip = 2;
933  son.fWidth = -son.fWidth;
934  for (unsigned int layer = 0; layer < fNumLayers; layer++)
935  son.fBit[layer] = son.fWidth - son.fBit[layer];
936  }
937  son.fWidth++;
938 
939  treenode* sonptr = nodeexists(father->fSon[offs+flip], &son);
940 
941  int hash = (son.fBit[fNumLayers-1] + son.fBit[1]) % fHashSize;
942  //cout << "hash = " << hash << endl;
943  int insert_hitpattern = 1;
944 
945  if (! sonptr && 0 == (sonptr = existent(&son, hash))) {
946  //cout << "Pattern is unknown" << endl;
947  //cout << "-----------" << endl;
948  //son.print();
949  //cout << "-----------" << endl;
950  if (consistent(&son, level+1, detector)) {
951  //cout << "Adding treenode..." << endl;
952  sonptr = new treenode(son);
953  sonptr->fSon[0] = sonptr->fSon[1] =
954  sonptr->fSon[2] = sonptr->fSon[3] = 0;
955  sonptr->fMaxLevel =
956  sonptr->fMinLevel = level;
957 
958  sonptr->SetNext(fHashTable[hash]);
959  fHashTable[hash] = sonptr;
960 
961  marklin (sonptr, level+1, detector);
962  }
963  else
964  insert_hitpattern = 0;
965  }
966  else if ( (sonptr->fMinLevel > level && consistent( &son, level+1, detector) )
967  || sonptr->fMaxLevel < level) {
968  sonptr->fMinLevel = (int) std::min (level,sonptr->fMinLevel);
969  sonptr->fMaxLevel = (int) std::max (level,sonptr->fMaxLevel);
970  marklin (sonptr, level+1, detector);
971  }
972 
973  if (insert_hitpattern && /* "insert pattern"
974  flag is set and */
975  ! nodeexists (father->fSon[offs+flip], &son)) {
976 
977  nodenode* nodptr = new nodenode(); /* create a nodenode */
978  nodptr->SetNext(father->fSon[offs+flip]); /* append it to the son list */
979  nodptr->SetTree(sonptr);
980  father->fSon[offs+flip] = nodptr;
981  }
982  }
983 
984  } // end of other region
985 
986 }
EQwRegionID GetRegion() const
int consistent(treenode *testnode, int level, QwDetectorInfo *detector)
Determines whether the pattern is geometrically possible.
treenode ** fHashTable
void SetTree(treenode *tree)
Set the tree.
Definition: nodenode.h:61
unsigned int & fNumWires
Number of wires in a region 3 VDC group.
int fNumPatterns
Number of valid patterns in the tree.
void SetNext(nodenode *next)
Set the next node.
Definition: nodenode.h:69
int fMinLevel
Minimum level at which this node is valid.
Definition: treenode.h:79
int fWidth
Width in bins of the hit pattern.
Definition: treenode.h:87
nodenode * fSon[4]
Each tree has four son nodes.
Definition: treenode.h:95
unsigned int fHashSize
Length of the hash table (as member field)
void SetNext(treenode *next)
Set the next node.
Definition: treenode.h:105
static const double min
Definition: QwUnits.h:76
EQwDetectorType GetType() const
treenode * nodeexists(nodenode *nd, treenode *tr)
int * fBit
Hit pattern, one bin specified per detector layer.
Definition: treenode.h:84
static std::ostream & endl(std::ostream &)
End of the line.
Definition: QwLog.cc:299
int fMaxLevel
Maximum level at which this node is valid.
Definition: treenode.h:81
treenode * existent(treenode *node, int hash)
Search for a node in the search tree.
void marklin(treenode *father, int level, QwDetectorInfo *detector)
Recursively generate the treesearch pattern database.
unsigned int & fNumPlanes
Number of planes in the region 2 HDCs.
A nodenode is used as a pointer which links treenodes to their siblings.
Definition: nodenode.h:42
A treenode contains the bits that make up a tree pattern.
Definition: treenode.h:63
unsigned int fNumLayers
Number of detector planes.
#define QwError
Predefined log drain for errors.
Definition: QwLog.h:40

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

treenode * QwTrackingTree::nodeexists ( nodenode nd,
treenode tr 
)

Definition at line 450 of file QwTrackingTree.cc.

References QwLog::endl(), QwTracking::treenode::fBit, fNumLayers, QwTracking::nodenode::GetNext(), QwTracking::nodenode::GetTree(), and QwError.

Referenced by marklin().

451 {
452  while (node) {
453  if (! node->GetTree()) {
454  QwError << "Floor gone from under my feet!" << QwLog::endl;
455  return 0;
456  }
457  if (! memcmp(node->GetTree()->fBit, tr->fBit, fNumLayers * sizeof(tr->fBit[0])))
458  return node->GetTree(); /* found it! */
459  node = node->GetNext(); /* nope, so look at the next son of this father */
460  }
461  return 0;
462 }
int * fBit
Hit pattern, one bin specified per detector layer.
Definition: treenode.h:84
static std::ostream & endl(std::ostream &)
End of the line.
Definition: QwLog.cc:299
unsigned int fNumLayers
Number of detector planes.
#define QwError
Predefined log drain for errors.
Definition: QwLog.h:40

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void QwTrackingTree::Print ( const Option_t *  options = 0) const
inline

Print the full tree and hash table.

Definition at line 72 of file QwTrackingTree.h.

References PrintHashTable(), and PrintTree().

72 { PrintTree(); PrintHashTable(); };
void PrintHashTable() const
Print the hash table.
void PrintTree() const
Print the full tree.

+ Here is the call graph for this function:

void QwTrackingTree::PrintHashTable ( ) const

Print the hash table.

Definition at line 119 of file QwTrackingTree.cc.

References QwLog::endl(), fHashSize, fHashTable, QwTracking::treenode::GetNext(), and QwOut.

Referenced by Print().

120 {
121  QwOut << "Hash table:" << QwLog::endl;
122  for (size_t i = 0; i < fHashSize; i++) {
123  QwOut << "hash " << i << ":" << QwLog::endl;
124  treenode* node = fHashTable[i];
125  while (node) {
126  QwOut << node << ": " << *node << QwLog::endl;
127  node = node->GetNext();
128  }
129  }
130 }
#define QwOut
Predefined log drain for explicit output.
Definition: QwLog.h:35
treenode ** fHashTable
unsigned int fHashSize
Length of the hash table (as member field)
treenode * GetNext() const
Get the next node.
Definition: treenode.h:112
static std::ostream & endl(std::ostream &)
End of the line.
Definition: QwLog.cc:299
A treenode contains the bits that make up a tree pattern.
Definition: treenode.h:63

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void QwTrackingTree::PrintTree ( ) const

Print the full tree.

Note
(wdconinc) Merged out all those little classes from tree.cc and tree.h to separate class def files in directory and namespace QwTracking. Proper include should be done, as well as using namespace QwTracking. Print the full tree

Definition at line 108 of file QwTrackingTree.cc.

References QwLog::endl(), fHashTable, QwTracking::treenode::Print(), and QwOut.

Referenced by Print().

109 {
110  // The first entry of the hash table is the root of the tree. The node fFather
111  // is only the root node that is copied before the tree is constructed, so it
112  // stays empty.
113  QwOut << "Tree:" << QwLog::endl;
114  fHashTable[0]->Print();
115 }
#define QwOut
Predefined log drain for explicit output.
Definition: QwLog.h:35
treenode ** fHashTable
void Print(bool recursive=false, int indent=0)
Print some debugging information.
Definition: treenode.cc:104
static std::ostream & endl(std::ostream &)
End of the line.
Definition: QwLog.cc:299

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

QwTrackingTreeRegion * QwTrackingTree::readtree ( const string &  filename,
int  levels,
int  tlayers,
double  rwidth,
bool  skipreading 
)
Parameters
filenameThe filename of the file where the tree is stored
levelsThe number of levels
tlayersThe number of layers
rwidthThe distance between the wires/strips
skipreadingFlag to skip the reading of cached trees
Returns
The search treeregion

Open the file for reading and complain if this fails

If num and width cannot be read, then the file is invalid

Allocate a shorttree array

Allocate a QwTrackingTreeRegion object

... and fill by recursively calling _readtree

Close the file after reading in the tree

Definition at line 1000 of file QwTrackingTree.cc.

References _readtree(), QwLog::endl(), fMaxRef, fRef, QwTrackingTreeRegion::GetNode(), QwTrackingTreeRegion::IsSearchable(), QwDebug, QwWarning, QwTracking::shortnode::SetNext(), QwTrackingTreeRegion::SetSearchable(), QwTracking::shortnode::SetTree(), and QwTrackingTreeRegion::SetWidth().

Referenced by inittree().

1006 {
1007  FILE *file = 0;
1008  shorttree *stb = 0;
1009  QwTrackingTreeRegion *trr = 0;
1010 
1011  Double_t width = 0.0;
1012  int32_t num = 0;
1013 
1014  // Construct full path to tree file
1015  bfs::path fullfilename = bfs::path(filename);
1016  if (! bfs::exists(fullfilename)) {
1017  QwWarning << "Could not find tree file." << QwLog::endl
1018  << "full file name = " << fullfilename.string() << QwLog::endl;
1019  return 0;
1020  }
1021 
1022 
1023  fRef = 0;
1024 
1025  // Skip the reading of the trees
1026  if (skipreading) return 0;
1027 
1028  /// Open the file for reading and complain if this fails
1029  file = fopen(fullfilename.string().c_str(), "rb");
1030  if (! file) {
1031  QwWarning << "Tree file not found. Rebuilding..." << QwLog::endl
1032  << "full file name = " << fullfilename.string() << QwLog::endl;
1033  return 0;
1034  }
1035 
1036  /// If num and width cannot be read, then the file is invalid
1037  if (fread(&num, sizeof(num), 1L, file) < 1 ||
1038  fread(&width, sizeof(width), 1L, file) < 1 ) {
1039  QwWarning << "Tree file appears invalid. Rebuilding..." << QwLog::endl
1040  << "full file name = " << fullfilename.string() << QwLog::endl;
1041  fclose(file);
1042  return 0;
1043  }
1044 
1045  /// Allocate a shorttree array
1046  // Note: new of an array needs a default constructor,
1047  // so set default size with a static function
1048  shorttree::SetDefaultSize(tlayers);
1049  stb = new shorttree[num];
1050 
1051  /// Allocate a QwTrackingTreeRegion object
1052  trr = new QwTrackingTreeRegion();
1053  fMaxRef = num;
1054  /// ... and fill by recursively calling _readtree
1055  if (_readtree (file, stb, 0, tlayers) < 0) {
1056  // Errors occurred while reading the tree
1057  delete [] stb; stb = 0;
1058  delete trr; trr = 0;
1059  QwWarning << "Tree file appears invalid. Rebuilding..." << QwLog::endl
1060  << "full file name = " << fullfilename.string() << QwLog::endl;
1061  fclose(file);
1062  return 0;
1063  }
1064 
1065  /// Close the file after reading in the tree
1066  if (file) fclose(file);
1067 
1068  trr->SetSearchable(stb ? true : false);
1069  QwDebug << "Set searchable = " << trr->IsSearchable() << QwLog::endl;
1070 
1071  shortnode* node = trr->GetNode();
1072  node->SetTree(stb, num);
1073  node->SetNext(0);
1074  trr->SetWidth(width);
1075 
1076  return trr;
1077 }
void SetNext(shortnode *next)
Set the next node.
Definition: shortnode.h:62
bool IsSearchable() const
Is this region searchable?
int _readtree(FILE *file, shorttree *stb, shortnode **father, int32_t tlayers)
Recursive method to read the concise treesearch database from disk.
shortnode * GetNode()
Get the node to this tree region.
void SetSearchable(bool searchable=true)
Set this tree region to searchable.
A container for the pattern databases for each detector region.
int fRef
Reference.
#define QwDebug
Predefined log drain for debugging output.
Definition: QwLog.h:60
Similar to a treenode.
Definition: shorttree.h:44
void SetWidth(double width)
Set the width.
static std::ostream & endl(std::ostream &)
End of the line.
Definition: QwLog.cc:299
void SetTree(shorttree *tree, int ntrees=1)
Set the tree.
Definition: shortnode.h:74
Similar to a nodenode.
Definition: shortnode.h:38
#define QwWarning
Predefined log drain for warnings.
Definition: QwLog.h:45
int fMaxRef
Maximum number of references in the cached tree file.

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void QwTrackingTree::SetDebugLevel ( const int  debuglevel)
inline

Set the debug level.

Definition at line 67 of file QwTrackingTree.h.

References fDebug.

67 { fDebug = debuglevel; };
int fDebug
Debug level.
void QwTrackingTree::SetGeometry ( const QwGeometry geometry)
inline

Definition at line 78 of file QwTrackingTree.h.

References fGeometry.

Referenced by QwTrackingWorker::InitTree().

78 { fGeometry = geometry; };
QwGeometry fGeometry
Detector (or set of detectors) represented by this search tree.

+ Here is the caller graph for this function:

void QwTrackingTree::SetMaxSlope ( const double  maxslope)
inline

Set the maximum allowed slope.

Definition at line 69 of file QwTrackingTree.h.

References fMaxSlope.

Referenced by QwTrackingWorker::InitTree().

69 { fMaxSlope = maxslope; };
double fMaxSlope
Maximum allowed slope for tracks in this detector.

+ Here is the caller graph for this function:

long QwTrackingTree::writetree ( const string &  filename,
treenode tn,
int  levels,
int  tlayers,
double  width 
)

This function initializes the output file. It then calls the iterative _writetree function to fill the output file.

Returns
The number of patterns written to the file

Write 4 bytes to fill later with the number of different patterns

... and write whole tree

append marker for end of son list

Now write the total numer of different patterns,

close the file

and return the number of different patterns

Definition at line 1227 of file QwTrackingTree.cc.

References _writetree(), QwLog::endl(), fRef, QwWarning, and SONEND.

Referenced by inittree().

1233 {
1234  // Construct full file name
1235  bfs::path fullfilename = bfs::path(filename);
1236 
1237  // Open the output stream
1238  FILE *file = fopen(fullfilename.string().c_str(), "wb");
1239  fRef = 0;
1240  if (!file) {
1241  QwWarning << "Could not open tree file. Rebuilding..." << QwLog::endl
1242  << "full file name = " << fullfilename.string() << QwLog::endl;
1243  return 0;
1244  }
1245 
1246  /// Write 4 bytes to fill later with the number of different patterns
1247  if (fwrite(&fRef, sizeof(int32_t), 1L, file) != 1 ||
1248  fwrite(&width, sizeof(double), 1L, file) != 1 ||
1249  _writetree(tn, file, tlayers) < 0) { ///... and write whole tree
1250  fclose(file);
1251  return 0;
1252  }
1253  if (fputc(SONEND, file) == EOF) /// append marker for end of son list
1254  return -1;
1255 
1256  rewind(file);
1257 
1258  /// Now write the total numer of different patterns,
1259  if (fwrite(&fRef, sizeof(int32_t), 1L, file) != 1) {
1260  fclose(file);
1261  return 0;
1262  }
1263  /// close the file
1264  fclose(file);
1265 
1266  /// and return the number of different patterns
1267  return fRef;
1268 }
#define SONEND
int fRef
Reference.
static std::ostream & endl(std::ostream &)
End of the line.
Definition: QwLog.cc:299
int _writetree(treenode *tn, FILE *fp, int32_t tlayers)
Recursive method for pulling in the concise treesearch search database.
#define QwWarning
Predefined log drain for warnings.
Definition: QwLog.h:45

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

Field Documentation

int QwTrackingTree::fDebug
private

Debug level.

Definition at line 123 of file QwTrackingTree.h.

Referenced by QwTrackingTree(), and SetDebugLevel().

treenode* QwTrackingTree::fFather
private

Father node: the main entry point to the tree.

Definition at line 145 of file QwTrackingTree.h.

Referenced by _inittree(), QwTrackingTree(), and ~QwTrackingTree().

QwGeometry QwTrackingTree::fGeometry
private

Detector (or set of detectors) represented by this search tree.

Definition at line 121 of file QwTrackingTree.h.

Referenced by consistent(), and SetGeometry().

const std::string QwTrackingTree::fgTreeDir
staticprivate

Name of the tree directory (in $QWSCRATCH), as static member field.

Definition at line 118 of file QwTrackingTree.h.

unsigned int QwTrackingTree::fHashSize
private

Length of the hash table (as member field)

Definition at line 130 of file QwTrackingTree.h.

Referenced by marklin(), PrintHashTable(), QwTrackingTree(), and ~QwTrackingTree().

treenode** QwTrackingTree::fHashTable
private

Hash table: the list of all nodes in the tree, organized in linked lists and sorted by hash value; an array of pointers to treenodes.

Definition at line 150 of file QwTrackingTree.h.

Referenced by _inittree(), existent(), marklin(), PrintHashTable(), PrintTree(), QwTrackingTree(), and ~QwTrackingTree().

int QwTrackingTree::fMaxLevel
private
          maximum level of the bin division within

the treesearch database, i.e.: resolution = width / (2^maxlevel)

Definition at line 140 of file QwTrackingTree.h.

Referenced by inittree(), and marklin().

int QwTrackingTree::fMaxRef
private

Maximum number of references in the cached tree file.

Definition at line 138 of file QwTrackingTree.h.

Referenced by _readtree(), and readtree().

double QwTrackingTree::fMaxSlope
private

Maximum allowed slope for tracks in this detector.

Definition at line 132 of file QwTrackingTree.h.

Referenced by consistent(), and SetMaxSlope().

unsigned int QwTrackingTree::fNumLayers
private

Number of detector planes.

Definition at line 126 of file QwTrackingTree.h.

Referenced by consistent(), existent(), inittree(), marklin(), nodeexists(), and QwTrackingTree().

int QwTrackingTree::fNumPatterns
private

Number of valid patterns in the tree.

Definition at line 133 of file QwTrackingTree.h.

Referenced by _inittree(), inittree(), marklin(), and QwTrackingTree().

unsigned int& QwTrackingTree::fNumPlanes
private

Number of planes in the region 2 HDCs.

Definition at line 127 of file QwTrackingTree.h.

Referenced by marklin().

unsigned int& QwTrackingTree::fNumWires
private

Number of wires in a region 3 VDC group.

Definition at line 128 of file QwTrackingTree.h.

Referenced by marklin().

int QwTrackingTree::fRef
private

Reference.

Definition at line 136 of file QwTrackingTree.h.

Referenced by _readtree(), _writetree(), readtree(), and writetree().


The documentation for this class was generated from the following files: