17 fTree =
tfs->
make<TTree>(
"MatchingVariables",
"MatchingVariables");
36 std::map<double,TVector2> hitProjection;
39 for (
auto &
hit : cluster) {
41 hitProjection[direction*pos] = pos;
45 start = hitProjection.begin()->second.Proj(direction) + centre;
46 end = hitProjection.rbegin()->second.Proj(direction) + centre;
56 double clusterOverlap = 0;
59 double s1 = (start1-centre)*direction;
60 double e1 = (end1-centre)*direction;
61 double s2 = (start2-centre)*direction;
62 double e2 = (end2-centre)*direction;
66 std::cout <<
"s1>e1: " << s1 <<
" and " << e1 << std::endl;
72 std::cout <<
"s1>e1: " << s1 <<
" and " << e1 << std::endl;
79 if ((e1 > s2) && (e2 > s1))
80 clusterOverlap =
std::min((e1 - s2), (e2 - s1));
82 return clusterOverlap;
91 double dcross = (direction1.X() * direction2.Y()) - (direction1.Y() * direction2.X());
92 TVector2 p = centre2 - centre1;
93 double pcrossd = (p.X() * direction2.Y()) - (p.Y() * direction2.X());
94 TVector2 crossing = centre1 + ((pcrossd/dcross) * direction1);
97 double crossingDistance =
std::min((centre1-crossing).Mod(),(centre2-crossing).Mod());
99 return crossingDistance;
107 double minDistance = 99999.;
110 for (
auto const& hit1 : cluster1) {
111 for (
auto const& hit2 : cluster2) {
116 double distance = (pos1 - pos2).Mod();
118 if (distance < minDistance) minDistance = distance;
132 TVector2 parallel = (centre2 - centre1).Unit();
133 TVector2 perpendicular = parallel.Rotate(TMath::Pi()/2);
136 double s1 = (start1-centre1)*perpendicular;
137 double e1 = (end1-centre1)*perpendicular;
138 double s2 = (start2-centre2)*perpendicular;
139 double e2 = (end2-centre2)*perpendicular;
142 double projectionStart =
std::max(TMath::Abs(s1), TMath::Abs(s2));
143 double projectionEnd =
std::max(TMath::Abs(e1), TMath::Abs(e2));
145 double projectionWidth = projectionStart + projectionEnd;
147 return projectionWidth;
155 double wireCentre[3];
300 std::vector<unsigned int> mergedClusters;
302 std::vector<art::PtrVector<recob::Hit> > oldClusters = planeClusters;
308 unsigned int nclusters = 0;
309 for (
auto &
cluster : oldClusters)
313 bool mergedAllClusters =
false;
314 while (!mergedAllClusters) {
320 for (
unsigned int initCluster = 0; initCluster < oldClusters.size(); ++initCluster) {
321 if (oldClusters.at(initCluster).size() <
fMinMergeClusterSize or std::find(mergedClusters.begin(), mergedClusters.end(), initCluster) != mergedClusters.end())
continue;
322 cluster = oldClusters.
at(initCluster);
323 mergedClusters.push_back(initCluster);
328 bool mergedAllToThisCluster =
false;
329 while (!mergedAllToThisCluster) {
333 for (
unsigned int trialCluster = 0; trialCluster < oldClusters.size(); ++trialCluster) {
335 if (oldClusters.at(trialCluster).size() <
fMinMergeClusterSize or std::find(mergedClusters.begin(), mergedClusters.end(), trialCluster) != mergedClusters.end())
continue;
338 TPrincipal *pca1 =
new TPrincipal(2,
""), *pca2 =
new TPrincipal(2,
"");
343 TVector2 chargePoint1 = TVector2(0,0), chargePoint2 = TVector2(0,0);
344 double totalCharge1 = 0, totalCharge2 = 0;
346 for (
auto &hit1 : cluster) {
351 chargePoint1 += hit1->Integral() * pos;
352 totalCharge1 += hit1->Integral();
354 for (
auto &hit2 : oldClusters.at(trialCluster)) {
359 chargePoint2 += hit2->Integral() * pos;
360 totalCharge2 += hit2->Integral();
363 pca1->MakePrincipals();
364 pca2->MakePrincipals();
367 TVector2 direction1 = TVector2( (*pca1->GetEigenVectors())[0][0], (*pca1->GetEigenVectors())[1][0] ).Unit();
368 TVector2 direction2 = TVector2( (*pca2->GetEigenVectors())[0][0], (*pca2->GetEigenVectors())[1][0] ).Unit();
369 TVector2 direction = ((direction1+direction2)/2).Unit();
370 TVector2 centre1 = chargePoint1 / totalCharge1;
371 TVector2 centre2 = chargePoint2 / totalCharge2;
372 TVector2 centre = (centre1+centre2)/2;
373 TVector2 start1, end1;
374 TVector2 start2, end2;
377 double length1 = (end1-start1).Mod();
378 double length2 = (end2-start2).Mod();
382 double projectedWidth =
FindProjectedWidth(centre1, start1, end1, centre2, start2, end2);
383 double angle = direction1.DeltaPhi(direction2);
384 if (angle > 1.57) angle = 3.14159 - angle;
390 if (
PassCuts(angle, crossingDistance, projectedWidth, separation, overlap, TMath::Max(length1, length2))) {
392 for (
auto &
hit : oldClusters.at(trialCluster))
393 cluster.push_back(
hit);
395 mergedClusters.push_back(trialCluster);
405 if (nadded == 0) mergedAllToThisCluster =
true;
409 clusters.push_back(cluster);
410 if (mergedClusters.size() == nclusters) mergedAllClusters =
true;
414 return clusters.size();
418 bool cluster::MergeClusterAlg::PassCuts(
double const& angle,
double const& crossingDistance,
double const& projectedWidth,
double const& separation,
double const& overlap,
double const& longLength) {
422 bool passCrossingDistanceAngle =
false;
423 if (crossingDistance < (-2 + (5 / (1 * TMath::Abs(angle)) - 0) ) )
424 passCrossingDistanceAngle =
true;
426 bool passSeparationAngle =
false;
427 if (separation < (200 * TMath::Abs(angle) + 40))
428 passSeparationAngle =
true;
430 bool passProjectedWidth =
false;
432 passProjectedWidth =
true;
434 return passCrossingDistanceAngle and passSeparationAngle and passProjectedWidth;
geo::Length_t WireCoordinate(double YPos, double ZPos, geo::PlaneID const &planeid) const
Returns the index of the nearest wire to the specified position.
MergeClusterAlg(fhicl::ParameterSet const &pset)
art::ServiceHandle< art::TFileService > tfs
geo::WireID WireID() const
Initial tdc tick for hit.
int MergeClusters(std::vector< art::PtrVector< recob::Hit > > const &planeClusters, std::vector< art::PtrVector< recob::Hit > > &clusters)
CryostatID_t Cryostat
Index of cryostat.
WireID_t Wire
Index of the wire within its plane.
SigType_t SignalType(geo::PlaneID const &pid) const
Returns the type of signal on the channels of specified TPC plane.
Cluster finding and building.
TVector2 HitCoordinates(art::Ptr< recob::Hit > const &hit)
unsigned int Nwires(unsigned int p, unsigned int tpc=0, unsigned int cstat=0) const
Returns the total number of wires in the specified plane.
void reconfigure(fhicl::ParameterSet const &p)
double FindProjectedWidth(TVector2 const ¢re1, TVector2 const &start1, TVector2 const &end1, TVector2 const ¢re2, TVector2 const &start2, TVector2 const &end2)
void FindClusterEndPoints(art::PtrVector< recob::Hit > const &cluster, TVector2 const ¢re, TVector2 const &direction, TVector2 &start, TVector2 &end)
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
Signal from induction planes.
T get(std::string const &key) const
double FindMinSeparation(art::PtrVector< recob::Hit > const &cluster1, art::PtrVector< recob::Hit > const &cluster2)
double fProjWidthThreshold
reference at(size_type n)
PlaneID_t Plane
Index of the plane within its TPC.
double FindCrossingDistance(TVector2 const &direction1, TVector2 const ¢re1, TVector2 const &direction2, TVector2 const ¢re2)
Detector simulation of raw signals on wires.
float PeakTime() const
Time of the signal peak, in tick units.
T * make(ARGS...args) const
double GlobalWire(geo::WireID const &wireID)
std::vector< evd::details::RawDigitInfo_t >::const_iterator end(RawDigitCacheDataClass const &cache)
void GetCenter(double *xyz, double localz=0.0) const
Fills the world coordinate of a point on the wire.
TPCID_t TPC
Index of the TPC within its cryostat.
double FindClusterOverlap(TVector2 const &direction, TVector2 const ¢re, TVector2 const &start1, TVector2 const &end1, TVector2 const &start2, TVector2 const &end2)
unsigned int fMinMergeClusterSize
double fMaxMergeSeparation
bool PassCuts(double const &angle, double const &crossingDistance, double const &projectedWidth, double const &separation, double const &overlap, double const &longLength)
art::ServiceHandle< geo::Geometry > fGeom
WireGeo const & WireIDToWireGeo(geo::WireID const &wireid) const
Returns the specified wire.