All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Public Member Functions | Private Types | Private Member Functions | Private Attributes | List of all members
cluster::DBCluster3D Class Reference
Inheritance diagram for cluster::DBCluster3D:

Public Member Functions

 DBCluster3D (fhicl::ParameterSet const &p)
 
 DBCluster3D (DBCluster3D const &)=delete
 
 DBCluster3D (DBCluster3D &&)=delete
 
DBCluster3Doperator= (DBCluster3D const &)=delete
 
DBCluster3Doperator= (DBCluster3D &&)=delete
 

Private Types

using Point_t = recob::tracking::Point_t
 
using Vector_t = recob::tracking::Vector_t
 

Private Member Functions

void produce (art::Event &e) override
 

Private Attributes

const art::InputTag fHitModuleLabel
 
const art::InputTag fSpacePointModuleLabel
 
const art::InputTag fSPHitAssnLabel
 
DBScan3DAlg fDBScan
 
geo::GeometryCore const * fGeom
 
double tickToDist
 
double fMinHitDis
 

Detailed Description

Definition at line 33 of file DBCluster3D_module.cc.

Member Typedef Documentation

Definition at line 35 of file DBCluster3D_module.cc.

Definition at line 36 of file DBCluster3D_module.cc.

Constructor & Destructor Documentation

cluster::DBCluster3D::DBCluster3D ( fhicl::ParameterSet const &  p)
explicit

Definition at line 65 of file DBCluster3D_module.cc.

66  : EDProducer{p}
67  , fHitModuleLabel(p.get<art::InputTag>("HitModuleLabel"))
68  , fSpacePointModuleLabel(p.get<art::InputTag>("SpacePointModuleLabel"))
69  , fSPHitAssnLabel(p.get<art::InputTag>("SPHitAssnLabel"))
70  , fDBScan(p.get<fhicl::ParameterSet>("DBScan3DAlg"))
71  , fMinHitDis(p.get<double>("MinHitDis"))
72 {
73  produces<std::vector<recob::Slice>>();
74  produces<art::Assns<recob::Slice, recob::Hit>>();
75  produces<art::Assns<recob::Slice, recob::SpacePoint>>();
76 
77  fGeom = art::ServiceHandle<geo::Geometry const>().get();
78  auto const clock_data = art::ServiceHandle<detinfo::DetectorClocksService const>()->DataForJob();
79  auto const det_prop =
80  art::ServiceHandle<detinfo::DetectorPropertiesService const>()->DataForJob(clock_data);
81 
82  tickToDist = det_prop.DriftVelocity(det_prop.Efield(), det_prop.Temperature());
83  tickToDist *= 1.e-3 * sampling_rate(clock_data); // 1e-3 is conversion of 1/us to 1/ns
85 }
geo::GeometryCore const * fGeom
pdgs p
Definition: selectors.fcl:22
const art::InputTag fSpacePointModuleLabel
const art::InputTag fHitModuleLabel
const art::InputTag fSPHitAssnLabel
double sampling_rate(DetectorClocksData const &data)
Returns the period of the TPC readout electronics clock.
cluster::DBCluster3D::DBCluster3D ( DBCluster3D const &  )
delete
cluster::DBCluster3D::DBCluster3D ( DBCluster3D &&  )
delete

Member Function Documentation

DBCluster3D& cluster::DBCluster3D::operator= ( DBCluster3D const &  )
delete
DBCluster3D& cluster::DBCluster3D::operator= ( DBCluster3D &&  )
delete
void cluster::DBCluster3D::produce ( art::Event &  e)
overrideprivate

Definition at line 88 of file DBCluster3D_module.cc.

