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