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