EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
HoughTree.h
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file HoughTree.h
1 //
2 // AYK (ayk@bnl.gov)
3 //
4 // Hough transform track finder;
5 //
6 // Initial port from OLYMPUS sources: Oct'2015;
7 //
8 
9 #include <map>
10 #include <cstdio>
11 
12 #include <ResolutionLevel.h>
13 #include <HoughNodeGroup.h>
14 #include <HoughCell.h>
15 #include <MatchCandidateGroup.h>
16 
17 #ifndef _HOUGH_TREE_
18 #define _HOUGH_TREE_
19 
21  public:
22  HoughDimension(const char *name, double min, double max): mMin(min), mMax(max) {
23  // Sanity check, please;
24  if (!name || min >= max) {
25  printf("\n HoughDimension::HoughDimension(): illegal input!\n\n");
26  throw;
27  } //if
28  mName = strdup(name); assert(mName);
29 
30  printf("%s -> %7.2f .. %7.2f\n", mName, mMin, mMax);
31  };
32 
33  const char *GetName() const { return mName; };
34  double GetMin() const { return mMin; };
35  double GetMax() const { return mMax; };
36 
37  private:
38  // For printouts and book-keeping purposes only;
39  char *mName;
40 
41  // Parameter range;
42  double mMin, mMax;
43 };
44 
45 // May want to consider __u64 if ever come to a situation when multi-index composed
46 // out of all the dimensions becomes larger than __u32 type; well, if 64-bits are
47 // not enough, will have to change binary search code;
49 // So depth will be counted in the range [0..31] for __u32 indices;
50 #define _MAX_BTREE_INDEX_DEPTH_ ((sizeof(t_btree_index) << 3)-1)
51 
53 
54 class HoughTree
55 {
56  public:
57  HoughTree();
58  // FIXME: populate with something useful, please;
59  ~HoughTree() {};
60 
61  int AddDimension(const char *name, double min, double max);
62  int AddResolutionLevel(const unsigned div[]);
63 
64  virtual HoughNodeGroup *AllocateNodeGroup(unsigned id) { return new HoughNodeGroup(id); };
65 
66 #if _LATER_
67  HoughNodeGroup *AddNodeGroup(void *ptr, double min, double max,
68  double gra, SpaceGridType gridType);
69  HoughNodeGroup *AddNodeGroup(void *ptr, unsigned cdim, const double min[], const double max[],
70  const double gra[], SpaceGridType gridType);
71 #endif
72  HoughNodeGroup *AddNodeGroup(/*void *ptr,*/ unsigned id, unsigned cdim, const double min[], const double max[],
73  const double gra[]);
74  unsigned GetGdim() const { return mGroups.size(); };
75 
76  unsigned LaunchPatternFinder();
77 
78  void SetVerbosityLevel(unsigned level) { mVerbosityLevel = level; };
79  unsigned GetVerbosityLevel() const { return mVerbosityLevel; };
80 
81  unsigned GetDdim() const { return mDimensions.size(); };
82  const HoughDimension *GetDimension(unsigned id) const {
83  return id < mDimensions.size() ? &mDimensions[id] : 0;
84  };
85 
86  int SetBlindCellDecisionLevel(unsigned level) {
87  if (level >= GetLdim()) return -1;
88 
89  mBlindCellDecisionLevel = level;
90  return 0;
91  };
92  int SetOkHitCounterLimits(unsigned min, unsigned max) {
93  // Here and below need to count node counter or such rather than just mGroups.size();
94 #if _LATER_
95  if (min > max || max > mGroups.size()) return -1;
96 #endif
97 
99  return 0;
100  };
102  if (max > mGroups.size()) return -1;
103 
105  return 0;
106  };
108  if (max > mGroups.size()) return -1;
109 
111  return 0;
112  };
113 
114  unsigned GetGroupCount() const { return mGroups.size(); };
115  HoughNodeGroup *GetGroup(unsigned gr) const { return mGroups[gr]; };
116 
117  unsigned GetLdim() const { return mResolutionLevels.size(); };
118  ResolutionLevel *GetLevel(unsigned lv) const {
119  return (lv < mResolutionLevels.size() ? mResolutionLevels[lv] : 0);
120  };
121 
122  // Just to arrange a loop;
125  return (tc < mMatchCandidateCount ? mMatchCandidates[tc] : 0);
126  };
127 
128  int AllocateLookUpTable();
129 
130  void SetFastTreeSearchMode(unsigned qualityItrNum) {
131  mTrackQualityIterationNum = qualityItrNum; assert(qualityItrNum);
132  mFastTreeSearchMode = true;
133  };
134 
135  protected:
136  //void PrintTrackCandidateArray(unsigned from, unsigned to, TrackCandidatePrintoutFlag flag) const;
137 
138  virtual MatchCandidate *AllocateMatchCandidate() = 0;
139  //virtual void SeparateSiamTracks(MatchCandidate *match, unsigned minHitCount,
140  // std::vector<MatchCandidate*> *newMatches) = 0;
141  //virtual void ResolveAmbiguities(MatchCandidate *match) = 0;
142  virtual void ResolveAmbiguitiesNg(MatchCandidate *match) = 0;
143  virtual void FinalFit(MatchCandidate *match) = 0;
144 
145  // Registering detector groups to be AND'ed during calculations; configuration
146  // is assumed to be fixed upon start-up; basically *planes* in the track finder context;
147  std::vector<HoughNodeGroup*> mGroups;
148 
149  // Track finder loop will probably be arranged between max and min values;
151 
152  private:
153  int AddResolutionLevelCore(const unsigned div[]);
154 
155  unsigned PurgeDuplicateTracks();
156 
157  // Do not want to make respective HoughCell constructor; InitializeCell() iteratively
158  // calls itself to allocate daughter cells and I sort of feel uncomfortable to do
159  // this in the constructor;
160  HoughCell *GetInitializedCell(unsigned lv, const unsigned id[]);
161  unsigned CheckCell(unsigned lv, const unsigned id[], HoughCell **pcell,
162  const std::vector<GroupMember*> members[]);
163 
164  bool IsSubset(MatchCandidate *match) const;
165 
166  bool IsBusy(const GroupMember *member) const {
167  return (mFastTreeSearchMode ? member->IsBooked() : member->IsBusy());
168  };
169 
170  virtual void SetupTrackQualityIteration(unsigned itr) = 0;
171 
172  unsigned GetUsefulGroupCount(const HoughCell *cell) const {
173  unsigned counter = 0;
174 
175  for(unsigned gr=0; gr<GetGdim(); gr++)
176  if (cell->From(gr) != __OUT_OF_RANGE_BIT_)
177  counter++;
178 
179  return counter;
180  };
181 
183  if (mMatchCandidateCount == mMatchCandidates.size())
185 
187 
188  match->ResetToTheVirginState();
189 
190  return match;
191  };
192 
193  // Function which calculates expected gnum-dimensioned {wire}
194  // hit index array id[] for a given ddim-dimensioned parameter vector par[];
195  virtual void MappingCall(const double par[], t_hough_range id[]) = 0;
196 
197  // Some allocation should be done after all the add_hough_...()
198  // configuration routines succeeded;
200 
201  // New dimensions can be added until division strategy is selected;
203 
204  // Well, just propagate from XML config for now;
205  unsigned mVerbosityLevel;
206 
207  // Min number of hits in a given branch in the track finder context;
208  // max number of hits has a separate sense; it looks one can hardly
209  // estimate the most efficient branch direction (select for instance
210  // 6-hit branches first, then investigate 5-hit branches, etc, because
211  // cell calculation takes most of the CPU already; also it is not
212  // guaranteed that track candidate with max number of hits will be
213  // found earlier than any smaller-number=of-hits combination because
214  // branching decision on lower level could be wrong already (say I
215  // have 9 planes and a minimum of 7 hits; there are 2 branches, with
216  // 9 and 8 hit planes respectively; I select 9-fold one, but it
217  // effectively had noise hits in 2 planes, so track candidate will
218  // at the end have 7 hits; the 8-fold branch had all hits true, and
219  // will at the end have 8-hit track candidate; apparently a better -
220  // 8-fold track - will be found later tan 7-fold one); so for now prefer
221  // to arrange a loop from max to min, and suppress track candidates
222  // which have same hits as the ones in already found tracks, up to the
223  // missing ones; track fitting will take care to check whether there
224  // were outlier hits or not; do not want to take hroot->gnum as max,
225  // because entering with this limit is not necessarily the most
226  // efficient strategy (if there are either too many planes or plane
227  // efficiency is too low);
229 
230  // For now allocation is perhaps not too much efficient (pointers);
231  // the convention then is: if a certain daughter cell is NULL, it
232  // has NOT been allocated yet; if pointer is mBlindCell, then cell
233  // is a "blind end", so it has no overlap with real tracks in the
234  // suggested parameter space rectangle,
235  // including higher resolution levels; since the parameter
236  // space has in general larger volume than allowed by chamber
237  // acceptance, the lower resolution cell(s) may have all edges out
238  // of acceptance (for sure can be so for 0-th level, where useful
239  // parameter space can be "enclosed" in a larger volume); then it is
240  // more safe to check their daughters up to the
241  // mBlindCellDecisionLevel, and only if they all have no
242  // overlap with acceptance, declare them all (and parent cell) as "blind";
245 
246  // When calculation acceptance of lower level cells increase resolution
247  // up to this level only, and take largest estimate; THINK: highest resolution
248  // level for now per default and no method to change this;
250 
251  // During track finder iterations "good" track mark their hits as "sort of
252  // used"; new track candidates can borrow few such hits if needed; "suspicious"
253  // node is such where hit is either borrowed or missing at all;
255 
256  // Number of parameter cube dimensions; here and below prefer arrays
257  // instead of linked lists; mSingleCellEdgeNum=2**Dimensions.size(): number of
258  // single cell edges (is reset to 1 in the constructor and will be doubled with
259  // every new dimension declared by the AddDimension() call;
261  std::vector<HoughDimension> mDimensions;
262 
263  // Hit counter limits may be assigned plane-group specific; otherwise
264  // they will be global for group #0;
265  std::map<unsigned,unsigned> mGlimits, mGcounters;
266 
267  // Number of resolution levels; their description;
268  std::vector<ResolutionLevel*> mResolutionLevels;
269 
270  // The actual Hough cell tree;
272 
273  // Binary tree of 3D calculation lookup table;
274  // FIXME: a less economic allocation scheme is used for now (?);
276 
277  protected:
278  // HoughTree::IsBusy() call is based on member->IsBooked() rather than
279  // member->IsBusy(); so track candidates grab hits right during tree search;
282 
283  // Match (track) candidates at the highest resolution level; prefer to
284  // use std::vector as a convenient way to arrange permanent storage (do not
285  // call clear() at the end of every event), but use another running variable
286  // which indicates current number of allocated track candidates in this event;
288  std::vector<MatchCandidate*> mMatchCandidates;
289 };
290 
291 #endif