DirOfGamma.cxx
Go to the documentation of this file.
1 #include "DirOfGamma.h"
2 
4 
5 #include "larcore/CoreUtils/ServiceUtil.h" // lar::providerFrom<>()
9 
11 
12 #include "TMath.h"
13 
15  : fHit(src)
16 {
17  geo::GeometryCore const* geom = lar::providerFrom<geo::Geometry>();
18 
19  unsigned int plane = src->WireID().Plane;
20  unsigned int tpc = src->WireID().TPC;
21  unsigned int cryo = src->WireID().Cryostat;
22 
23  double wireCentre[3];
24  geom->WireIDToWireGeo(src->WireID()).GetCenter(wireCentre);
25  double x = detProp.ConvertTicksToX(src->PeakTime(), plane, tpc, cryo);
26  double globalWire;
27 
28  if (tpc % 2 == 0) {
29  globalWire = geom->WireCoordinate(wireCentre[1], wireCentre[2], plane, 0, cryo);
30  fPoint.Set(globalWire, x);
31  }
32  else {
33  globalWire = geom->WireCoordinate(wireCentre[1], wireCentre[2], plane, 1, cryo);
34  fPoint.Set(globalWire, x);
35  }
36  fCharge = src->SummedADC();
37 }
38 
39 ems::Bin2D::Bin2D(const TVector2& center) : fCenter2D(center), fTotCharge(0.0), fSize(0) {}
40 
41 void
43 {
44  fHits2D.push_back(hit);
45  fTotCharge += hit->GetCharge();
46  fSize = fHits2D.size();
47  SortLess();
48 }
49 
50 void
52 {
53  return std::sort(fHits2D.begin(), fHits2D.end(), bDistCentMore2D(fCenter2D));
54 }
55 
56 void
58 {
59  return std::sort(fHits2D.begin(), fHits2D.end(), bDistCentLess2D(fCenter2D));
60 }
61 
62 std::vector<art::Ptr<recob::Hit>>
63 ems::Bin2D::GetIniHits(const double radius, const unsigned int nhits) const
64 {
65 
66  std::vector<art::Ptr<recob::Hit>> vec;
67  for (unsigned int i = 0; i < fHits2D.size(); i++) {
68  if (pma::Dist2(fHits2D[i]->GetPointCm(), fCenter2D) < radius * radius) {
69  vec.push_back(fHits2D[i]->GetHitPtr());
70  if (vec.size() == nhits) break;
71  }
72  }
73 
74  return vec;
75 }
76 
77 ems::EndPoint::EndPoint(const Hit2D& center, const std::vector<Hit2D*>& hits, unsigned int nbins)
78  : fCenter2D(center), fPoints2D(hits), fNbins(nbins)
79 {
80 
81  for (unsigned int i = 0; i < fNbins; i++) {
82  fBins.push_back(Bin2D(center.GetPointCm()));
83  }
84 
85  FillBins();
88 
89  fPlane = center.GetHitPtr()->WireID().Plane;
90  fTpc = center.GetHitPtr()->WireID().TPC;
91  fCryo = center.GetHitPtr()->WireID().Cryostat;
92 }
93 
94 void
96 {
97  TVector2 vstart(0, 1);
98 
99  unsigned int saveid = 0;
100  bool exist = false;
101  for (unsigned int i = 0; i < fPoints2D.size(); i++) {
102  if (fPoints2D[i]->GetHitPtr().key() != fCenter2D.GetHitPtr().key()) {
103  TVector2 pos(fPoints2D[i]->GetPointCm());
104  TVector2 centre(fCenter2D.GetPointCm());
105  TVector2 vecp = pos - centre;
106  float sinsign = (vstart.X() * vecp.Y()) - (vstart.Y() * vecp.X());
107  float cosine = (vstart * vecp) / vecp.Mod();
108  float theta = 180.0F * (std::acos(cosine)) / TMath::Pi();
109 
110  unsigned int id = 0;
111  double bin = double(360.0) / double(fNbins);
112 
113  if (sinsign >= 0)
114  id = int(theta / bin);
115  else if (sinsign < 0)
116  id = int(theta / bin) + (fNbins / 2);
117  if (id > (fNbins - 1)) id = (fNbins - 1);
118 
119  fBins[id].Add(fPoints2D[i]);
120  fBins[(id + 1) % fNbins].Add(fPoints2D[i]);
121  }
122  else {
123  saveid = i;
124  exist = true;
125  }
126  }
127 
128  if (exist)
129  for (unsigned int id = 0; id < fNbins; id++)
130  fBins[id].Add(fPoints2D[saveid]);
131 }
132 
133 void
135 {
136  fMaxCharge = 0.0;
137  unsigned int saveid = 0;
138  for (unsigned int i = 0; i < fNbins; i++)
139  if (fBins[i].Size() && (fMaxCharge < fBins[i].GetTotCharge())) {
140  fMaxCharge = fBins[i].GetTotCharge();
141  saveid = i;
142  }
143 
144  fMaxChargeIdBin = saveid;
145 }
146 
147 void
149 {
150  fMeanCharge = 0.0;
151  if (fNbins == 0) return;
152 
153  unsigned int iprev, inext;
154 
155  if (fMaxChargeIdBin > 0)
156  iprev = fMaxChargeIdBin - 1;
157  else
158  iprev = fNbins - 1;
159 
160  inext = (fMaxChargeIdBin + 1) % fNbins;
161 
162  double sumcharge = 0.0;
163  for (unsigned int i = 0; i < fNbins; i++)
164  if ((i != fMaxChargeIdBin) && (i != iprev) && (i != inext))
165  sumcharge += fBins[i].GetTotCharge();
166 
167  fMeanCharge = sumcharge / double(fNbins);
168 }
169 
170 double
172 {
173  if ((fMaxCharge + fMeanCharge) == 0) return 0.0;
174  return ((fMaxCharge - fMeanCharge) / (fMaxCharge + fMeanCharge));
175 }
176 
178  const std::vector<art::Ptr<recob::Hit>>& src,
179  unsigned int nbins,
180  unsigned int idcl)
181  : fNbins(nbins), fIdCl(idcl), fCandidateID(0), fIsCandidateIDset(false)
182 {
183  fHits = src;
184 
185  for (unsigned int i = 0; i < src.size(); i++) {
186  Hit2D* hit = new Hit2D(detProp, src[i]);
187  fPoints2D.push_back(hit);
188  }
189 
191 
192  for (unsigned int i = 0; i < fNbins; i++)
193  fBins.push_back(Bin2D(fBaryCenter));
194 
195  FillBins();
196  ComputeMaxDist();
197  if (FindCandidates()) {
199  FindInitialPart();
200  }
201 }
202 
203 void
205 {
206  double nomx = 0.0;
207  double nomy = 0.0;
208  double denom = 0.0;
209  for (unsigned int i = 0; i < fPoints2D.size(); i++) {
210  nomx += fPoints2D[i]->GetPointCm().X() * fPoints2D[i]->GetCharge();
211  nomy += fPoints2D[i]->GetPointCm().Y() * fPoints2D[i]->GetCharge();
212  denom += fPoints2D[i]->GetCharge();
213  }
214 
215  double bx = nomx / denom;
216  double by = nomy / denom;
217  fBaryCenter.Set(bx, by);
218 }
219 
220 void
222 {
223  TVector2 vstart(0, 1);
224 
225  for (unsigned int i = 0; i < fPoints2D.size(); i++) {
226  TVector2 pos(fPoints2D[i]->GetPointCm().X(), fPoints2D[i]->GetPointCm().Y());
227  TVector2 vecp = pos - fBaryCenter;
228  float sinsign = (vstart.X() * vecp.Y()) - (vstart.Y() * vecp.X());
229  float cosine = (vstart * vecp) / (vstart.Mod() * vecp.Mod());
230  float theta = 180.0F * (std::acos(cosine)) / TMath::Pi();
231 
232  unsigned int id = 0;
233  double bin = double(360.0) / double(fNbins);
234 
235  if (sinsign >= 0)
236  id = int(theta / bin);
237  else if (sinsign < 0)
238  id = int(theta / bin) + (fNbins / 2);
239  if (id > (fNbins - 1)) id = (fNbins - 1);
240 
241  fBins[id].Add(fPoints2D[i]);
242  }
243 
244  for (unsigned int id = 0; id < fBins.size(); id++)
245  fBins[id].Sort();
246 }
247 
248 void
250 {
251  double maxdist2 = 0.0;
252 
253  for (unsigned int id = 0; id < fBins.size(); id++) {
254 
255  if (!fBins[id].Size()) continue;
256 
257  Hit2D* candidate = fBins[id].GetHits2D().front();
258  if (candidate) {
259  double dist2 = pma::Dist2(candidate->GetPointCm(), fBaryCenter);
260  if (dist2 > maxdist2) { maxdist2 = dist2; }
261  }
262  }
263 
264  fNormDist = std::sqrt(maxdist2);
265 }
266 
267 bool
269 {
270  float rad = 0.5F * fNormDist;
271  unsigned int nbins = fNbins * 4;
272  for (unsigned int id = 0; id < fNbins; id++) {
273 
274  if (!fBins[id].Size()) continue;
275 
276  std::vector<Hit2D*> points;
277  Hit2D* candidate2D = fBins[id].GetHits2D().front();
278 
279  for (unsigned int i = 0; i < fPoints2D.size(); i++) {
280  double distnorm = std::sqrt(pma::Dist2(candidate2D->GetPointCm(), fBaryCenter)) / fNormDist;
281  double dist2 = pma::Dist2(candidate2D->GetPointCm(), fPoints2D[i]->GetPointCm());
282 
283  if ((distnorm > 0.5) && (dist2 < rad * rad)) points.push_back(fPoints2D[i]);
284  }
285 
286  if (fBins[id].Size() > 1) {
287  EndPoint ep(*candidate2D, points, nbins);
288  fCandidates.push_back(ep);
289  }
290  }
291  if (fCandidates.size())
292  return true;
293  else
294  return false;
295 }
296 
297 void
299 {
300  fNormCharge = 0.0;
301  for (unsigned int i = 0; i < fCandidates.size(); i++) {
302  if (fCandidates[i].GetMaxCharge() > fNormCharge) {
303  fNormCharge = fCandidates[i].GetMaxCharge();
304  }
305  }
306 }
307 
308 void
310 {
311  double max_asymmetry = 0.0;
312  unsigned int saveid = 0;
313  bool found = false;
314 
315  double maxdist2 = 0.0;
316  double maxcharge = 0.0;
317  unsigned int idmaxdist = 0;
318  unsigned int idmaxcharge = 0;
319 
320  for (unsigned int i = 0; i < fCandidates.size(); i++) {
321  double dist2 = pma::Dist2(fCandidates[i].GetPosition(), fBaryCenter);
322  double charge = fCandidates[i].GetMaxCharge();
323  if (dist2 > maxdist2) {
324  maxdist2 = dist2;
325  idmaxdist = i;
326  }
327  if (charge > maxcharge) {
328  maxcharge = charge;
329  idmaxcharge = i;
330  }
331  }
332 
333  maxdist2 = 0.0;
334  unsigned int idmaxdistb = 0;
335  for (size_t i = 0; i < fCandidates.size(); i++) {
336  if ((i == idmaxdist) || (i == idmaxcharge)) continue;
337 
338  double dist2 = pma::Dist2(fCandidates[i].GetPosition(), fCandidates[idmaxdist].GetPosition());
339  if (dist2 > maxdist2) {
340  maxdist2 = dist2;
341  idmaxdistb = i;
342  }
343  }
344 
345  if (fCandidates.size() > 2) {
346  for (unsigned int i = 0; i < fCandidates.size(); i++) {
347  double asymmetry = fCandidates[i].GetAsymmetry();
348 
349  if ((i == idmaxdist) || (i == idmaxcharge) || (i == idmaxdistb)) {
350  if (asymmetry > max_asymmetry) {
351  max_asymmetry = asymmetry;
352  saveid = i;
353  found = true;
354  }
355  }
356  }
357  }
358  else {
359  for (unsigned int i = 0; i < fCandidates.size(); i++) {
360  double asymmetry = fCandidates[i].GetAsymmetry();
361 
362  if ((i == idmaxdist) || (i == idmaxdistb)) {
363  if (asymmetry > max_asymmetry) {
364  max_asymmetry = asymmetry;
365  saveid = i;
366  found = true;
367  }
368  }
369  }
370  }
371 
372  if (!found)
373  mf::LogError("DirOfGamma") << fCandidates.size() << "DirOfGamma - Find Initial Part problem.";
374 
375  fStartHit = fCandidates[saveid].GetHit();
376  fStartPoint = fCandidates[saveid].GetPosition();
377  fIniHits = fCandidates[saveid].MaxChargeBin().GetIniHits();
378  fCandidateID = saveid;
379 }
geo::Length_t WireCoordinate(double YPos, double ZPos, geo::PlaneID const &planeid) const
Returns the index of the nearest wire to the specified position.
void SortLess()
Definition: DirOfGamma.cxx:57
void FindInitialPart()
Definition: DirOfGamma.cxx:309
TVector2 fPoint
Definition: DirOfGamma.h:53
static constexpr double rad
Definition: Units.h:164
DirOfGamma(const detinfo::DetectorPropertiesData &detProp, const std::vector< art::Ptr< recob::Hit >> &src, unsigned int nbins, unsigned int idcl)
Definition: DirOfGamma.cxx:177
void FillBins()
Definition: DirOfGamma.cxx:95
double Dist2(const TVector2 &v1, const TVector2 &v2)
Definition: Utilities.cxx:37
void Add(Hit2D *hit)
Definition: DirOfGamma.cxx:42
geo::WireID WireID() const
Definition: Hit.h:233
std::vector< art::Ptr< recob::Hit > > fHits
Definition: DirOfGamma.h:270
struct vector vector
CryostatID_t Cryostat
Index of cryostat.
Definition: geo_types.h:212
std::vector< Hit2D * > fPoints2D
Definition: DirOfGamma.h:162
MaybeLogger_< ELseverityLevel::ELsev_error, false > LogError
std::vector< Hit2D * > fHits2D
Definition: DirOfGamma.h:97
void ComputeMaxCharge()
Definition: DirOfGamma.cxx:134
art framework interface to geometry description
bool FindCandidates()
Definition: DirOfGamma.cxx:268
art::Ptr< recob::Hit > const & GetHitPtr() const
Definition: DirOfGamma.h:45
TVector2 fBaryCenter
Definition: DirOfGamma.h:282
size_t fNbins
Definition: DirOfGamma.h:163
std::vector< Bin2D > fBins
Definition: DirOfGamma.h:264
Hit2D fCenter2D
Definition: DirOfGamma.h:161
unsigned int fSize
Definition: DirOfGamma.h:99
void ComputeMaxDist()
Definition: DirOfGamma.cxx:249
const TVector2 & fCenter2D
Definition: DirOfGamma.h:96
key_type key() const noexcept
Definition: Ptr.h:216
double fTotCharge
Definition: DirOfGamma.h:98
Hit2D(detinfo::DetectorPropertiesData const &detProp, art::Ptr< recob::Hit > src)
Definition: DirOfGamma.cxx:14
EndPoint(const Hit2D &center, const std::vector< Hit2D * > &hits, unsigned int nbins)
Definition: DirOfGamma.cxx:77
double GetCharge() const
Definition: DirOfGamma.h:39
size_t fPlane
Definition: DirOfGamma.h:176
PlaneID_t Plane
Index of the plane within its TPC.
Definition: geo_types.h:493
Description of geometry of one entire detector.
std::vector< art::Ptr< recob::Hit > > GetIniHits(const double radius=10.0, const unsigned int nhits=10) const
Definition: DirOfGamma.cxx:63
Detector simulation of raw signals on wires.
Encapsulate the geometry of a wire.
double ConvertTicksToX(double ticks, int p, int t, int c) const
size_t fMaxChargeIdBin
Definition: DirOfGamma.h:170
double fCharge
Definition: DirOfGamma.h:51
Implementation of the Projection Matching Algorithm.
float PeakTime() const
Time of the signal peak, in tick units.
Definition: Hit.h:218
size_t fCandidateID
Definition: DirOfGamma.h:261
void ComputeBaryCenter()
Definition: DirOfGamma.cxx:204
void ComputeMaxCharge()
Definition: DirOfGamma.cxx:298
TVector2 fStartPoint
Definition: DirOfGamma.h:268
def center(depos, point)
Definition: depos.py:117
void Sort()
Definition: DirOfGamma.cxx:51
QTextStream & bin(QTextStream &s)
float SummedADC() const
The sum of calibrated ADC counts of the hit (0. by default)
Definition: Hit.h:223
list x
Definition: train.py:276
std::vector< EndPoint > fCandidates
Definition: DirOfGamma.h:265
TVector2 const & GetPointCm() const
Definition: DirOfGamma.h:34
double fMeanCharge
Definition: DirOfGamma.h:166
void ComputeMeanCharge()
Definition: DirOfGamma.cxx:148
double fMaxCharge
Definition: DirOfGamma.h:165
double GetAsymmetry() const
Definition: DirOfGamma.cxx:171
TPCID_t TPC
Index of the TPC within its cryostat.
Definition: geo_types.h:406
std::vector< Bin2D > fBins
Definition: DirOfGamma.h:168
art::Ptr< recob::Hit > fStartHit
Definition: DirOfGamma.h:267
std::vector< art::Ptr< recob::Hit > > fIniHits
Definition: DirOfGamma.h:269
std::vector< Hit2D * > fPoints2D
Definition: DirOfGamma.h:263
size_t fCryo
Definition: DirOfGamma.h:178
WireGeo const & WireIDToWireGeo(geo::WireID const &wireid) const
Bin2D(const TVector2 &center)
Definition: DirOfGamma.cxx:39