diff --git a/recon/src/main/java/org/hps/recon/particle/HpsReconParticleDriver.java b/recon/src/main/java/org/hps/recon/particle/HpsReconParticleDriver.java index b10c5170f7..3ea4b69df4 100644 --- a/recon/src/main/java/org/hps/recon/particle/HpsReconParticleDriver.java +++ b/recon/src/main/java/org/hps/recon/particle/HpsReconParticleDriver.java @@ -145,6 +145,24 @@ public class HpsReconParticleDriver extends ReconParticleDriver { private double[] beamPositionToUse = new double[3]; private boolean requireClustersForV0 = true; + /** + * Whether to refit TARGET_CONSTRAINED vertices after shifting the tracks + * to the first-pass vertex, as is done for UNCONSTRAINED and + * BS_CONSTRAINED. Off by default (original behaviour). + */ + private boolean refitTargetConstrained = false; + + /** + * Whether the first-pass vertex fit uses the reference point of the + * input track states. Kalman perigee states are defined about the beam + * spot (e.g. z = -1.1 mm), not the origin; without this the fitter + * assumes the origin, which biases target-constrained fits (the vertex + * is pulled to twice the target z and the opening angle closes by ~2%). + * On by default; set false to reproduce the original (pass5 and earlier) + * behaviour. + */ + private boolean useTrackReferencePoint = true; + /** * Represents a type of constraint for vertex fitting. * @@ -283,6 +301,27 @@ public void setStoreCovTrkMomList(boolean b) { public void setRequireClustersForV0(boolean b) { this.requireClustersForV0 = b; } + + /** + * Set whether TARGET_CONSTRAINED vertices are refit with the tracks + * shifted to the first-pass vertex. + * + * @param b True to refit target-constrained vertices + */ + public void setRefitTargetConstrained(boolean b) { + this.refitTargetConstrained = b; + } + + /** + * Set whether the first-pass vertex fit is done about the reference + * point of the input track states instead of the origin (default true). + * Set false only to reproduce the original behaviour. + * + * @param b True to use the track state reference point + */ + public void setUseTrackReferencePoint(boolean b) { + this.useTrackReferencePoint = b; + } public void setUnconstrainedMollerCandidatesColName(String s) { @@ -545,6 +584,22 @@ private BilliorVertex fitVertex(Constraint constraint, ReconstructedParticle ele break; } + // The Billior tracks carry the parameters of the first track state, + // which are defined about that state's reference point (tracking + // frame). Fit about the same point so that the vertex position and + // the beam/target constraints are computed in absolute coordinates. + if (useTrackReferencePoint) { + double[] eleRef = electron.getTracks().get(0).getTrackStates().get(0).getReferencePoint(); + double[] posRef = positron.getTracks().get(0).getTrackStates().get(0).getReferencePoint(); + if (Math.abs(eleRef[0] - posRef[0]) > 1e-6 || Math.abs(eleRef[1] - posRef[1]) > 1e-6 + || Math.abs(eleRef[2] - posRef[2]) > 1e-6) { + LOGGER.warning(String.format("Electron and positron track reference points differ: " + + "(%f, %f, %f) vs (%f, %f, %f); using the electron's.", + eleRef[0], eleRef[1], eleRef[2], posRef[0], posRef[1], posRef[2])); + } + vtxFitter.setReferencePosition(eleRef); + } + // Add the electron and positron tracks to a track list for // the vertex fitter. List billiorTracks = new ArrayList(); @@ -589,7 +644,10 @@ private BilliorVertex fitVertex(Constraint constraint, ReconstructedParticle ele // ... this is required because the vertex fit assumes trajectories // change linearly about the reference point (which we initially guess to be // (0,0,0) while for long-lived decays there is significant curvature - if (constraint == Constraint.BS_CONSTRAINED || constraint == Constraint.UNCONSTRAINED) { + // Optionally do the same for TARGET_CONSTRAINED: the first pass is + // linearized about (0,0,0), the refit about the target point itself. + if (constraint == Constraint.BS_CONSTRAINED || constraint == Constraint.UNCONSTRAINED + || (constraint == Constraint.TARGET_CONSTRAINED && refitTargetConstrained)) { List recoList = new ArrayList(); recoList.add(electron); recoList.add(positron); diff --git a/recon/src/main/java/org/hps/recon/particle/ReconParticleDriver.java b/recon/src/main/java/org/hps/recon/particle/ReconParticleDriver.java index a6a798c89d..b6341bab55 100644 --- a/recon/src/main/java/org/hps/recon/particle/ReconParticleDriver.java +++ b/recon/src/main/java/org/hps/recon/particle/ReconParticleDriver.java @@ -285,6 +285,16 @@ public void setBeamSigmaY(double sigmaY) { beamSize[2] = sigmaY; // The beamsize array is in the tracking frame HPS Y => TRACK Z } + /** + * Sets the beam size sigma in the z-direction. + * + * @param sigmaZ - The standard deviation of the beam width in the + * z-direction (beam/target longitudinal spread). + */ + public void setBeamSigmaZ(double sigmaZ) { + beamSize[0] = sigmaZ; // The beamsize array is in the tracking frame HPS Z => TRACK X + } + /** * Sets the beam position in the z-direction in mm. * diff --git a/recon/src/main/java/org/hps/recon/vertexing/BilliorVertexer.java b/recon/src/main/java/org/hps/recon/vertexing/BilliorVertexer.java index ee649f990c..211bbb6714 100644 --- a/recon/src/main/java/org/hps/recon/vertexing/BilliorVertexer.java +++ b/recon/src/main/java/org/hps/recon/vertexing/BilliorVertexer.java @@ -453,9 +453,12 @@ private BasicMatrix makeRk(double Vx, double Vy, double Vz, double pxtot, double rk.setElement(1, 0, _beamPosition[1] - ((Vy + _referencePosition[1]) - pytot / pxtot * (Vx - _beamPosition[0] + _referencePosition[0]))); rk.setElement(2, 0, _beamPosition[2] - ((Vz + _referencePosition[2]) - pztot / pxtot * (Vx - _beamPosition[0] + _referencePosition[0]))); } else { - rk.setElement(0, 0, _beamPosition[0] - Vx); - rk.setElement(1, 0, _beamPosition[1] - Vy); - rk.setElement(2, 0, _beamPosition[2] - Vz); + // The vertex position is relative to the reference position, so add it back + // before comparing with the (absolute) target position. The reference is the + // origin unless the tracks were shifted for a refit (see HpsReconParticleDriver). + rk.setElement(0, 0, _beamPosition[0] - (Vx + _referencePosition[0])); + rk.setElement(1, 0, _beamPosition[1] - (Vy + _referencePosition[1])); + rk.setElement(2, 0, _beamPosition[2] - (Vz + _referencePosition[2])); } if (_debug) System.out.println("makeRk::rk = (" + rk.e(0, 0) + ", " + rk.e(1, 0) + ", " + rk.e(2, 0) + ")"); diff --git a/steering-files/src/main/resources/org/hps/steering/recon/PhysicsRun2021MCRecon_KF_WithSpacing_pass5_physics_HitSmear_HitKill_14272_fixedBeamPos.lcsim b/steering-files/src/main/resources/org/hps/steering/recon/PhysicsRun2021MCRecon_KF_WithSpacing_pass5_physics_HitSmear_HitKill_14272_fixedBeamPos.lcsim new file mode 100644 index 0000000000..9102e2702d --- /dev/null +++ b/steering-files/src/main/resources/org/hps/steering/recon/PhysicsRun2021MCRecon_KF_WithSpacing_pass5_physics_HitSmear_HitKill_14272_fixedBeamPos.lcsim @@ -0,0 +1,243 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 14 + false + + + false + + + pass5v9run14272_L1b_axial_hole.txt pass5v9run14272_L1b_stereo_hole.txt pass5v9run14272_L1t_axial_hole.txt pass5v9run14272_L1t_stereo_hole.txt pass5v9run14272_L2b_axial_hole.txt pass5v9run14272_L2b_stereo_hole.txt pass5v9run14272_L2t_axial_hole.txt pass5v9run14272_L2t_stereo_hole.txt + false + + + timeSmearing-2nsL4L7-4nsL1L3.txt + false + + + false + 0.8 + 0.8 + + + posSmearing_pass5_v9.txt + false + + + 1000 + + + HodoscopeReadoutHits + CONFIG + true + + + HodoscopeReadoutHits + 8 + CONFIG + true + + + + + + + 13.3 + + + WARNING + EcalClusters + + + EcalClusters + EcalClustersCorr + + + + SVTRawTrackerHits + + + .5 + 1 + Pileup + Migrad + true + 165 + true + true + false + true + false + false + true + false + + + 24.0 + 3.0 + false + 400 + 4.0 + 1.0 + 3.0 + 3.0 + true + true + false + + + true + true + 2 + 1 + 8.881915381218574 + 39.249197341740356 + 8.37847994612359 + 11.546843987796496 + 9 + 9 + 8 + 8 + 3 + 2 + 40.0 + 5.0 + 12.320066328390354 + 9.206482863412027 + 5.862027198856136 + 5.508828061070076 + 5 + false + 400 + 0.3473319986601534 + false + 0.0 + 0.0 + 0.055 + 0.045 + true + -1.1 + 7.197594353612735 + false + + + KalmanFullTracks + true + false + + + EcalClustersCorr + KalmanFullTracks + KalmanFullTracks + TrackClusterMatcherMinDistance + UnconstrainedV0Candidates_KF + UnconstrainedV0Vertices_KF + BeamspotConstrainedV0Candidates_KF + BeamspotConstrainedV0Vertices_KF + TargetConstrainedV0Candidates_KF + TargetConstrainedV0Vertices_KF + FinalStateParticles_KF + OtherElectrons_KF + true + false + false + + true + 0.0 + 0.0 + 0.055 + 0.045 + -1.1 + 7.0 + 7.0 + 0.0 + 40.0 + 40 + 40 + false + true + true + false + true + true + UnconstrainedMollerCandidates_KF + UnconstrainedMollerVertices_KF + BeamspotConstrainedMollerCandidates_KF + BeamspotConstrainedMollerVertices_KF + TargetConstrainedMollerCandidates_KF + TargetConstrainedMollerVertices_KF + + + ${outputFile}_hit_eff.root + + + ${outputFile}.slcio + + + + + +