16 #include "TPrincipal.h" 25 fTree =
tfs->make<TTree>(
"MatchingVariables",
"MatchingVariables");
26 fTree->Branch(
"Angle", &
fAngle);
40 TVector2
const& centre,
41 TVector2
const& direction,
47 std::map<double, TVector2> hitProjection;
50 for (
auto&
hit : cluster) {
52 hitProjection[direction * pos] = pos;
56 start = hitProjection.begin()->second.Proj(direction) + centre;
57 end = hitProjection.rbegin()->second.Proj(direction) + centre;
61 TVector2
const& centre,
62 TVector2
const& start1,
64 TVector2
const& start2,
65 TVector2
const& end2)
const 69 double clusterOverlap = 0;
72 double s1 = (start1 - centre) * direction;
73 double e1 = (end1 - centre) * direction;
74 double s2 = (start2 - centre) * direction;
75 double e2 = (end2 - centre) * direction;
79 std::cout <<
"s1>e1: " << s1 <<
" and " << e1 << std::endl;
85 std::cout <<
"s1>e1: " << s1 <<
" and " << e1 << std::endl;
92 if ((e1 > s2) && (e2 > s1)) clusterOverlap = std::min((e1 - s2), (e2 - s1));
94 return clusterOverlap;
98 TVector2
const& centre1,
99 TVector2
const& direction2,
100 TVector2
const& centre2)
const 105 double dcross = (direction1.X() * direction2.Y()) - (direction1.Y() * direction2.X());
106 TVector2 p = centre2 - centre1;
107 double pcrossd = (p.X() * direction2.Y()) - (p.Y() * direction2.X());
108 TVector2 crossing = centre1 + ((pcrossd / dcross) * direction1);
111 return std::min((centre1 - crossing).Mod(), (centre2 - crossing).Mod());
119 double minDistance = 99999.;
122 for (
auto const& hit1 : cluster1) {
123 for (
auto const& hit2 : cluster2) {
128 double distance = (pos1 - pos2).Mod();
130 if (distance < minDistance) minDistance = distance;
138 TVector2
const& start1,
139 TVector2
const& end1,
140 TVector2
const& centre2,
141 TVector2
const& start2,
142 TVector2
const& end2)
const 147 TVector2 parallel = (centre2 - centre1).Unit();
148 TVector2 perpendicular = parallel.Rotate(TMath::Pi() / 2);
151 double s1 = (start1 - centre1) * perpendicular;
152 double e1 = (end1 - centre1) * perpendicular;
153 double s2 = (start2 - centre2) * perpendicular;
154 double e2 = (end2 - centre2) * perpendicular;
157 double projectionStart = std::max(TMath::Abs(s1), TMath::Abs(s2));
158 double projectionEnd = std::max(TMath::Abs(e1), TMath::Abs(e2));
160 return projectionStart + projectionEnd;
188 std::vector<unsigned int> mergedClusters;
190 std::vector<art::PtrVector<recob::Hit>> oldClusters = planeClusters;
193 std::sort(oldClusters.begin(),
196 return a.
size() > b.size();
200 unsigned int nclusters = 0;
201 for (
auto&
cluster : oldClusters)
205 bool mergedAllClusters =
false;
206 while (!mergedAllClusters) {
212 for (
unsigned int initCluster = 0; initCluster < oldClusters.size(); ++initCluster) {
214 std::find(mergedClusters.begin(), mergedClusters.end(), initCluster) !=
215 mergedClusters.end())
217 cluster = oldClusters.
at(initCluster);
218 mergedClusters.push_back(initCluster);
223 bool mergedAllToThisCluster =
false;
224 while (!mergedAllToThisCluster) {
228 for (
unsigned int trialCluster = 0; trialCluster < oldClusters.size(); ++trialCluster) {
231 std::find(mergedClusters.begin(), mergedClusters.end(), trialCluster) !=
232 mergedClusters.end())
236 TPrincipal *pca1 =
new TPrincipal(2,
""), *pca2 =
new TPrincipal(2,
"");
241 TVector2 chargePoint1 = TVector2(0, 0), chargePoint2 = TVector2(0, 0);
242 double totalCharge1 = 0, totalCharge2 = 0;
244 for (
auto& hit1 : cluster) {
249 chargePoint1 += hit1->Integral() * pos;
250 totalCharge1 += hit1->Integral();
252 for (
auto& hit2 : oldClusters.at(trialCluster)) {
257 chargePoint2 += hit2->Integral() * pos;
258 totalCharge2 += hit2->Integral();
261 pca1->MakePrincipals();
262 pca2->MakePrincipals();
265 TVector2 direction1 =
266 TVector2((*pca1->GetEigenVectors())[0][0], (*pca1->GetEigenVectors())[1][0]).Unit();
267 TVector2 direction2 =
268 TVector2((*pca2->GetEigenVectors())[0][0], (*pca2->GetEigenVectors())[1][0]).Unit();
269 TVector2 direction = ((direction1 + direction2) / 2).Unit();
270 TVector2 centre1 = chargePoint1 / totalCharge1;
271 TVector2 centre2 = chargePoint2 / totalCharge2;
272 TVector2 centre = (centre1 + centre2) / 2;
273 TVector2 start1, end1;
274 TVector2 start2, end2;
277 double length1 = (end1 - start1).Mod();
278 double length2 = (end2 - start2).Mod();
282 double projectedWidth =
FindProjectedWidth(centre1, start1, end1, centre2, start2, end2);
283 double angle = direction1.DeltaPhi(direction2);
284 if (angle > 1.57) angle = 3.14159 - angle;
289 angle, crossingDistance, projectedWidth, separation, TMath::Max(length1, length2))) {
291 for (
auto&
hit : oldClusters.at(trialCluster))
292 cluster.push_back(
hit);
294 mergedClusters.push_back(trialCluster);
303 if (nadded == 0) mergedAllToThisCluster =
true;
307 clusters.push_back(cluster);
308 if (mergedClusters.size() == nclusters) mergedAllClusters =
true;
311 return clusters.size();
315 double const crossingDistance,
316 double const projectedWidth,
317 double const separation,
318 double const longLength)
const 322 bool passCrossingDistanceAngle =
false;
323 if (crossingDistance < (-2 + (5 / (1 * TMath::Abs(angle)) - 0))) passCrossingDistanceAngle =
true;
325 bool passSeparationAngle =
false;
326 if (separation < (200 * TMath::Abs(angle) + 40)) passSeparationAngle =
true;
328 bool passProjectedWidth =
false;
330 passProjectedWidth =
true;
332 return passCrossingDistanceAngle and passSeparationAngle and passProjectedWidth;
MergeClusterAlg(fhicl::ParameterSet const &pset)
Point_t const & GetCenter() const
Returns the world coordinate of the center of the wire [cm].
int MergeClusters(std::vector< art::PtrVector< recob::Hit >> const &planeClusters, std::vector< art::PtrVector< recob::Hit >> &clusters) const
unsigned int Nwires(PlaneID const &planeid) const
Returns the total number of wires in the specified plane.
double WireCoordinate(Point_t const &point) const
Returns the coordinate of the point on the plane, in wire units.
The data type to uniquely identify a Plane.
void FindClusterEndPoints(art::PtrVector< recob::Hit > const &cluster, TVector2 const ¢re, TVector2 const &direction, TVector2 &start, TVector2 &end) const
art::ServiceHandle< art::TFileService const > tfs
CryostatID_t Cryostat
Index of cryostat.
cout<< "Opened file "<< fin<< " ixs= "<< ixs<< endl;if(ixs==0) hhh=(TH1F *) fff-> Get("h1")
WireID_t Wire
Index of the wire within its plane.
geo::WireID const & WireID() const
Initial tdc tick for hit.
SigType_t SignalType(PlaneID const &pid) const
Returns the type of signal on the channels of specified TPC plane.
Cluster finding and building.
geo::WireReadoutGeom const * fWireReadoutGeom
WireGeo const & Wire(WireID const &wireid) const
Returns the specified wire.
double FindClusterOverlap(TVector2 const &direction, TVector2 const ¢re, TVector2 const &start1, TVector2 const &end1, TVector2 const &start2, TVector2 const &end2) const
decltype(auto) constexpr end(T &&obj)
ADL-aware version of std::end.
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
Signal from induction planes.
double fProjWidthThreshold
reference at(size_type n)
PlaneID_t Plane
Index of the plane within its TPC.
Detector simulation of raw signals on wires.
TVector2 HitCoordinates(art::Ptr< recob::Hit > const &hit) const
float PeakTime() const
Time of the signal peak, in tick units.
double FindMinSeparation(art::PtrVector< recob::Hit > const &cluster1, art::PtrVector< recob::Hit > const &cluster2) const
double FindCrossingDistance(TVector2 const &direction1, TVector2 const ¢re1, TVector2 const &direction2, TVector2 const ¢re2) const
double GlobalWire(geo::WireID const &wireID) const
PlaneGeo const & Plane(TPCID const &tpcid, View_t view) const
Returns the specified wire.
bool PassCuts(double angle, double crossingDistance, double projectedWidth, double separation, double longLength) const
TPCID_t TPC
Index of the TPC within its cryostat.
double FindProjectedWidth(TVector2 const ¢re1, TVector2 const &start1, TVector2 const &end1, TVector2 const ¢re2, TVector2 const &start2, TVector2 const &end2) const
unsigned int fMinMergeClusterSize
double fMaxMergeSeparation