lcsim/src/org/lcsim/recon/pfa/identifier
diff -u -r1.4 -r1.5
--- TrackHelixExtrapolator.java 23 Sep 2008 18:26:03 -0000 1.4
+++ TrackHelixExtrapolator.java 9 Oct 2008 21:38:28 -0000 1.5
@@ -76,13 +76,44 @@
// Get helix fit output
m_alphaIntercept = Double.NaN;
if (isValidBarrelIntercept(m_swimmer, alphaBarrel, m_cutSeparation)) {
- m_alphaIntercept = alphaBarrel;
validBarrel = true;
- } else if (isValidEndcapIntercept(m_swimmer, alphaEndcap, m_cutSeparation)) {
- m_alphaIntercept = alphaEndcap;
+ }
+ if (isValidEndcapIntercept(m_swimmer, alphaEndcap, m_cutSeparation)) {
validEndcap = true;
}
+ // Check for special case in corner of barrel/endcap overlap region
+ if ( validEndcap && validBarrel ) {
+ // Both apparently valid... check again
+ boolean tightValidEndcap = isValidEndcapIntercept(m_swimmer, alphaEndcap, 0.0);
+ boolean tightValidBarrel = isValidBarrelIntercept(m_swimmer, alphaBarrel, 0.0);
+ if (tightValidEndcap && tightValidBarrel) {
+ // This can happen if the track has moderate pT -- it goes into the
+ // barrel, spirals out again, and eventually hits the endcap.
+ // If this is what happened then it should reach the barrel first.
+ if (alphaEndcap < alphaBarrel) {
+ Hep3Vector interceptEndcap = m_swimmer.getPointAtDistance(alphaEndcap);
+ Hep3Vector interceptBarrel = m_swimmer.getPointAtDistance(alphaBarrel);
+ double rEndcap = Math.sqrt(interceptEndcap.x()*interceptEndcap.x() + interceptEndcap.y()*interceptEndcap.y());
+ double rBarrel = Math.sqrt(interceptBarrel.x()*interceptBarrel.x() + interceptBarrel.y()*interceptBarrel.y());
+ double zEndcap = interceptEndcap.z();
+ double zBarrel = interceptBarrel.z();
+ throw new AssertionError("Track hits endcap THEN barrel -- this doesn't make sense!\nEndcap intercept at alpha="+alphaEndcap+" has r="+rEndcap+", z="+zEndcap+"\nBarrel intercept at alpha="+alphaBarrel+" has r="+rBarrel+", z="+zBarrel);
+ } else {
+ validEndcap = false;
+ }
+ } else if (!tightValidEndcap && !tightValidBarrel) {
+ throw new AssertionError("Invalid state");
+ } else {
+ // Only one valid solution -- OK
+ validEndcap = tightValidEndcap;
+ validBarrel = tightValidBarrel;
+ }
+ }
+
+ if (validEndcap) { m_alphaIntercept = alphaEndcap; }
+ if (validBarrel) { m_alphaIntercept = alphaBarrel; }
+
// Did we make a successful extrapolation?
if ( Double.isNaN(m_alphaIntercept)) {
// No -- extrapolation failed
@@ -92,23 +123,11 @@
// Invalid state
if (m_debug) { System.out.println("DEBUG: "+this.getClass().getName()+" failed to extrapolate: not a valid barrel or endcap point"); }
return null;
+ } else if ( validEndcap && validBarrel ) {
+ // Invalid state
+ if (m_debug) { System.out.println("DEBUG: "+this.getClass().getName()+" failed to extrapolate: valid barrel AND endcap point"); }
+ throw new AssertionError("DEBUG: "+this.getClass().getName()+" failed to extrapolate: valid barrel AND endcap point");
} else {
- // One or both solutions valid.
- if ( validEndcap && validBarrel ) {
- // Both apparently valid... check again
- boolean tightValidEndcap = isValidEndcapIntercept(m_swimmer, alphaEndcap, 0.0);
- boolean tightValidBarrel = isValidBarrelIntercept(m_swimmer, alphaBarrel, 0.0);
- if (tightValidEndcap && tightValidBarrel) {
- throw new AssertionError("Invalid state");
- } else if (!tightValidEndcap && !tightValidBarrel) {
- throw new AssertionError("Invalid state");
- } else {
- // Only one valid solution -- OK
- validEndcap = tightValidEndcap;
- validBarrel = tightValidBarrel;
- }
- }
-
// Extrapolation succeeded.
m_intercept = m_swimmer.getPointAtDistance(m_alphaIntercept);
m_barrelValid = validBarrel;
@@ -180,12 +199,14 @@
}
}
protected boolean isValidBarrelIntercept(HelixSwimmer swimmer, double alpha, double uncertainty) {
- // Must have -m_ECAL_barrel_z <= z <= +m_ECAL_barrel_z (within errors)
+ // OLD: // Must have -m_ECAL_barrel_z <= z <= +m_ECAL_barrel_z (within errors)
+ // NEW: // Above AND must have -m_ECAL_endcap_z <= z <= m_ECAL_endcap_z
//double uncertainty = m_cutSeparation;
Hep3Vector intercept = swimmer.getPointAtDistance(alpha);
double z = intercept.z();
- boolean zInRange = (z >= m_ECAL_barrel_zmin-uncertainty && z <= m_ECAL_barrel_zmax+uncertainty);
- return zInRange;
+ boolean zInRangeBarrel = (z >= m_ECAL_barrel_zmin-uncertainty && z <= m_ECAL_barrel_zmax+uncertainty);
+ boolean vetoEndcap = (z >= -m_ECAL_endcap_z && z <= m_ECAL_endcap_z);
+ return zInRangeBarrel && vetoEndcap;
}
protected boolean isValidEndcapIntercept(HelixSwimmer swimmer, double alpha, double uncertainty) {
// Must have m_ECAL_endcap_rmin <= r <= m_ECAL_endcap_rmax (within errors)
lcsim/src/org/lcsim/recon/pfa/identifier
diff -u -r1.3 -r1.4
--- TrackHelixPlusHitExtrapolator.java 23 Sep 2008 18:26:03 -0000 1.3
+++ TrackHelixPlusHitExtrapolator.java 9 Oct 2008 21:38:28 -0000 1.4
@@ -35,89 +35,307 @@
// Start by swimming as per parent:
super.performExtrapolation(tr);
- // Now scan over tracker hits and find the one with the outermost Z:
+ // Now scan over tracker hits and find the outermost one.
+ // Note that the details here depend on what kind of hit
+ // we're looking at.
List<TrackerHit> trackHits = tr.getTrackerHits();
if (trackHits.size() == 0) { throw new AssertionError("Track found with no track hits!"); }
- TrackerHit trackHitWithLargestModZ = null;
- Hep3Vector positionOfTrackHitWithLargestModZ = null;
- for (TrackerHit trackHit : trackHits) {
- Hep3Vector pos = new BasicHep3Vector(trackHit.getPosition());
- if (trackHitWithLargestModZ==null) {
- trackHitWithLargestModZ = trackHit;
- positionOfTrackHitWithLargestModZ = pos;
+ TrackerHit outermostHit = findOutermostHit(trackHits);
+
+ // Find the POCA to the hit with the old helix:
+ double alpha = Double.NaN;
+ Hep3Vector pointOfClosestApproachToTrackHit = null;
+ Hep3Vector offset = null;
+
+ if (outermostHit instanceof org.lcsim.event.base.BaseTrackerHitMC) {
+ // This cheated hit has exact 3D info
+ Hep3Vector positionOfOutermostHit = new BasicHep3Vector(outermostHit.getPosition());
+ alpha = m_swimmer.getTrackLengthToPoint(positionOfOutermostHit);
+ pointOfClosestApproachToTrackHit = m_swimmer.getPointAtLength(alpha);
+ // Correct with a 3D step from POCA-to-hit to the hit itself.
+ offset = VecOp.sub(positionOfOutermostHit, pointOfClosestApproachToTrackHit);
+ } else if (outermostHit instanceof org.lcsim.fit.helicaltrack.HelicalTrack2DHit) {
+ // This is a barrel hit with 2D hit info (and a weak constraint on z)
+ // Correct with an offset in r-phi but not in z
+ org.lcsim.fit.helicaltrack.HelicalTrack2DHit hit = (org.lcsim.fit.helicaltrack.HelicalTrack2DHit)(outermostHit);
+ double r = hit.r();
+ alpha = m_swimmer.getDistanceToRadius(r);
+ pointOfClosestApproachToTrackHit = m_swimmer.getPointAtLength(alpha);
+ // Correct in xy but not in z since no z information
+ offset = new BasicHep3Vector(hit.x() - pointOfClosestApproachToTrackHit.x(), hit.y() - pointOfClosestApproachToTrackHit.y(), 0.0);
+ } else if (outermostHit instanceof org.lcsim.fit.helicaltrack.HelicalTrackCross) {
+ // This is an endcap hit with hit info from axial+stereo strips.
+ // Uncertainty is ambiguous somehow -- unclear...
+ org.lcsim.fit.helicaltrack.HelicalTrackCross hit = (org.lcsim.fit.helicaltrack.HelicalTrackCross)(outermostHit);
+ double z = hit.z();
+ alpha = m_swimmer.getDistanceToZ(z);
+ pointOfClosestApproachToTrackHit = m_swimmer.getPointAtLength(alpha);
+ // Step from extrapolation point (x, y, z) to hit position (x', y', z) -- note that both have same z.
+ offset = new BasicHep3Vector(hit.x() - pointOfClosestApproachToTrackHit.x(), hit.y() - pointOfClosestApproachToTrackHit.y(), 0.0);
+ } else if (outermostHit instanceof org.lcsim.fit.helicaltrack.HelicalTrack3DHit) {
+ // This is a vertex detector hit with 3D hit info
+ org.lcsim.fit.helicaltrack.HelicalTrack3DHit hit = (org.lcsim.fit.helicaltrack.HelicalTrack3DHit)(outermostHit);
+ Hep3Vector positionOfOutermostHit = new BasicHep3Vector(hit.x(), hit.y(), hit.z());
+ alpha = m_swimmer.getTrackLengthToPoint(positionOfOutermostHit);
+ pointOfClosestApproachToTrackHit = m_swimmer.getPointAtLength(alpha);
+ // Correct with a 3D step from POCA-to-hit to the hit itself.
+ offset = VecOp.sub(positionOfOutermostHit, pointOfClosestApproachToTrackHit);
+ } else {
+ // Unknown!
+ Hep3Vector positionOfOutermostHit = new BasicHep3Vector(outermostHit.getPosition());
+ double r = Math.sqrt(positionOfOutermostHit.x()*positionOfOutermostHit.x() + positionOfOutermostHit.y()*positionOfOutermostHit.y());
+ double z = positionOfOutermostHit.z();
+ throw new AssertionError("ERROR: Unknown hit of type "+outermostHit.getClass().getName()+" at r="+r+", z="+z);
+ }
+
+ Hep3Vector momentumAtPOCA = m_swimmer.getMomentumAtLength(alpha);
+ Hep3Vector newPoint = VecOp.add(pointOfClosestApproachToTrackHit, offset);
+
+ // Make a new helix swimmer:
+ HelixSwimmer newHelix = new HelixSwimmer(m_fieldStrength[2]);
+ newHelix.setTrack(momentumAtPOCA, newPoint, tr.getCharge());
+ // Over-write old helix swimmer:
+ m_swimmer = newHelix;
+
+ // Try swimming to the barrel:
+ double alphaBarrel = swimToBarrel(m_swimmer);
+ boolean validBarrel = false;
+ // Try swimming to the endcap:
+ double alphaEndcap = swimToEndcap(m_swimmer);
+ boolean validEndcap = false;
+
+ // Get helix fit output
+ m_alphaIntercept = Double.NaN;
+ m_intercept = null;
+ if (isValidBarrelIntercept(m_swimmer, alphaBarrel, m_cutSeparation)) {
+ validBarrel = true;
+ }
+ if (isValidEndcapIntercept(m_swimmer, alphaEndcap, m_cutSeparation)) {
+ validEndcap = true;
+ }
+
+ // Check for special case in corner of barrel/endcap overlap region
+ if ( validEndcap && validBarrel ) {
+ // Both apparently valid... check again
+ boolean tightValidEndcap = isValidEndcapIntercept(m_swimmer, alphaEndcap, 0.0);
+ boolean tightValidBarrel = isValidBarrelIntercept(m_swimmer, alphaBarrel, 0.0);
+ if (tightValidEndcap && tightValidBarrel) {
+ // This can happen if the track has moderate pT -- it goes into the
+ // barrel, spirals out again, and eventually hits the endcap.
+ // If this is what happened then it should reach the barrel first.
+ if (alphaEndcap < alphaBarrel) {
+ Hep3Vector interceptEndcap = m_swimmer.getPointAtDistance(alphaEndcap);
+ Hep3Vector interceptBarrel = m_swimmer.getPointAtDistance(alphaBarrel);
+ double rEndcap = Math.sqrt(interceptEndcap.x()*interceptEndcap.x() + interceptEndcap.y()*interceptEndcap.y());
+ double rBarrel = Math.sqrt(interceptBarrel.x()*interceptBarrel.x() + interceptBarrel.y()*interceptBarrel.y());
+ double zEndcap = interceptEndcap.z();
+ double zBarrel = interceptBarrel.z();
+ throw new AssertionError("Track hits endcap THEN barrel -- this doesn't make sense!\nEndcap intercept at alpha="+alphaEndcap+" has r="+rEndcap+", z="+zEndcap+"\nBarrel intercept at alpha="+alphaBarrel+" has r="+rBarrel+", z="+zBarrel);
+ } else {
+ validEndcap = false;
+ }
+ } else if (!tightValidEndcap && !tightValidBarrel) {
+ throw new AssertionError("Invalid state");
} else {
- if (Math.abs(pos.z()) > Math.abs(positionOfTrackHitWithLargestModZ.z())) {
- trackHitWithLargestModZ = trackHit;
- positionOfTrackHitWithLargestModZ = pos;
+ // Only one valid solution -- OK
+ validEndcap = tightValidEndcap;
+ validBarrel = tightValidBarrel;
+ }
+ }
+
+ if (validEndcap) { m_alphaIntercept = alphaEndcap; }
+ if (validBarrel) { m_alphaIntercept = alphaBarrel; }
+
+ // Did we make a successful extrapolation?
+ if ( Double.isNaN(m_alphaIntercept)) {
+ // No -- extrapolation failed
+ if (m_debug) { System.out.println("DEBUG: "+this.getClass().getName()+" failed to extrapolate: alpha is NaN"); }
+ return null;
+ } else if ( !(validEndcap || validBarrel) ) {
+ // Invalid state
+ if (m_debug) { System.out.println("DEBUG: "+this.getClass().getName()+" failed to extrapolate: not a valid barrel or endcap point"); }
+ return null;
+ } else if ( validEndcap && validBarrel ) {
+ // Invalid state
+ if (m_debug) { System.out.println("DEBUG: "+this.getClass().getName()+" failed to extrapolate: valid barrel AND endcap point"); }
+ throw new AssertionError("DEBUG: "+this.getClass().getName()+" failed to extrapolate: valid barrel AND endcap point");
+ //return null;
+ } else {
+ // Extrapolation succeeded.
+ m_intercept = m_swimmer.getPointAtDistance(m_alphaIntercept);
+ m_barrelValid = validBarrel;
+ m_endcapValid = validEndcap;
+ if (m_debug) {
+ System.out.print("DEBUG: "+this.getClass().getName()+" extrapolated OK. validEndcap="+validEndcap+" and validBarrel="+validBarrel+" and m_alphaIntercept="+m_alphaIntercept);
+ if (m_intercept == null) {
+ System.out.print(" -- but intercept point is null!");
+ } else {
+ double r = Math.sqrt(m_intercept.x()*m_intercept.x() + m_intercept.y()*m_intercept.y());
+ System.out.print(" -- intercept point at r="+r+", z="+m_intercept.z());
}
+ System.out.println();
}
+ // Output
+ HelixExtrapolationResult output = new HelixExtrapolationResult(new TrackHelixPlusHitExtrapolator(this));
+ return output;
}
+ }
- if (trackHitWithLargestModZ == null) {
- throw new AssertionError("Unable to determine outermost hit!");
+ TrackerHit findOutermostHit(List<TrackerHit> trackerHits) {
+ boolean cheatHitFound = false;
+ boolean helicalHitFound = false;
+ for (TrackerHit hit : trackerHits) {
+ boolean thisHitIsCheatHit = (hit instanceof org.lcsim.event.base.BaseTrackerHitMC);
+ boolean thisHitIsHelicalHit = (hit instanceof org.lcsim.fit.helicaltrack.HelicalTrackCross || hit instanceof org.lcsim.fit.helicaltrack.HelicalTrack2DHit || hit instanceof org.lcsim.fit.helicaltrack.HelicalTrack3DHit);
+ if (thisHitIsCheatHit && thisHitIsHelicalHit) {
+ throw new AssertionError("Ambiguous hit of class "+hit.getClass().getName());
+ } else if (!thisHitIsCheatHit && !thisHitIsHelicalHit) {
+ throw new AssertionError("Unidentified hit of unknown class "+hit.getClass().getName());
+ }
+ if (thisHitIsCheatHit) {
+ cheatHitFound = true;
+ }
+ if (thisHitIsHelicalHit) {
+ helicalHitFound = true;
+ }
+ }
+ if (cheatHitFound && helicalHitFound) {
+ throw new AssertionError("Mixed list of hits!");
+ }
+ if (cheatHitFound) {
+ return findOutermostCheatHit(trackerHits);
+ } else if (helicalHitFound) {
+ return findOutermostHelicalHit(trackerHits);
} else {
- // Find the POCA to the hit with the old helix:
- double alpha = m_swimmer.getTrackLengthToPoint(positionOfTrackHitWithLargestModZ);
- Hep3Vector pointOfClosestApproachToTrackHit = m_swimmer.getPointAtLength(alpha);
- Hep3Vector momentumAtPOCA = m_swimmer.getMomentumAtLength(alpha);
-
- // Make a new helix swimmer:
- HelixSwimmer newHelix = new HelixSwimmer(m_fieldStrength[2]);
- newHelix.setTrack(momentumAtPOCA, positionOfTrackHitWithLargestModZ, tr.getCharge());
- // Over-write old helix swimmer:
- m_swimmer = newHelix;
-
- // Try swimming to the barrel:
- double alphaBarrel = swimToBarrel(m_swimmer);
- boolean validBarrel = false;
- // Try swimming to the endcap:
- double alphaEndcap = swimToEndcap(m_swimmer);
- boolean validEndcap = false;
-
- // Get helix fit output
- m_alphaIntercept = Double.NaN;
- m_intercept = null;
- if (isValidBarrelIntercept(m_swimmer, alphaBarrel, m_cutSeparation)) {
- m_alphaIntercept = alphaBarrel;
- validBarrel = true;
- } else if (isValidEndcapIntercept(m_swimmer, alphaEndcap, m_cutSeparation)) {
- m_alphaIntercept = alphaEndcap;
- validEndcap = true;
- }
-
- // Did we make a successful extrapolation?
- if ( Double.isNaN(m_alphaIntercept)) {
- // No -- extrapolation failed
- if (m_debug) { System.out.println("DEBUG: "+this.getClass().getName()+" failed to extrapolate: alpha is NaN"); }
- return null;
- } else if ( !(validEndcap || validBarrel) ) {
- // Invalid state
- if (m_debug) { System.out.println("DEBUG: "+this.getClass().getName()+" failed to extrapolate: not a valid barrel or endcap point"); }
- return null;
- } else if ( validEndcap && validBarrel ) {
- // Invalid state
- if (m_debug) { System.out.println("DEBUG: "+this.getClass().getName()+" failed to extrapolate: valid barrel AND endcap point"); }
- throw new AssertionError("DEBUG: "+this.getClass().getName()+" failed to extrapolate: valid barrel AND endcap point");
- //return null;
+ throw new AssertionError("Unclassified list of hits!");
+ }
+ }
+
+ TrackerHit findOutermostCheatHit(List<TrackerHit> trackerHits) {
+ // Find hit with outermost Z
+ TrackerHit outermostHit = null;
+ Hep3Vector positionOfOutermostHit = null;
+ for (TrackerHit trackHit : trackerHits) {
+ Hep3Vector pos = new BasicHep3Vector(trackHit.getPosition());
+ if (outermostHit==null) {
+ outermostHit = trackHit;
+ positionOfOutermostHit = pos;
} else {
- // Extrapolation succeeded.
- m_intercept = m_swimmer.getPointAtDistance(m_alphaIntercept);
- m_barrelValid = validBarrel;
- m_endcapValid = validEndcap;
- if (m_debug) {
- System.out.print("DEBUG: "+this.getClass().getName()+" extrapolated OK. validEndcap="+validEndcap+" and validBarrel="+validBarrel+" and m_alphaIntercept="+m_alphaIntercept);
- if (m_intercept == null) {
- System.out.print(" -- but intercept point is null!");
+ if (Math.abs(pos.z()) > Math.abs(positionOfOutermostHit.z())) {
+ outermostHit = trackHit;
+ positionOfOutermostHit = pos;
+ }
+ }
+ }
+ return outermostHit;
+ }
+
+ TrackerHit findOutermostHelicalHit(List<TrackerHit> trackerHits) {
+ // This is a little tricky. The rules are:
+ // 1) Any outer tracker layer > any vertex detector layer
+ // 2) For two vertex detector hits, the one with the larger |z| wins.
+ // 3) For any two outer tracker barrel layers, the one with the larger r wins.
+ // 4) For any two outer tracker endcap layers, the one with the larger |z| wins.
+ // 5) For a tracker barrel & endcap layer...
+ // 5a) If barrel |zmin| > endcap |z|, the barrel wins
+ // 5b) If barrel |zmax| < endcap |z|, the endcap wins
+ // 5c) If there is ambiguity, the barrel wins (a little arbitrary)
+ TrackerHit outermostHit = null;
+ for (TrackerHit hit : trackerHits) {
+ if (outermostHit == null) {
+ outermostHit = hit;
+ } else {
+ boolean outermostHitIsVertexHit = (outermostHit instanceof org.lcsim.fit.helicaltrack.HelicalTrack3DHit);
+ boolean outermostHitIsBarrelHit = (outermostHit instanceof org.lcsim.fit.helicaltrack.HelicalTrack2DHit);
+ boolean outermostHitIsEndcapHit = (outermostHit instanceof org.lcsim.fit.helicaltrack.HelicalTrackCross);
+ if (!(outermostHitIsVertexHit || outermostHitIsBarrelHit || outermostHitIsEndcapHit)) { throw new AssertionError("Unidentified hit"); }
+ if (outermostHitIsVertexHit && outermostHitIsBarrelHit) { throw new AssertionError("Ambiguous hit"); }
+ if (outermostHitIsVertexHit && outermostHitIsEndcapHit) { throw new AssertionError("Ambiguous hit"); }
+ if (outermostHitIsBarrelHit && outermostHitIsEndcapHit) { throw new AssertionError("Ambiguous hit"); }
+ boolean currentHitIsVertexHit = (hit instanceof org.lcsim.fit.helicaltrack.HelicalTrack3DHit);
+ boolean currentHitIsBarrelHit = (hit instanceof org.lcsim.fit.helicaltrack.HelicalTrack2DHit);
+ boolean currentHitIsEndcapHit = (hit instanceof org.lcsim.fit.helicaltrack.HelicalTrackCross);
+ if (!(currentHitIsVertexHit || currentHitIsBarrelHit || currentHitIsEndcapHit)) { throw new AssertionError("Unidentified hit"); }
+ if (currentHitIsVertexHit && currentHitIsBarrelHit) { throw new AssertionError("Ambiguous hit"); }
+ if (currentHitIsVertexHit && currentHitIsEndcapHit) { throw new AssertionError("Ambiguous hit"); }
+ if (currentHitIsBarrelHit && currentHitIsEndcapHit) { throw new AssertionError("Ambiguous hit"); }
+
+ if (currentHitIsVertexHit) {
+ if (outermostHitIsVertexHit) {
+ // 2) For two vertex detector hits, the one with the larger |z| wins.
+ double currentHit_z = Math.abs(((org.lcsim.fit.helicaltrack.HelicalTrack3DHit)(hit)).z());
+ double outermostHit_z = Math.abs(((org.lcsim.fit.helicaltrack.HelicalTrack3DHit)(outermostHit)).z());
+ if (currentHit_z > outermostHit_z) {
+ outermostHit = hit;
+ }
+ continue;
+ } else {
+ // 1) Any outer tracker layer > any vertex detector layer
+ continue;
+ }
+ } else {
+ if (outermostHitIsVertexHit) {
+ // 1) Any outer tracker layer > any vertex detector layer
+ outermostHit = hit;
+ continue;
} else {
- double r = Math.sqrt(m_intercept.x()*m_intercept.x() + m_intercept.y()*m_intercept.y());
- System.out.print(" -- intercept point at r="+r+", z="+m_intercept.z());
+ if (outermostHitIsBarrelHit && currentHitIsBarrelHit) {
+ // 3) For any two outer tracker barrel layers, the one with the larger r wins.
+ double currentHit_r = ((org.lcsim.fit.helicaltrack.HelicalTrack2DHit)(hit)).r();
+ double outermostHit_r = ((org.lcsim.fit.helicaltrack.HelicalTrack2DHit)(outermostHit)).r();
+ if (currentHit_r > outermostHit_r) {
+ outermostHit = hit;
+ }
+ continue;
+ } else if (outermostHitIsEndcapHit && currentHitIsEndcapHit) {
+ // 4) For any two outer tracker endcap layers, the one with the larger |z| wins.
+ double currentHit_z = Math.abs(((org.lcsim.fit.helicaltrack.HelicalTrackCross)(hit)).z());
+ double outermostHit_z = Math.abs(((org.lcsim.fit.helicaltrack.HelicalTrackCross)(outermostHit)).z());
+ if (currentHit_z > outermostHit_z) {
+ outermostHit = hit;
+ }
+ continue;
+ } else if (outermostHitIsBarrelHit && currentHitIsEndcapHit) {
+ // One barrel and one endcap layer
+ double barrel_zmin = Math.abs(((org.lcsim.fit.helicaltrack.HelicalTrack2DHit)(outermostHit)).zmin());
+ double barrel_zmax = Math.abs(((org.lcsim.fit.helicaltrack.HelicalTrack2DHit)(outermostHit)).zmax());
+ double endcap_z = Math.abs(((org.lcsim.fit.helicaltrack.HelicalTrackCross)(hit)).z());
+ if (barrel_zmin > endcap_z) {
+ // 5a) If barrel |zmin| > endcap |z|, the barrel wins
+ continue;
+ } else if (barrel_zmax < endcap_z) {
+ // 5b) If barrel |zmax| < endcap |z|, the endcap wins
+ outermostHit = hit;
+ continue;
+ } else {
+ // 5c) If there is ambiguity, the barrel wins (a little arbitrary)
+ continue;
+ }
+ } else if (outermostHitIsEndcapHit&¤tHitIsBarrelHit) {
+ // One barrel and one endcap layer
+ double barrel_zmin = Math.abs(((org.lcsim.fit.helicaltrack.HelicalTrack2DHit)(hit)).zmin());
+ double barrel_zmax = Math.abs(((org.lcsim.fit.helicaltrack.HelicalTrack2DHit)(hit)).zmax());
+ double endcap_z = Math.abs(((org.lcsim.fit.helicaltrack.HelicalTrackCross)(outermostHit)).z());
+ if (barrel_zmin > endcap_z) {
+ // 5a) If barrel |zmin| > endcap |z|, the barrel wins
+ outermostHit = hit;
+ continue;
+ } else if (barrel_zmax < endcap_z) {
+ // 5b) If barrel |zmax| < endcap |z|, the endcap wins
+ continue;
+ } else {
+ // 5c) If there is ambiguity, the barrel wins (a little arbitrary)
+ outermostHit = hit;
+ continue;
+ }
+ }
}
- System.out.println();
}
- // Output
- HelixExtrapolationResult output = new HelixExtrapolationResult(new TrackHelixPlusHitExtrapolator(this));
- return output;
+ // Shouldn't reach here
+ throw new AssertionError("Failed to classify! outermostHit is "+outermostHit.getClass().getName()+" and hit is "+hit.getClass().getName());
}
}
+
+ return outermostHit;
}
}