Author: [log in to unmask]
Date: Wed Aug 10 12:31:35 2016
New Revision: 4458
Log:
re-calculates the invariant mass by combining ecal and svt information
Added:
java/trunk/analysis/src/main/java/org/hps/analysis/ecal/MassCalculator.java
Added: java/trunk/analysis/src/main/java/org/hps/analysis/ecal/MassCalculator.java
=============================================================================
--- java/trunk/analysis/src/main/java/org/hps/analysis/ecal/MassCalculator.java (added)
+++ java/trunk/analysis/src/main/java/org/hps/analysis/ecal/MassCalculator.java Wed Aug 10 12:31:35 2016
@@ -0,0 +1,234 @@
+package org.hps.analysis.ecal;
+
+import hep.physics.vec.Hep3Vector;
+
+import org.hps.recon.ecal.cluster.ClusterUtilities;
+import org.hps.recon.tracking.TrackUtils;
+import org.lcsim.event.Cluster;
+import org.lcsim.event.ReconstructedParticle;
+import org.lcsim.event.Track;
+import org.lcsim.event.TrackState;
+
+/**
+ * This code contains all of the calculations, as found in the 2015 data, for combining the Ecal energy and SVT
+ * momentum.
+ *
+ * @author Holly Szumila-Vance <[log in to unmask]>
+ **/
+public class MassCalculator {
+
+ // TODO: BEAMGAPTOP and BEAMGAPBOT need to come from detector definitions:
+ static final double BEAMGAPTOP = 22.7;// mm
+ static final double BEAMGAPBOT = -22.9;// mm
+ static final double BEAMGAPTOPC = BEAMGAPTOP + 13.0;// mm
+ static final double BEAMGAPBOTC = BEAMGAPBOT - 13.0;// mm
+ static final double par[] = {35, 0.02871, -0.3046, -9.997, 0.1401, -0.00077, 55.09, -0.4651};
+
+ /**
+ * Calculates the y position of a cluster in the Ecal relative to the inner beam gap edge of the Ecal.
+ *
+ * @param ix
+ * @param y0
+ * @return |yrel|
+ */
+ static double getY(int ix, double y0) {
+ if (ix > -11 && ix < -1) {
+ // if (x0<-113 || x0>49){
+ if (y0 > 0) {
+ if (y0 < 55) {
+ return Math.abs(y0 - BEAMGAPTOPC);
+ } else {
+ return Math.abs(y0 - BEAMGAPTOP);
+ }
+ } else {
+ if (y0 > -55) {
+ return Math.abs(y0 - BEAMGAPBOTC);
+ } else {
+ return Math.abs(y0 - BEAMGAPBOT);
+ }
+ }
+ } else {
+ if (y0 > 0) {
+ return Math.abs(y0 - BEAMGAPTOP);
+ } else {
+ return Math.abs(y0 - BEAMGAPBOT);
+ }
+ }
+ }
+
+ /**
+ * Calculates the parameter, B, as a function of position for understanding the resolution of the energy in the
+ * Ecal.
+ *
+ * @param ypos
+ * @return B
+ */
+ static double calcBpar(double ypos) {
+ if (ypos > 3) {
+ int ii = (ypos < par[0]) ? 2 : 5;
+ return par[1] - par[ii] * Math.exp(-(ypos - par[ii + 1]) * par[ii + 2]);
+ } else {
+ return 0.2;
+ }
+ }
+
+ /**
+ * Calculates the energy resolution accounting for position relative to the edge in the Ecal/
+ *
+ * @param energy
+ * @param ix
+ * @param ypos
+ * @return sigma E
+ */
+ static double sigE(double energy, int ix, double ypos) {
+
+ // return energy*(sqrt(pow(0.0165,2)/pow(energy,2)+pow(calcBpar(getY(ix,ypos)),2)/energy+pow(0.0181,2)));
+ return energy
+ * (Math.sqrt(Math.pow(0.0162, 2) / Math.pow(energy, 2) + Math.pow(calcBpar(getY(ix, ypos)), 2) / energy
+ + Math.pow(0.025, 2)));
+ }
+
+ /**
+ * Calculates the momentum resolution. Fixed for 2015 data.
+ *
+ * @param mom
+ * @return sigma P
+ */
+ static double sigP(double mom) {
+
+ return 0.067 * mom;
+
+ }
+
+ /**
+ * Calculates the sigma of the E/P distribution in order to check if the cluster energy is in the peak or tail of
+ * the distribution before combining.
+ *
+ * @param energy
+ * @param mom
+ * @param ix
+ * @param ypos
+ * @return E/P sigma
+ */
+ static double sigmaFrac(double energy, double mom, int ix, double ypos) {
+
+ return Math.sqrt(Math.pow(sigE(energy, ix, ypos) / energy, 2) + Math.pow(sigP(mom) / mom, 2));
+
+ }
+
+ /**
+ * Calculates the cosine of the opening angle of the vertex
+ *
+ * @param v0
+ * @return cosine of the opening angle
+ */
+ static double cosTheta(ReconstructedParticle v0) {
+ double px1 = v0.getStartVertex().getParameters().get("p1X");
+ double py1 = v0.getStartVertex().getParameters().get("p1Y");
+ double pz1 = v0.getStartVertex().getParameters().get("p1Z");
+ double px2 = v0.getStartVertex().getParameters().get("p2X");
+ double py2 = v0.getStartVertex().getParameters().get("p2Y");
+ double pz2 = v0.getStartVertex().getParameters().get("p2Z");
+
+ return (px1 * px2 + py1 * py2 + pz1 * pz2)
+ / (Math.sqrt(Math.pow(px1, 2) + Math.pow(py1, 2) + Math.pow(pz1, 2)) * Math.sqrt(Math.pow(px2, 2)
+ + Math.pow(py2, 2) + Math.pow(pz2, 2)));
+ }
+
+ /**
+ * This takes in a cluster, track, refit momentum and outputs the combined, weighted momentum if it satisfies
+ * conditions.
+ *
+ * @return combined momentum (GeV)
+ */
+ public static double combinedMomentum(Cluster cluster, Track track, double momentum) {
+ double energy = cluster.getEnergy();
+ TrackState trackState = track.getTrackStates().get(0);
+ Hep3Vector posAtEcal = TrackUtils.getTrackPositionAtEcal(trackState);
+
+ int ix = ClusterUtilities.findSeedHit(cluster).getIdentifierFieldValue("ix");
+ double yraw = posAtEcal.y();
+ double ypos = getY(ix, yraw);
+ double sigmaE = sigE(energy, ix, ypos);
+ double sigmaP = sigP(momentum);
+
+ double ff = (1 - energy / momentum) / sigmaFrac(energy, momentum, ix, ypos);
+
+ if (ff > -2 && ff < 1.8 && ypos > 8 && (energy / momentum) > 0.82 && (energy / momentum) < 1.2) {
+
+ return (energy / (Math.pow(sigmaE, 2)) + momentum / Math.pow(sigmaP, 2))
+ / (1. / (Math.pow(sigmaE, 2)) + 1. / Math.pow(sigmaP, 2));
+
+ } else {
+ return momentum;
+ }
+ }
+
+ /**
+ * This takes in the clusters of two particles and the associated vertex and calculates the invariant mass. The
+ * cluster order must match the track order as listed in the vertex.
+ *
+ * @return weighted invariant mass (GeV)
+ */
+ public static double combinedMass(Cluster clusterA, Cluster clusterB, ReconstructedParticle v0) {
+ double momentumA = Math.sqrt(Math.pow(v0.getStartVertex().getParameters().get("p1X"), 2)
+ + Math.pow(v0.getStartVertex().getParameters().get("p1Y"), 2) + Math.pow(v0.getStartVertex().getParameters().get("p1Z"), 2));
+ double momentumB = Math.sqrt(Math.pow(v0.getStartVertex().getParameters().get("p2X"), 2)
+ + Math.pow(v0.getStartVertex().getParameters().get("p2Y"), 2) + Math.pow(v0.getStartVertex().getParameters().get("p2Z"), 2));
+
+ double energyA = combinedMomentum(clusterA, v0.getParticles().get(0).getTracks().get(0), momentumA);
+ double energyB = combinedMomentum(clusterB, v0.getParticles().get(1).getTracks().get(0), momentumB);
+
+ double cosT = cosTheta(v0);
+ double mass = Math.sqrt(2 * energyA * energyB * (1 - cosT));
+
+ return mass;
+
+ }
+
+ /**
+ * This takes in the clusters of two particles and the associated vertex and calculates the invariant mass. The
+ * cluster order must match the track order as listed in the vertex.
+ *
+ * Use if electron has no cluster
+ *
+ * @return weighted invariant mass (GeV)
+ */
+ public static double combinedMass(Track trackA, Cluster clusterB, ReconstructedParticle v0) {
+ double momentumA = Math.sqrt(Math.pow(v0.getStartVertex().getParameters().get("p1X"), 2)
+ + Math.pow(v0.getStartVertex().getParameters().get("p1Y"), 2) + Math.pow(v0.getStartVertex().getParameters().get("p1Z"), 2));
+ double momentumB = Math.sqrt(Math.pow(v0.getStartVertex().getParameters().get("p2X"), 2)
+ + Math.pow(v0.getStartVertex().getParameters().get("p2Y"), 2) + Math.pow(v0.getStartVertex().getParameters().get("p2Z"), 2));
+ double energyA = momentumA;
+ double energyB = combinedMomentum(clusterB, v0.getParticles().get(1).getTracks().get(0), momentumB);
+
+ double cosT = cosTheta(v0);
+ double mass = Math.sqrt(2 * energyA * energyB * (1 - cosT));
+
+ return mass;
+
+ }
+ /**
+ * This takes in the clusters of two particles and the associated vertex and calculates the invariant mass. The
+ * cluster order must match the track order as listed in the vertex.
+ *
+ * Use if positron has no cluster
+ *
+ * @return weighted invariant mass (GeV)
+ */
+ public static double combinedMass(Cluster clusterA, Track trackB, ReconstructedParticle v0) {
+ double momentumA = Math.sqrt(Math.pow(v0.getStartVertex().getParameters().get("p1X"), 2)
+ + Math.pow(v0.getStartVertex().getParameters().get("p1Y"), 2) + Math.pow(v0.getStartVertex().getParameters().get("p1Z"), 2));
+ double momentumB = Math.sqrt(Math.pow(v0.getStartVertex().getParameters().get("p2X"), 2)
+ + Math.pow(v0.getStartVertex().getParameters().get("p2Y"), 2) + Math.pow(v0.getStartVertex().getParameters().get("p2Z"), 2));
+ double energyA = combinedMomentum(clusterA, v0.getParticles().get(0).getTracks().get(0), momentumA);
+ double energyB = momentumB;
+
+ double cosT = cosTheta(v0);
+ double mass = Math.sqrt(2 * energyA * energyB * (1 - cosT));
+
+ return mass;
+
+ }
+
+}
|