145 auto ClusterHandle = e.
getHandle< std::vector<gar::rec::Cluster> >(itag);
146 if (!ClusterHandle)
return;
149 if (!TrackHandle)
return;
156 std::unique_ptr<art::Assns<gar::rec::Cluster, gar::rec::Track, gar::rec::TrackEnd>>
162 std::vector<art::Ptr<gar::rec::Track>> candTrack;
163 std::vector<gar::rec::TrackEnd> candEnd;
164 std::vector<float> candDist;
167 for (
size_t iCluster=0; iCluster<ClusterHandle->size(); ++iCluster) {
169 TVector3 clusterCenter(cluster.
Position());
173 float yClus = clusterCenter[1];
174 float zClus = clusterCenter[2];
176 float xClus = clusterCenter[0];
178 for (
size_t iTrack=0; iTrack<TrackHandle->size(); ++iTrack) {
182 bool outside[2]; outside[0] = outside[1] =
false;
183 candTrack.clear(); candEnd.clear(); candDist.clear();
203 float trackPar[5];
float trackEnd[3];
205 for (
int i=0; i<5; ++i) trackPar[i] = track.
TrackParBeg()[i];
206 for (
int i=0; i<3; ++i) trackEnd[i] = track.
Vertex()[i];
208 for (
int i=0; i<5; ++i) trackPar[i] = track.
TrackParEnd()[i];
209 for (
int i=0; i<3; ++i) trackEnd[i] = track.
End()[i];
213 for (
int i=0; i<3; ++i) trackEnd[i] -=
ItsInTulsa[i];
214 float radius = 1.0/trackPar[2];
215 float zCent = trackPar[1] - radius*sin(trackPar[3]);
216 float yCent = trackPar[0] + radius*cos(trackPar[3]);
218 float distRadially =
std::hypot(zClus-zCent,yClus-yCent) -
abs(radius);
219 distRadially =
abs(distRadially);
229 float retXYZ1[3];
float retXYZ2[3];
236 trackPar,trackEnd,rClus, 0.0, 0.0, retXYZ1,retXYZ2);
244 float transDist1 =
std::hypot(retXYZ1[2]-zClus,retXYZ1[1]-yClus);
245 float transDist2 =
std::hypot(retXYZ2[2]-zClus,retXYZ2[1]-yClus);
247 if (transDist1<transDist2) {
248 trackXYZ.SetXYZ(retXYZ1[0],retXYZ1[1],retXYZ1[2]);
250 trackXYZ.SetXYZ(retXYZ2[0],retXYZ2[1],retXYZ2[2]);
255 if (looneyExtrap)
continue;
259 extrapXerr = trackXYZ.X() -xClus;
263 float expected_mean = 0;
266 float cutQuantity = extrapXerr -expected_mean;
278 if (
abs(radiansInDrift) >= 2.0*
M_PI ) {
286 trackPar,trackEnd, xClus, retXYZ1);
292 trackXYZ.SetXYZ(retXYZ1[0],retXYZ1[1],retXYZ1[2]);
296 if (looneyExtrap)
continue;
303 float angClus = std::atan2(yClus-yCent,zClus-zCent);
304 float angXtrap = std::atan2(retXYZ1[1] -yCent,retXYZ1[2] -zCent) -angClus;
306 if (angXtrap > +
M_PI) angXtrap -= 2.0*
M_PI;
307 if (angXtrap < -
M_PI) angXtrap += 2.0*
M_PI;
309 float extrapRphiErr =
abs(radius)*angXtrap;
319 float xEval = trackXYZ.x();
321 trackPar,trackEnd, xEval,trackDir);
331 float dotSee = clusterDir.Dot(trackDir);
341 candTrack.push_back(trackPtr);
342 candEnd.push_back(iEnd);
343 float howFar =
std::hypot(trackXYZ.x() -xClus, trackXYZ.y() -yClus, trackXYZ.z() -zClus);
344 candDist.push_back(howFar);
349 if (candEnd.size()==0)
continue;
352 if (candEnd.size()==2) {
353 if (candDist[0]>candDist[1]) {
354 trackPtrBest = candTrack[1];
355 candEndBest = candEnd[1];
359 ClusterTrackAssns->addSingle(clusterPtr,trackPtrBest,candEndBest);
TH2F * xClusTrack
Cluster to track in barrel, x only, vs x of trackend.
const float * TrackParBeg() const
const detinfo::DetectorProperties * fDetProp
detector properties
Handle< PROD > getHandle(SelectorBase const &) const
bool PointInECALEndcap(TVector3 const &point) const
virtual double SpillLength() const =0
Duration of spill [ns].
std::string fInstanceName
float fTrackEndRCut
Extrapolate only track ends outside central region.
TH1F * nEntryVsCut
Number passing each cut.
TH1F * radClusTrack
Cluster to track in transverse plane.
const detinfo::DetectorClocks * fClocks
detector clock information
float fBarrelXCut
Max dist cluster center (drift time compensated) track in x.
Cluster finding and building.
TrackEnd const TrackEndEnd
const geo::GeometryCore * fGeo
pointer to the geometry
TH1F * phiClusTrack
Cluster to track in endcap.
std::enable_if_t< std::is_arithmetic_v< T >, T > hypot(T x, T y)
virtual double Efield(unsigned int planegap=0) const =0
Returns the nominal electric field in the specified volume.
float fEndcapRphiCut
Max dist cluster center (drift time compensated) track in r*phi.
float fPerpRCut
Max dist cluster center to circle of track (z,y) only.
const float * Vertex() const
const std::vector< gar::rec::CaloHit * > & CalorimeterHits() const
static int PropagateToX(const float *trackpar, const float *Xpoint, const float x, float *retXYZ, const float Rmax=0.0)
const float * TrackParEnd() const
static int PropagateToCylinder(const float *trackpar, const float *Xpoint, const float rCyl, const float yCyl, const float zCyl, float *retXYZ1, float *retXYZ2, const float Xmax=0.0, const float epsilon=2.0e-5)
bool PointInECALBarrel(TVector3 const &point) const
const float * EigenVectors() const
std::string fClusterLabel
label to find the right reco caloclusters
virtual double Temperature() const =0
const float * End() const
TH2F * dotClustTrack
cos(cluster axis to extrapolated track)
std::string fTrackLabel
label to find the reco tracks
const float * Position() const
TrackEnd const TrackEndBeg
static int DirectionX(const float *trackpar, const float *Xpoint, float &xEval, float *retXYZ)
float fTrackEndXCut
Extrapolate only track ends outside central drift.
float fClusterDirCut
Min cos angle between extrapolated track and cluster direction.
virtual double DriftVelocity(double efield=0., double temperature=0., bool cmPerns=true) const =0
float fClusterDirNhitCut
Do not cut on cluster direction unless you have this many hits or more.