PmaElement3D.cxx
Go to the documentation of this file.
1 /**
2  * @file PmaElement3D.cxx
3  *
4  * @author D.Stefan and R.Sulej
5  *
6  * @brief Implementation of the Projection Matching Algorithm
7  *
8  * Base for 3D segments and track nodes. See PmaTrack3D.h file for details.
9  * See PmaTrack3D.h file for details.
10  */
11 
16 
18 
19 // Impact factors on the objective function: U V Z
20 float pma::Element3D::fOptFactors[3] = { 0.2F, 0.8F, 1.0F };
21 
23  fTPC(-1), fCryo(-1),
24  fFrozen(false),
25  fHitsRadius(0)
26 {
28  for (unsigned int i = 0; i < 3; i++)
29  {
30  fNHits[i] = 0;
31  fNThisHits[i] = 0;
32  fSumHitsQ[i] = 0.0;
33  }
34 }
35 
36 size_t pma::Element3D::NEnabledHits(unsigned int view) const
37 {
38  size_t n = 0;
39  for (size_t i = 0; i < fAssignedHits.size(); i++)
40  if (fAssignedHits[i]->IsEnabled() &&
41  ((view == geo::kUnknown) || (view == fAssignedHits[i]->View2D()))) n++;
42  return n;
43 }
44 
46 {
47  std::sort(fAssignedHits.begin(), fAssignedHits.end(), pma::bTrajectory3DOrderLess());
48 }
49 
51 {
52  fAssignedPoints.clear();
53  fAssignedHits.clear();
54  fHitsRadius = 0.0;
55 }
56 
58 {
59  std::vector< pma::Hit3D* > hitsColl, hitsInd1, hitsInd2;
60  for (size_t i = 0; i < 3; ++i) fNThisHitsEnabledAll = 0;
61  for (auto h : fAssignedHits)
62  {
63  if (h->IsEnabled()) fNThisHitsEnabledAll++;
64  switch (h->View2D())
65  {
66  case geo::kZ: hitsColl.push_back(h); break;
67  case geo::kV: hitsInd2.push_back(h); break;
68  case geo::kU: hitsInd1.push_back(h); break;
69  }
70  }
71  fNThisHits[0] = hitsInd1.size();
72  fNThisHits[1] = hitsInd2.size();
73  fNThisHits[2] = hitsColl.size();
74 
75  pma::SortedObjectBase const * chain = dynamic_cast< pma::SortedObjectBase* >(this);
76  pma::Element3D* el = 0;
77  for (size_t b = 0; b < chain->NextCount(); b++)
78  {
79  el = dynamic_cast< pma::Element3D* >(chain->Next(b));
80  if (el)
81  for (auto h : el->fAssignedHits)
82  {
83  switch (h->View2D())
84  {
85  case geo::kZ: hitsColl.push_back(h); break;
86  case geo::kV: hitsInd2.push_back(h); break;
87  case geo::kU: hitsInd1.push_back(h); break;
88  }
89  }
90  }
91  el = dynamic_cast< pma::Element3D* >(chain->Prev());
92  if (el)
93  {
94  for (auto h : el->fAssignedHits)
95  {
96  switch (h->View2D())
97  {
98  case geo::kZ: hitsColl.push_back(h); break;
99  case geo::kV: hitsInd2.push_back(h); break;
100  case geo::kU: hitsInd1.push_back(h); break;
101  }
102  }
103  }
104 
105  fHitsRadius = GetHitsRadius2D(hitsColl);
106  double r = GetHitsRadius2D(hitsInd2);
107  if (r > fHitsRadius) fHitsRadius = r;
108  r = GetHitsRadius2D(hitsInd1);
109  if (r > fHitsRadius) fHitsRadius = r;
110 
111  float amp, sigmaMax = 0.0F;
112  fSumHitsQ[0] = 0.0; fNHits[0] = hitsInd1.size();
113  for (size_t i = 0; i < hitsInd1.size(); i++)
114  {
115  amp = hitsInd1[i]->GetAmplitude();
116  if (amp > sigmaMax) sigmaMax = amp;
117  fSumHitsQ[0] += amp;
118  }
119  for (size_t i = 0; i < hitsInd1.size(); i++)
120  {
121  if (sigmaMax > 0.0F)
122  {
123  amp = hitsInd1[i]->GetAmplitude();
124  if (amp > 0.0F)
125  hitsInd1[i]->SetSigmaFactor((float)sqrt(amp / sigmaMax));
126  else hitsInd1[i]->SetSigmaFactor(0.01F);
127  }
128  else hitsInd1[i]->SetSigmaFactor(1.0F);
129  }
130 
131  sigmaMax = 0.0F;
132  fSumHitsQ[1] = 0.0; fNHits[1] = hitsInd2.size();
133  for (size_t i = 0; i < hitsInd2.size(); i++)
134  {
135  amp = hitsInd2[i]->GetAmplitude();
136  if (amp > sigmaMax) sigmaMax = amp;
137  fSumHitsQ[1] += amp;
138  }
139  for (size_t i = 0; i < hitsInd2.size(); i++)
140  {
141  if (sigmaMax > 0.0F)
142  {
143  amp = hitsInd2[i]->GetAmplitude();
144  if (amp > 0.0F)
145  hitsInd2[i]->SetSigmaFactor((float)sqrt(amp / sigmaMax));
146  else hitsInd2[i]->SetSigmaFactor(0.01F);
147  }
148  else hitsInd2[i]->SetSigmaFactor(1.0F);
149  }
150 
151  sigmaMax = 0.0F;
152  fSumHitsQ[2] = 0.0; fNHits[2] = hitsColl.size();
153  for (size_t i = 0; i < hitsColl.size(); i++)
154  {
155  amp = hitsColl[i]->SummedADC();
156  if (amp > sigmaMax) sigmaMax = amp;
157  fSumHitsQ[2] += amp;
158  }
159  for (size_t i = 0; i < hitsColl.size(); i++)
160  {
161  if (sigmaMax > 0.0F)
162  {
163  amp = hitsColl[i]->SummedADC();
164  if (amp > 0.0F)
165  hitsColl[i]->SetSigmaFactor((float)sqrt(amp / sigmaMax));
166  else hitsColl[i]->SetSigmaFactor(0.01F);
167  }
168  else hitsColl[i]->SetSigmaFactor(1.0F);
169  }
170 }
171 
172 double pma::Element3D::SumDist2(void) const
173 {
174  if (fTPC < 0)
175  {
176  if (!fAssignedHits.empty()) mf::LogWarning("pma::Element3D") << "Hits assigned to TPC-crossing element.";
177  return 0.0F;
178  }
179 
180  double hit_sum = SumDist2Hits();
181 
182  if (fAssignedPoints.size())
183  {
184  double d, ref_sum = 0.0F;
185  for (auto p : fAssignedPoints)
186  {
187  d = sqrt( GetDistance2To(*p) ) - 0.5; // guide by ref points up to ~ 3D resolution
188  if (d > 0.0) ref_sum += d * d;
189  }
190  if (fAssignedHits.size())
191  {
192  ref_sum *= 0.2 * fAssignedHits.size() / fAssignedPoints.size();
193  }
194  hit_sum += ref_sum;
195  }
196 
197  return hit_sum;
198 }
199 
200 double pma::Element3D::SumDist2(unsigned int view) const
201 {
202  if (fTPC < 0)
203  {
204  if (!fAssignedHits.empty()) mf::LogWarning("pma::Element3D") << "Hits assigned to TPC-crossing element.";
205  return 0.0F;
206  }
207 
208  double hit_sum = 0.0F;
209  for (auto h : fAssignedHits)
210  {
211  if (h->IsEnabled())
212  {
213  unsigned int hitView = h->View2D();
214  if ((view == geo::kUnknown) || (view == hitView))
215  {
216  hit_sum += OptFactor(hitView) * // alpha_i
217  h->GetSigmaFactor() * // hit_amp / hit_max_amp
218  GetDistance2To(h->Point2D(), hitView); // hit_to_fit_dist^2
219  }
220  }
221  }
222  return hit_sum;
223 }
224 
225 double pma::Element3D::HitsRadius3D(unsigned int view) const
226 {
227  if (fTPC < 0)
228  {
229  if (!fAssignedHits.empty()) mf::LogWarning("pma::Element3D") << "Hits assigned to TPC-crossing element.";
230  return 0.0F;
231  }
232 
233  TVector3 mean3D(0, 0, 0);
234  size_t nHits = 0;
235  for (auto h : fAssignedHits)
236  if (h->View2D() == view)
237  { mean3D += h->Point3D(); nHits++; }
238  if (!nHits) return 0.0;
239  mean3D *= (1.0 / nHits);
240 
241  double r2, maxR2 = 0.0;
242  for (auto h : fAssignedHits)
243  if (h->View2D() == view)
244  {
245  r2 = pma::Dist2(h->Point3D(), mean3D);
246  if (r2 > maxR2) maxR2 = r2;
247  }
248  return sqrt(maxR2);
249 }
250 
251 bool pma::Element3D::SelectRndHits(size_t nmax_per_view)
252 {
253  if (!nmax_per_view) { return SelectAllHits(); }
254 
255  size_t nhits[3];
256  for (size_t i = 0; i < 3; ++i) nhits[i] = NHits(i);
257 
258  int m[3], count[3];
259  bool state[3];
260  for (size_t i = 0; i < 3; ++i)
261  {
262  if (nhits[i] >= 2 * nmax_per_view)
263  {
264  m[i] = nhits[i] / nmax_per_view;
265  state[i] = true;
266  }
267  else if (nhits[i] > nmax_per_view)
268  {
269  m[i] = nhits[i] / (nhits[i] - nmax_per_view);
270  state[i] = false;
271  }
272  else { m[i] = 0; state[i] = false; }
273 
274  count[i] = 0;
275  }
276 
277  bool b, changed = false;
278  for (auto h : fAssignedHits)
279  {
280  b = h->IsEnabled();
281 
282  size_t view = h->View2D();
283  if (m[view])
284  {
285  if (count[view] % m[view] == 0) h->SetEnabled(state[view]);
286  else h->SetEnabled(!(state[view]));
287 
288  ++count[view];
289  }
290  else h->SetEnabled(true);
291 
292  changed |= (b != h->IsEnabled());
293  }
294  return changed;
295 }
296 
298 {
299  bool changed = false;
300  for (auto h : fAssignedHits)
301  {
302  changed |= !(h->IsEnabled());
303  h->SetEnabled(true);
304  }
305  return changed;
306 }
double fSumHitsQ[3]
Definition: PmaElement3D.h:121
double GetHitsRadius2D(const std::vector< pma::Hit3D * > &hits, bool exact=false)
Definition: Utilities.cxx:98
double Dist2(const TVector2 &v1, const TVector2 &v2)
Definition: Utilities.cxx:37
Planes which measure V.
Definition: geo_types.h:130
Unknown view.
Definition: geo_types.h:136
Planes which measure Z direction.
Definition: geo_types.h:132
size_t fNThisHits[3]
Definition: PmaElement3D.h:118
double HitsRadius3D(unsigned int view) const
virtual void ClearAssigned(pma::Track3D *trk=0)
Planes which measure U.
Definition: geo_types.h:129
Implementation of the Projection Matching Algorithm.
virtual unsigned int NextCount(void) const
Definition: SortedObjects.h:46
size_t fNHits[3]
Definition: PmaElement3D.h:120
std::vector< TVector3 * > fAssignedPoints
Definition: PmaElement3D.h:117
std::void_t< T > n
p
Definition: test.py:223
std::vector< pma::Hit3D * > fAssignedHits
Definition: PmaElement3D.h:116
Implementation of the Projection Matching Algorithm.
static float fOptFactors[3]
Definition: PmaElement3D.h:124
double SumDist2(void) const
Implementation of the Projection Matching Algorithm.
void SortHits(void)
bool SelectRndHits(size_t nmax_per_view)
size_t fNThisHitsEnabledAll
Definition: PmaElement3D.h:119
double fHitsRadius
Definition: PmaElement3D.h:122
virtual double GetDistance2To(const TVector3 &p3d) const =0
Distance [cm] from the 3D point to the object 3D.
static bool * b
Definition: config.cpp:1043
void UpdateHitParams(void)
bool SelectAllHits(void)
virtual pma::SortedObjectBase * Prev(void) const
Definition: SortedObjects.h:44
virtual double SumDist2Hits(void) const =0
size_t NHits(void) const
Definition: PmaElement3D.h:74
virtual pma::SortedObjectBase * Next(unsigned int index=0) const
Definition: SortedObjects.h:45
size_t NEnabledHits(unsigned int view=geo::kUnknown) const
Implementation of the Projection Matching Algorithm.
static float OptFactor(unsigned int view)
Definition: PmaElement3D.h:106