15 #include "TPrincipal.h" 20 fTree =
tfs->make<TTree>(
"MatchingVariables",
"MatchingVariables");
39 std::map<double,TVector2> hitProjection;
42 for (
auto &
hit : cluster) {
44 hitProjection[direction*
pos] =
pos;
48 start = hitProjection.begin()->second.Proj(direction) + centre;
49 end = hitProjection.rbegin()->second.Proj(direction) + centre;
59 double clusterOverlap = 0;
62 double s1 = (start1-centre)*direction;
63 double e1 = (end1-centre)*direction;
64 double s2 = (start2-centre)*direction;
65 double e2 = (end2-centre)*direction;
69 std::cout <<
"s1>e1: " << s1 <<
" and " << e1 <<
std::endl;
75 std::cout <<
"s1>e1: " << s1 <<
" and " << e1 <<
std::endl;
82 if ((e1 > s2) && (e2 > s1))
83 clusterOverlap =
std::min((e1 - s2), (e2 - s1));
85 return clusterOverlap;
94 double dcross = (direction1.X() * direction2.Y()) - (direction1.Y() * direction2.X());
95 TVector2
p = centre2 - centre1;
96 double pcrossd = (p.X() * direction2.Y()) - (p.Y() * direction2.X());
97 TVector2 crossing = centre1 + ((pcrossd/dcross) * direction1);
100 double crossingDistance =
std::min((centre1-crossing).Mod(),(centre2-crossing).Mod());
102 return crossingDistance;
110 double minDistance = 99999.;
113 for (
auto const& hit1 : cluster1) {
114 for (
auto const& hit2 : cluster2) {
119 double distance = (pos1 - pos2).Mod();
121 if (distance < minDistance) minDistance =
distance;
135 TVector2 parallel = (centre2 - centre1).Unit();
136 TVector2 perpendicular = parallel.Rotate(TMath::Pi()/2);
139 double s1 = (start1-centre1)*perpendicular;
140 double e1 = (end1-centre1)*perpendicular;
141 double s2 = (start2-centre2)*perpendicular;
142 double e2 = (end2-centre2)*perpendicular;
145 double projectionStart =
std::max(TMath::Abs(s1), TMath::Abs(s2));
146 double projectionEnd =
std::max(TMath::Abs(e1), TMath::Abs(e2));
148 double projectionWidth = projectionStart + projectionEnd;
150 return projectionWidth;
158 double wireCentre[3];
303 std::vector<unsigned int> mergedClusters;
305 std::vector<art::PtrVector<recob::Hit> > oldClusters = planeClusters;
311 unsigned int nclusters = 0;
312 for (
auto &
cluster : oldClusters)
316 bool mergedAllClusters =
false;
317 while (!mergedAllClusters) {
323 for (
unsigned int initCluster = 0; initCluster < oldClusters.size(); ++initCluster) {
324 if (oldClusters.at(initCluster).size() <
fMinMergeClusterSize or std::find(mergedClusters.begin(), mergedClusters.end(), initCluster) != mergedClusters.end())
continue;
325 cluster = oldClusters.at(initCluster);
326 mergedClusters.push_back(initCluster);
331 bool mergedAllToThisCluster =
false;
332 while (!mergedAllToThisCluster) {
336 for (
unsigned int trialCluster = 0; trialCluster < oldClusters.size(); ++trialCluster) {
338 if (oldClusters.at(trialCluster).size() <
fMinMergeClusterSize or std::find(mergedClusters.begin(), mergedClusters.end(), trialCluster) != mergedClusters.end())
continue;
341 TPrincipal *pca1 =
new TPrincipal(2,
""), *pca2 =
new TPrincipal(2,
"");
346 TVector2 chargePoint1 = TVector2(0,0), chargePoint2 = TVector2(0,0);
347 double totalCharge1 = 0, totalCharge2 = 0;
349 for (
auto &hit1 : cluster) {
354 chargePoint1 += hit1->Integral() *
pos;
355 totalCharge1 += hit1->Integral();
357 for (
auto &hit2 : oldClusters.at(trialCluster)) {
362 chargePoint2 += hit2->Integral() *
pos;
363 totalCharge2 += hit2->Integral();
366 pca1->MakePrincipals();
367 pca2->MakePrincipals();
370 TVector2 direction1 = TVector2( (*pca1->GetEigenVectors())[0][0], (*pca1->GetEigenVectors())[1][0] ).Unit();
371 TVector2 direction2 = TVector2( (*pca2->GetEigenVectors())[0][0], (*pca2->GetEigenVectors())[1][0] ).Unit();
372 TVector2
direction = ((direction1+direction2)/2).Unit();
373 TVector2 centre1 = chargePoint1 / totalCharge1;
374 TVector2 centre2 = chargePoint2 / totalCharge2;
375 TVector2 centre = (centre1+centre2)/2;
376 TVector2 start1, end1;
377 TVector2 start2, end2;
380 double length1 = (end1-start1).Mod();
381 double length2 = (end2-start2).Mod();
385 double projectedWidth =
FindProjectedWidth(centre1, start1, end1, centre2, start2, end2);
386 double angle = direction1.DeltaPhi(direction2);
387 if (angle > 1.57) angle = 3.14159 - angle;
393 if (
PassCuts(angle, crossingDistance, projectedWidth, separation, overlap, TMath::Max(length1, length2))) {
395 for (
auto &
hit : oldClusters.at(trialCluster))
396 cluster.push_back(
hit);
398 mergedClusters.push_back(trialCluster);
408 if (nadded == 0) mergedAllToThisCluster =
true;
412 clusters.push_back(cluster);
413 if (mergedClusters.size() == nclusters) mergedAllClusters =
true;
417 return clusters.size();
421 bool cluster::MergeClusterAlg::PassCuts(
double const& angle,
double const& crossingDistance,
double const& projectedWidth,
double const& separation,
double const& overlap,
double const& longLength)
const {
425 bool passCrossingDistanceAngle =
false;
426 if (crossingDistance < (-2 + (5 / (1 * TMath::Abs(angle)) - 0) ) )
427 passCrossingDistanceAngle =
true;
429 bool passSeparationAngle =
false;
430 if (separation < (200 * TMath::Abs(angle) + 40))
431 passSeparationAngle =
true;
433 bool passProjectedWidth =
false;
435 passProjectedWidth =
true;
437 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.
end
while True: pbar.update(maxval-len(onlies[E][S])) #print iS, "/", len(onlies[E][S]) found = False for...
MergeClusterAlg(fhicl::ParameterSet const &pset)
art::ServiceHandle< geo::Geometry const > fGeom
geo::WireID WireID() const
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.
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.
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 FindClusterOverlap(TVector2 const &direction, TVector2 const ¢re, TVector2 const &start1, TVector2 const &end1, TVector2 const &start2, TVector2 const &end2) const
int MergeClusters(std::vector< art::PtrVector< recob::Hit > > const &planeClusters, std::vector< art::PtrVector< recob::Hit > > &clusters) const
Signal from induction planes.
bool PassCuts(double const &angle, double const &crossingDistance, double const &projectedWidth, double const &separation, double const &overlap, double const &longLength) const
T get(std::string const &key) const
double fProjWidthThreshold
double distance(double x1, double y1, double z1, double x2, double y2, double z2)
static int max(int a, int b)
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
T min(sqlite3 *const db, std::string const &table_name, std::string const &column_name)
double FindCrossingDistance(TVector2 const &direction1, TVector2 const ¢re1, TVector2 const &direction2, TVector2 const ¢re2) const
double GlobalWire(geo::WireID const &wireID) const
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 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
QTextStream & endl(QTextStream &s)
WireGeo const & WireIDToWireGeo(geo::WireID const &wireid) const