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..7e90b78e37 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,17 @@ public class HpsReconParticleDriver extends ReconParticleDriver { private double[] beamPositionToUse = new double[3]; private boolean requireClustersForV0 = true; + /** + * 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 +294,17 @@ public void setStoreCovTrkMomList(boolean b) { public void setRequireClustersForV0(boolean b) { this.requireClustersForV0 = 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 +567,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(); 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..843c30735c 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 (the reference + // point of the input track states, or the previous vertex for a refit), so add + // it back before comparing with the (absolute) target position. + 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..a5ec50fa79 --- /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,238 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 + 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 + + + + + + diff --git a/tracking/src/main/java/org/hps/recon/tracking/kalman/KalmanPatRecDriver.java b/tracking/src/main/java/org/hps/recon/tracking/kalman/KalmanPatRecDriver.java index 4cc6836003..63c889c306 100644 --- a/tracking/src/main/java/org/hps/recon/tracking/kalman/KalmanPatRecDriver.java +++ b/tracking/src/main/java/org/hps/recon/tracking/kalman/KalmanPatRecDriver.java @@ -281,27 +281,23 @@ public void detectorChanged(Detector det) { // Setup optional usage of beam positions from database. final DatabaseConditionsManager mgr = DatabaseConditionsManager.getInstance(); double[] beamPositionArr = {beamPositionX, beamPositionY, beamPositionZ}; - if (mgr.hasConditionsRecord("beam_positions")){ - BeamPositionCollection beamPositions = + // Only read the database when asked to: previously the DB values were copied + // into beamPositionArr (used for the track state at the target) even with + // useBeamPositionConditions false. + if (useBeamPositionConditions && mgr.hasConditionsRecord("beam_positions")){ + BeamPositionCollection beamPositions = mgr.getCachedConditions(BeamPositionCollection.class, "beam_positions").getCachedData(); - BeamPosition beamPositionCond = beamPositions.get(0); + BeamPosition beamPositionCond = beamPositions.get(0); beamPositionArr[0] = beamPositionCond.getPositionX(); beamPositionArr[1] = beamPositionCond.getPositionY(); - beamPositionArr[2] = beamPositionCond.getPositionZ(); - System.out.println("beamPosition[0]: " + beamPositionArr[0]); - System.out.println("beamPosition[1]: " + beamPositionArr[1]); - System.out.println("beamPosition[2]: " + beamPositionArr[2]); - if (useBeamPositionConditions) { - logger.config("Using Kalman beam position from the conditions database"); - if (!useFixedVertexZPosition) kPar.setBeamSpotY(beamPositionCond.getPositionZ()); - else logger.config("Using fixed Kalman beam Z position: " + kPar.beamSpot[1]); - kPar.setBeamSpotX(beamPositionCond.getPositionX()); // Includes a transformation to Kalman coordinates - kPar.setBeamSpotZ(-beamPositionCond.getPositionY()); - } - else { - logger.config("Using Kalman beam position from the steering file or default"); - } - + if (!useFixedVertexZPosition) beamPositionArr[2] = beamPositionCond.getPositionZ(); + logger.config("Using Kalman beam position from the conditions database"); + if (!useFixedVertexZPosition) kPar.setBeamSpotY(beamPositionCond.getPositionZ()); + else logger.config("Using fixed Kalman beam Z position: " + kPar.beamSpot[1]); + kPar.setBeamSpotX(beamPositionCond.getPositionX()); // Includes a transformation to Kalman coordinates + kPar.setBeamSpotZ(-beamPositionCond.getPositionY()); + } else { + logger.config("Using Kalman beam position from the steering file or default"); } logger.config("Using Kalman beam position [ Z, X, Y ]: " + String.format("[ %f, %f, %f ]", kPar.beamSpot[0], -kPar.beamSpot[2], kPar.beamSpot[1]) + " in HPS coordinates.");