89 {
90  auto scol = std::make_unique<std::vector<recob::Slice>>();
91  auto slc_hit_assn = std::make_unique<art::Assns<recob::Slice, recob::Hit>>();
92  auto slc_sps_assn = std::make_unique<art::Assns<recob::Slice, recob::SpacePoint>>();
93 
94  auto hitsHandle = evt.getValidHandle<std::vector<recob::Hit>>(fHitModuleLabel);
95  auto spsHandle = evt.getValidHandle<std::vector<recob::SpacePoint>>(fSpacePointModuleLabel);
96 
97  // all hits in the collection
98  std::vector<art::Ptr<recob::Hit>> hits;
99  art::fill_ptr_vector(hits, hitsHandle);
100 
101  // all space points in the collection
102  std::vector<art::Ptr<recob::SpacePoint>> sps;
103  art::fill_ptr_vector(sps, spsHandle);
104 
105  art::FindManyP<recob::SpacePoint> spFromHit(hitsHandle, evt, fSPHitAssnLabel);
106  if (!spFromHit.isValid()) {
107  std::cout << "spFromHit is invalid\n";
108  return;
109  }
110  // Find the first Hit - SpacePoint assn and check consistency on the first event
111  static bool first = true;
112  if (first) {
113  bool success = false;
114  bool foundsps = false;
115  for (auto& hit : hits) {
116  auto& sps = spFromHit.at(hit.key());
117  if (sps.empty()) continue;
118  success = (sps[0].id() == spsHandle.id());
119  foundsps = true;
120  break;
121  } // hit
122  if ((!success) && foundsps)
123  throw cet::exception("DBCluster3D")
124  << "HitModuleLabel, SpacePointModuleLabel and SPHitAssnLabel are inconsistent\n";
125  first = false;
126  } // first
127 
128  art::FindManyP<recob::Hit> hitFromSp(spsHandle, evt, fSPHitAssnLabel);
129  if (!hitFromSp.isValid()) {
130  std::cout << "hitFromSp is invalid\n";
131  return;
132  }
133  fDBScan.init(sps, hitFromSp);
134  fDBScan.dbscan();
135 
136  //Find number of slices
137  int maxid = INT_MIN;
138  for (size_t i = 0; i < fDBScan.points.size(); ++i) {
139  if (fDBScan.points[i].cluster_id > maxid) maxid = fDBScan.points[i].cluster_id;
140  }
141  size_t nslc = 0;
142  if (maxid >= 0) nslc = maxid + 1;
143 
144  //Save hits associated with each slice
145  std::vector<std::vector<art::Ptr<recob::Hit>>> slcHits(nslc);
146  //Save hits on each PlaneID with pfparticle index
147  std::map<geo::PlaneID, std::vector<std::pair<art::Ptr<recob::Hit>, unsigned int>>> hitmap;
148  for (auto& hit : hits) {
149  auto& sps = spFromHit.at(hit.key());
150  if (sps.size()) { //found associated space point
151  if (fDBScan.points[sps[0].key()].cluster_id >= 0) {
152  slcHits[fDBScan.points[sps[0].key()].cluster_id].push_back(hit);
153  hitmap[geo::PlaneID(hit->WireID())].push_back(
154  std::make_pair(hit, fDBScan.points[sps[0].key()].cluster_id));
155  }
156  } // sps.size()
157  } // hit
158 
159  //Save hits not associated with any spacepoints
160  for (auto& hit : hits) {
161  bool found = false;
162  for (size_t i = 0; i < slcHits.size(); ++i) {
163  if (std::find(slcHits[i].begin(), slcHits[i].end(), hit) != slcHits[i].end()) {
164  found = true;
165  break;
166  }
167  }
168  if (!found) {
169  double wirePitch = fGeom->WirePitch(hit->WireID());
170  double UnitsPerTick = tickToDist / wirePitch;
171  double x0 = hit->WireID().Wire;
172  double y0 = hit->PeakTime() * UnitsPerTick;
173  double mindis = DBL_MAX;
174  unsigned slcIndex = UINT_MAX;
175  for (auto& hit2 : hitmap[geo::PlaneID(hit->WireID())]) {
176  double dx = hit2.first->WireID().Wire - x0;
177  double dy = hit2.first->PeakTime() * UnitsPerTick - y0;
178  double dis = dx * dx + dy * dy;
179  if (dis < mindis) {
180  mindis = dis;
181  slcIndex = hit2.second;
182  }
183  }
184  if (slcIndex != UINT_MAX && mindis < fMinHitDis) { slcHits[slcIndex].push_back(hit); }
185  }
186  }
187 
188  //Save spacepoints for each slice
189  std::vector<std::vector<art::Ptr<recob::SpacePoint>>> sps_in_slc(nslc);
190  for (size_t i = 0; i < fDBScan.points.size(); ++i) {
191  if (fDBScan.points[i].cluster_id >= 0) {
192  sps_in_slc[fDBScan.points[i].cluster_id].push_back(sps[i]);
193  }
194  } // i
195 
196  // calculate the properties of the slice
197  for (size_t isl = 0; isl < nslc; ++isl) {
198  double sum = sps_in_slc[isl].size();
199  // find the center
200  double center[3] = {0.};
201  // TODO: calculate the charge using recob::PointCharge instead of just counting hits
202  float charge = slcHits[isl].size();
203  for (auto& spt : sps_in_slc[isl]) {
204  for (unsigned short xyz = 0; xyz < 3; ++xyz)
205  center[xyz] += spt->XYZ()[xyz];
206  } // spt
207  for (unsigned short xyz = 0; xyz < 3; ++xyz)
208  center[xyz] /= sum;
209  // do a linear fit
210  double sumx = 0, sumy = 0., sumz = 0., sumx2 = 0, sumy2 = 0, sumz2 = 0;
211  double sumxy = 0, sumxz = 0;
212  for (auto& spt : sps_in_slc[isl]) {
213  double xx = spt->XYZ()[0] - center[0];
214  double yy = spt->XYZ()[1] - center[1];
215  double zz = spt->XYZ()[2] - center[2];
216  sumx += xx;
217  sumy += yy;
218  sumz += zz;
219  sumx2 += xx * xx;
220  sumy2 += yy * yy;
221  sumz2 += zz * zz;
222  sumxy += xx * yy;
223  sumxz += xx * zz;
224  } // spt
225  double delta = sum * sumx2 - sumx * sumx;
226  if (delta <= 0) continue;
227  // calculate the slopes
228  double dydx = (sumxy * sum - sumx * sumy) / delta;
229  double dzdx = (sumxz * sum - sumx * sumz) / delta;
230  // and convert to direction vector
231  double direction[3];
232  double norm = std::sqrt(1 + dydx * dydx + dzdx * dzdx);
233  direction[0] = 1 / norm;
234  direction[1] = dydx / norm;
235  direction[2] = dzdx / norm;
236  // Find the points that are farthest away from the center along the slice axis
237  unsigned int imax = 0, imin = 0;
238  float minAlong = 1E6, maxAlong = -1E6;
239  double tmpVec[3];
240  for (unsigned int ipt = 0; ipt < sps_in_slc[isl].size(); ++ipt) {
241  auto& spt = sps_in_slc[isl][ipt];
242  for (unsigned short xyz = 0; xyz < 3; ++xyz)
243  tmpVec[xyz] = spt->XYZ()[xyz] - center[xyz];
244  double dotp = 0;
245  for (unsigned short xyz = 0; xyz < 3; ++xyz)
246  dotp += tmpVec[xyz] * direction[xyz];
247  if (dotp < minAlong) {
248  minAlong = dotp;
249  imin = ipt;
250  }
251  if (dotp > maxAlong) {
252  maxAlong = dotp;
253  imax = ipt;
254  }
255  } // spt
256  // Find the aspect ratio
257  float cnt = 0.;
258  float aspectRatio = 0;
259  double arg = sum * sumy2 - sumy * sumy;
260  if (arg > 0) {
261  aspectRatio += std::abs(sum * sumxy - sumx * sumy) / sqrt(delta * arg);
262  ++cnt;
263  }
264  arg = sum * sumz2 - sumz * sumz;
265  if (arg > 0) {
266  aspectRatio += std::abs(sum * sumxz - sumx * sumz) / sqrt(delta * arg);
267  ++cnt;
268  }
269  if (cnt > 1) aspectRatio /= cnt;
270  int id = isl + 1;
271  Point_t ctr(center[0], center[1], center[2]);
272  Vector_t dir(direction[0], direction[1], direction[2]);
273  auto pos0 = sps_in_slc[isl][imin]->XYZ();
274  Point_t ep0(pos0[0], pos0[1], pos0[2]);
275  auto pos1 = sps_in_slc[isl][imax]->XYZ();
276  Point_t ep1(pos1[0], pos1[1], pos1[2]);
277  scol->emplace_back(id, ctr, dir, ep0, ep1, aspectRatio, charge);
278  util::CreateAssn(evt, *scol, slcHits[isl], *slc_hit_assn);
279  util::CreateAssn(evt, *scol, sps_in_slc[isl], *slc_sps_assn);
280  } // isl
281 
282  evt.put(std::move(scol));
283  evt.put(std::move(slc_hit_assn));
284  evt.put(std::move(slc_sps_assn));
285 }
geo::GeometryCore const * fGeom
The data type to uniquely identify a Plane.
Definition: geo_types.h:472
const art::InputTag fSpacePointModuleLabel
process_name hit
Definition: cheaterreco.fcl:51
const art::InputTag fHitModuleLabel
const art::InputTag fSPHitAssnLabel
geo::Length_t WirePitch(geo::PlaneID const &planeid) const
Returns the distance between two consecutive wires.
recob::tracking::Point_t Point_t
IDparameter< geo::PlaneID > PlaneID
Member type of validated geo::PlaneID parameter.
T abs(T value)
void init(const std::vector< art::Ptr< recob::SpacePoint >> &sps, art::FindManyP< recob::Hit > &hitFromSp)
Definition: DBScan3DAlg.cxx:29
auto end(FixedBins< T, C > const &) noexcept
Definition: FixedBins.h:585
auto norm(Vector const &v)
Return norm of the specified vector.
tuple dir
Definition: dropbox.py:28
auto begin(FixedBins< T, C > const &) noexcept
Definition: FixedBins.h:573
bool CreateAssn(art::Event &evt, std::vector< T > const &a, art::Ptr< U > const &b, art::Assns< U, T > &assn, std::string a_instance, size_t index=UINT_MAX)
Creates a single one-to-one association.
std::vector< point_t > points
Definition: DBScan3DAlg.h:82
TCEvent evt
Definition: DataStructs.cxx:8
recob::tracking::Vector_t Vector_t
BEGIN_PROLOG could also be cout

Member Data Documentation

DBScan3DAlg cluster::DBCluster3D::fDBScan
private

Definition at line 57 of file DBCluster3D_module.cc.

geo::GeometryCore const* cluster::DBCluster3D::fGeom
private

Definition at line 59 of file DBCluster3D_module.cc.

const art::InputTag cluster::DBCluster3D::fHitModuleLabel
private

Definition at line 53 of file DBCluster3D_module.cc.

double cluster::DBCluster3D::fMinHitDis
private

Definition at line 62 of file DBCluster3D_module.cc.

const art::InputTag cluster::DBCluster3D::fSpacePointModuleLabel
private

Definition at line 54 of file DBCluster3D_module.cc.

const art::InputTag cluster::DBCluster3D::fSPHitAssnLabel
private

Definition at line 55 of file DBCluster3D_module.cc.

double cluster::DBCluster3D::tickToDist
private

Definition at line 61 of file DBCluster3D_module.cc.


The documentation for this class was generated from the following file: