lcsim-contrib/src/main/java/org/lcsim/contrib/Partridge/sidloi
diff -N LOIEffFake.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ LOIEffFake.java 8 Feb 2010 22:26:49 -0000 1.1
@@ -0,0 +1,444 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package org.lcsim.contrib.Partridge.sidloi;
+
+import org.lcsim.contrib.Partridge.TrackingTest.*;
+import hep.aida.IHistogram1D;
+import hep.aida.IHistogramFactory;
+import hep.physics.jet.EventShape;
+import hep.physics.vec.BasicHep3Vector;
+import hep.physics.vec.Hep3Vector;
+
+import hep.physics.vec.VecOp;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.lcsim.contrib.Partridge.TrackingTest.FindableTrack.Ignore;
+import org.lcsim.event.EventHeader;
+import org.lcsim.event.LCRelation;
+import org.lcsim.event.MCParticle;
+import org.lcsim.event.RelationalTable;
+import org.lcsim.event.Track;
+import org.lcsim.event.base.BaseRelationalTable;
+import org.lcsim.fit.helicaltrack.HelicalTrackFit;
+import org.lcsim.fit.helicaltrack.HelixParamCalculator;
+import org.lcsim.recon.tracking.seedtracker.SeedStrategy;
+import org.lcsim.recon.tracking.seedtracker.StrategyXMLUtils;
+import org.lcsim.util.Driver;
+import org.lcsim.util.aida.AIDA;
+
+/**
+ *
+ * @author partridge
+ */
+public class LOIEffFake extends Driver {
+
+ private AIDA aida = AIDA.defaultInstance();
+ private EventShape es = new EventShape();
+ private IHistogramFactory hf;
+ private IHistogram1D pTeff1;
+ private IHistogram1D pTeff2;
+ private IHistogram1D thetaeff;
+ private IHistogram1D ctheff;
+ private IHistogram1D ctheff1;
+ private IHistogram1D ctheff2;
+ private IHistogram1D d0eff1;
+ private IHistogram1D d0eff2;
+ private IHistogram1D z0eff1;
+ private IHistogram1D z0eff2;
+ private IHistogram1D thrusteff;
+ private IHistogram1D fakes;
+ private IHistogram1D nfakes;
+ int ntrktot = 0;
+ int nevt = 0;
+
+ public LOIEffFake() {
+
+ // Define the efficiency histograms
+ hf = aida.histogramFactory();
+ pTeff1 = hf.createHistogram1D("Efficiency vs pT", "", 100, 0., 5., "type=efficiency");
+ pTeff2 = hf.createHistogram1D("Efficiency vs pT full", "", 100, 0., 50., "type=efficiency");
+ thetaeff = hf.createHistogram1D("Efficiency vs theta", "", 72, 0., 180., "type=efficiency");
+ ctheff = hf.createHistogram1D("Efficiency vs cos(theta)", "", 200, -1., 1., "type=efficiency");
+ ctheff1 = hf.createHistogram1D("Efficiency vs cos(theta) - pT < 0.5 GeV", "", 200, -1., 1., "type=efficiency");
+ ctheff2 = hf.createHistogram1D("Efficiency vs cos(theta) - pT > 0.5 GeV", "", 200, -1., 1., "type=efficiency");
+ d0eff1 = hf.createHistogram1D("Efficiency vs d0", "", 50, -5., 5., "type=efficiency");
+ d0eff2 = hf.createHistogram1D("Efficiency vs d0 full", "", 24, -12., 12., "type=efficiency");
+ z0eff1 = hf.createHistogram1D("Efficiency vs z0", "", 50, -5., 5., "type=efficiency");
+ z0eff2 = hf.createHistogram1D("Efficiency vs z0 full", "", 24, -12., 12., "type=efficiency");
+ thrusteff = hf.createHistogram1D("Efficiency vs alpha", "", 100, 0., 90., "type=efficiency");
+ fakes = hf.createHistogram1D("Number of mis-matched hits (unnormalized)", "", 10, 0., 10.);
+ }
+
+ @Override
+ public void process(EventHeader event) {
+
+ // Increment the event counter
+ nevt++;
+
+ // Get the magnetic field
+ Hep3Vector IP = new BasicHep3Vector(0., 0., 0.);
+ double bfield = event.getDetector().getFieldMap().getField(IP).z();
+
+ // Get the list of strategies being used
+ String sfile = "autogen_muons_sidloi2.xml";
+// String sfile = "sATLASFull-SM08.xml";
+ List<SeedStrategy> slist = StrategyXMLUtils.getStrategyListFromResource(
+ StrategyXMLUtils.getDefaultStrategiesPrefix() + sfile);
+
+ // Find the minimum pT among the strategies
+ double ptCut = 9999.;
+ for (SeedStrategy s : slist) {
+ if (s.getMinPT() < ptCut) ptCut = s.getMinPT();
+ }
+
+ // Get the list of MCParticles
+ List<MCParticle> mclist = event.getMCParticles();
+
+ // Create a relational table that maps TrackerHits to MCParticles
+ RelationalTable hittomc = new BaseRelationalTable(RelationalTable.Mode.MANY_TO_MANY, RelationalTable.Weighting.UNWEIGHTED);
+ List<LCRelation> mcrelations = event.get(LCRelation.class, "HelicalTrackMCRelations");
+ for (LCRelation relation : mcrelations) {
+ hittomc.add(relation.getFrom(), relation.getTo());
+ }
+
+ // Instantiate the class that determines if a track is "findable"
+ FindableTrack findable = new FindableTrack(event);
+
+ // Create a map between tracks and the associated MCParticle
+ List<Track> tracklist = event.getTracks();
+ RelationalTable trktomc = new BaseRelationalTable(RelationalTable.Mode.MANY_TO_MANY, RelationalTable.Weighting.UNWEIGHTED);
+
+ // Analyze the tracks in the event
+ for (Track track : tracklist) {
+
+ // Increment the total number of tracks
+ ntrktot++;
+
+ // Calculate the track pT and cos(theta)
+ Hep3Vector ptrk = new BasicHep3Vector(track.getMomentum());
+ double px = ptrk.x();
+ double py = ptrk.y();
+ double pz = ptrk.z();
+ double pt = Math.sqrt(px * px + py * py);
+ double cth = pz / ptrk.magnitude();
+ double d0 = track.getTrackParameter(HelicalTrackFit.dcaIndex);
+ double z0 = track.getTrackParameter(HelicalTrackFit.z0Index);
+
+ // Analyze the hits on the track
+ TrackAnalysis tkanal = new TrackAnalysis(track, hittomc);
+
+ // Calculate purity and make appropriate plots
+ int nbad = tkanal.getNBadHits();
+ int nhits = tkanal.getNHits();
+ double purity = tkanal.getPurity();
+ aida.histogram1D("Mis-matched hits for all tracks", 10, 0., 10.).fill(nbad);
+ aida.histogram1D("Mis-matched hits " + nhits + " hit tracks", 10, 0., 10.).fill(nbad);
+ fakes.fill(nbad);
+
+ // Make plots for fake, non-fake, and all tracks
+ if (purity < 0.5) {
+ aida.histogram1D("Hits for fake tracks", 20, 0., 20.).fill(nhits);
+ aida.histogram1D("pT for fake tracks", 100, 0., 10.).fill(pt);
+ aida.histogram1D("cos(theta) for fake tracks", 100, -1., 1.).fill(cth);
+ aida.histogram1D("d0 for fake tracks", 50, -10., 10.).fill(d0);
+ aida.histogram1D("z0 for fake tracks", 50, -10., 10.).fill(z0);
+ } else {
+ aida.histogram1D("Hits for non-fake tracks", 20, 0., 20.).fill(nhits);
+ aida.histogram1D("pT for non-fake tracks", 100, 0., 10.).fill(pt);
+ aida.histogram1D("cos(theta) for non-fake tracks", 100, -1., 1.).fill(cth);
+ aida.histogram1D("d0 for non-fake tracks", 50, -10., 10.).fill(d0);
+ aida.histogram1D("z0 for non-fake tracks", 50, -10., 10.).fill(z0);
+ }
+ aida.histogram1D("Hits for all tracks", 20, 0., 20.).fill(nhits);
+ aida.histogram1D("pT for all tracks", 100, 0., 10.).fill(pt);
+ aida.histogram1D("cos(theta) for all tracks", 100, -1., 1.).fill(cth);
+ aida.histogram1D("d0 for all tracks", 50, -10., 10.).fill(d0);
+ aida.histogram1D("z0 for all tracks", 50, -10., 10.).fill(z0);
+
+ // Now analyze MC Particles on this track
+ MCParticle mcp = tkanal.getMCParticle();
+ if (mcp != null) {
+
+ // Create a map between the tracks found and the assigned MC particle
+ trktomc.add(track, tkanal.getMCParticle());
+
+ // Calculate the MC momentum and polar angle
+ Hep3Vector pmc = mcp.getMomentum();
+ double pxmc = pmc.x();
+ double pymc = pmc.y();
+ double ptmc = Math.sqrt(pxmc * pxmc + pymc * pymc);
+ double pxtk = track.getPX();
+ double pytk = track.getPY();
+ double pttk = Math.sqrt(pxtk * pxtk + pytk * pytk);
+
+ // Calculate the helix parameters for this MC particle and pulls in pT, d0
+ HelixParamCalculator helix = new HelixParamCalculator(mcp, bfield);
+ double d0tk = track.getTrackParameter(HelicalTrackFit.dcaIndex);
+ double d0mc = helix.getDCA();
+ double d0err = Math.sqrt(track.getErrorMatrix().diagonal(HelicalTrackFit.dcaIndex));
+ double curv = track.getTrackParameter(HelicalTrackFit.curvatureIndex);
+ double curverr = Math.sqrt(track.getErrorMatrix().diagonal(HelicalTrackFit.curvatureIndex));
+ double pterr = pttk * curverr / curv;
+ double d0pull = (d0tk - d0mc) / d0err;
+ double ptpull = (pttk - ptmc) / pterr;
+
+ // Plot the pt and d0 pulls for various purity intervals
+ if (nbad == 0) {
+ aida.histogram2D("pT MC vs pT Reco for 0 Bad Hits",
+ 100, 0., 5., 100, 0., 5.).fill(ptmc, pttk);
+ aida.histogram2D("d0 MC vs d0 Reco for 0 Bad Hits",
+ 100, -0.2, 0.2, 100, -0.2, 0.2).fill(d0mc, d0tk);
+ aida.histogram1D("pT Pull for 0 Bad Hits", 100, -10., 10.).fill(ptpull);
+ aida.histogram1D("d0 pull for 0 Bad Hits", 100, -10., 10.).fill(d0pull);
+ } else if (purity > 0.5) {
+ aida.histogram2D("pT MC vs pT Reco for 0.5 < purity < 1",
+ 100, 0., 5., 100, 0., 5.).fill(ptmc, pttk);
+ aida.histogram2D("d0 MC vs d0 Reco for 0.5 < purity < 1",
+ 100, -0.2, 0.2, 100, -0.2, 0.2).fill(d0mc, d0tk);
+ aida.histogram1D("pT Pull for 0.5 < purity < 1", 100, -10., 10.).fill(ptpull);
+ aida.histogram1D("d0 pull for 0.5 < purity < 1", 100, -10., 10.).fill(d0pull);
+ } else if (purity < 0.5) {
+ aida.histogram2D("pT MC vs pT Reco for purity <= 0.5",
+ 100, 0., 5., 100, 0., 5.).fill(ptmc, pttk);
+ aida.histogram2D("d0 MC vs d0 Reco for purity <= 0.5",
+ 100, -0.2, 0.2, 100, -0.2, 0.2).fill(d0mc, d0tk);
+ aida.histogram1D("pT Pull for purity <= 0.5", 100, -10., 10.).fill(ptpull);
+ aida.histogram1D("d0 pull for purity <= 0.5", 100, -10., 10.).fill(d0pull);
+ }
+ }
+ }
+
+ // Calculate the thrust axis and find it's polar angle
+ Hep3Vector taxis = Thrust(mclist);
+ double cth_thrust = taxis.z() / taxis.magnitude();
+ double thrang = 180. * Math.acos(cth_thrust) / Math.PI;
+ aida.histogram1D("Polar angle of the thrust axis", 90, 0., 180.).fill(thrang);
+ aida.histogram1D("cos(theta) of the thrust axis", 100, -1., 1.).fill(cth_thrust);
+
+ // Now loop over all MC Particles
+ for (MCParticle mcp : mclist) {
+
+ // Calculate the pT and polar angle of the MC particle
+ Hep3Vector pmc = mcp.getMomentum();
+ double px = pmc.x();
+ double py = pmc.y();
+ double pz = pmc.z();
+ double pt = Math.sqrt(px * px + py * py);
+ double cth = pz / pmc.magnitude();
+ double theta = 180. * Math.acos(cth) / Math.PI;
+
+ // Calculate the angle between the MC Particle and the thrust axis
+ double calpha = VecOp.dot(pmc, taxis) / (pmc.magnitude() * taxis.magnitude());
+ double alpha = 180. * Math.acos(Math.abs(calpha)) / Math.PI;
+
+ // Find the number of layers hit by this mc particle
+ int nhits = findable.LayersHit(mcp);
+
+ // Calculate the helix parameters for this MC particle
+ HelixParamCalculator helix = new HelixParamCalculator(mcp, bfield);
+ double d0 = helix.getDCA();
+ double z0 = helix.getZ0();
+
+ // Calculate the weight for the efficiency plots
+ double wgt = 0.;
+ if (trktomc.allTo(mcp).size() > 0) wgt = 1.;
+
+ // Make pT efficiency plot
+ if (findable.isFindable(mcp, slist, Ignore.NoPTCut)) {
+ pTeff1.fill(pt, wgt);
+ pTeff2.fill(pt, wgt);
+ }
+
+ // Make angular efficiency plot
+ if (findable.isFindable(mcp, slist)) {
+ thetaeff.fill(theta, wgt);
+ ctheff.fill(cth, wgt);
+ if (pt < 0.5) ctheff1.fill(cth, wgt);
+ else ctheff2.fill(cth, wgt);
+ }
+
+ // Make d0 efficiency plot
+ if (findable.isFindable(mcp, slist, Ignore.NoDCACut)) {
+ d0eff1.fill(d0, wgt);
+ d0eff2.fill(d0, wgt);
+ }
+
+ // Make z0 efficiency plot
+ if (findable.isFindable(mcp, slist, Ignore.NoZ0Cut)) {
+ z0eff1.fill(z0, wgt);
+ z0eff2.fill(z0, wgt);
+ }
+
+ // Make the thrust axis efficiency plot
+ if (findable.isFindable(mcp, slist)) {
+ thrusteff.fill(alpha, wgt);
+ }
+
+ //
+ // Select charged MC particles
+ if (mcp.getCharge() == 0) continue;
+
+ // Select mcp that fail the final state requirement
+ if (mcp.getGeneratorStatus() != mcp.FINAL_STATE) {
+ aida.histogram1D("Hits for non-final state particles", 20, 0., 20.).fill(nhits);
+ aida.histogram1D("pT for non-final state particles", 100, 0., 10.).fill(pt);
+ aida.histogram1D("cos(theta) for non-final state particles", 100, -1., 1.).fill(cth);
+ aida.histogram1D("d0 for non-final state particles", 100, -100., 100.).fill(d0);
+ aida.histogram1D("z0 for non-final state particles", 100, -100., 100.).fill(z0);
+ aida.histogram1D("alpha for non-final state particles", 90, 0., 90.).fill(alpha);
+ continue;
+ }
+
+ // Make plots for the base sample
+ aida.histogram1D("Hits for base MC selection", 20, 0., 20.).fill(nhits);
+ aida.histogram1D("pT for base MC selection", 100, 0., 10.).fill(pt);
+ aida.histogram1D("cos(theta) for base MC selection", 100, -1., 1.).fill(cth);
+ aida.histogram1D("d0 for base MC selection", 100, -100., 100.).fill(d0);
+ aida.histogram1D("z0 for base MC selection", 100, -100., 100.).fill(z0);
+ aida.histogram1D("alpha for base MC selection", 90, 0., 90.).fill(alpha);
+
+ // Make plots for findable tracks
+ if (findable.isFindable(mcp, slist)) {
+ aida.histogram1D("Hits for findable tracks", 20, 0., 20.).fill(nhits);
+ aida.histogram1D("pT for findable tracks", 100, 0., 10.).fill(pt);
+ aida.histogram1D("cos(theta) for findable tracks", 100, -1., 1.).fill(cth);
+ aida.histogram1D("d0 for findable tracks", 100, -100., 100.).fill(d0);
+ aida.histogram1D("z0 for findable tracks", 100, -100., 100.).fill(z0);
+ aida.histogram1D("alpha for findable tracks", 90, 0., 90.).fill(alpha);
+
+ // Make plots for findable tracks that are not found
+ if (trktomc.allTo(mcp).size() == 0) {
+ aida.histogram1D("Hits for unfound tracks", 20, 0., 20.).fill(nhits);
+ aida.histogram1D("pT for unfound tracks", 100, 0., 10.).fill(pt);
+ aida.histogram1D("cos(theta) for unfound tracks", 100, -1., 1.).fill(cth);
+ aida.histogram1D("d0 for unfound tracks", 100, -100., 100.).fill(d0);
+ aida.histogram1D("z0 for unfound tracks", 100, -100., 100.).fill(z0);
+ aida.histogram1D("alpha for unfound tracks", 90, 0., 90.).fill(alpha);
+ }
+ continue;
+ }
+
+ // Create the running list of conditions to ignore
+ List<Ignore> ignores = new ArrayList<Ignore>();
+
+ // select mc particles that fail on the z0 cut
+ ignores.add(Ignore.NoZ0Cut);
+ if (findable.isFindable(mcp, slist, ignores)) {
+ aida.histogram1D("Hits for z0 check failures", 20, 0., 20.).fill(nhits);
+ aida.histogram1D("pT for z0 check failures", 100, 0., 10.).fill(pt);
+ aida.histogram1D("cos(theta) for z0 check failures", 100, -1., 1.).fill(cth);
+ aida.histogram1D("d0 for z0 check failures", 100, -100., 100.).fill(d0);
+ aida.histogram1D("z0 for z0 check failures", 100, -100., 100.).fill(z0);
+ aida.histogram1D("alpha for z0 check failures", 90, 0., 90.).fill(alpha);
+ continue;
+ }
+
+ // Select mc particles that fail on the d0 cut
+ ignores.add(Ignore.NoDCACut);
+ if (findable.isFindable(mcp, slist, ignores)) {
+ aida.histogram1D("Hits for d0 check failures", 20, 0., 20.).fill(nhits);
+ aida.histogram1D("pT for d0 check failures", 100, 0., 10.).fill(pt);
+ aida.histogram1D("cos(theta) for d0 check failures", 100, -1., 1.).fill(cth);
+ aida.histogram1D("d0 for d0 check failures", 100, -100., 100.).fill(d0);
+ aida.histogram1D("z0 for d0 check failures", 100, -100., 100.).fill(z0);
+ aida.histogram1D("alpha for d0 check failures", 90, 0., 90.).fill(alpha);
+ continue;
+ }
+
+ // select mc particles that fail the confirm check
+ ignores.add(Ignore.NoConfirmCheck);
+ if (findable.isFindable(mcp, slist, ignores)) {
+ aida.histogram1D("Hits for confirm check failures", 20, 0., 20.).fill(nhits);
+ aida.histogram1D("pT for confir check failures", 100, 0., 10.).fill(pt);
+ aida.histogram1D("cos(theta) for confirm check failures", 100, -1., 1.).fill(cth);
+ aida.histogram1D("d0 for seed confirm failures", 100, -100., 100.).fill(d0);
+ aida.histogram1D("z0 for seed confirm failures", 100, -100., 100.).fill(z0);
+ aida.histogram1D("alpha for seed confirm failures", 90, 0., 90.).fill(alpha);
+ continue;
+ }
+
+ // select mc particles that fail on the seed check
+ ignores.add(Ignore.NoSeedCheck);
+ if (findable.isFindable(mcp, slist, ignores)) {
+ aida.histogram1D("Hits for seed check failures", 20, 0., 20.).fill(nhits);
+ aida.histogram1D("pT for seed check failures", 100, 0., 10.).fill(pt);
+ aida.histogram1D("cos(theta) for seed check failures", 100, -1., 1.).fill(cth);
+ aida.histogram1D("d0 for seed check failures", 100, -100., 100.).fill(d0);
+ aida.histogram1D("z0 for seed check failures", 100, -100., 100.).fill(z0);
+ aida.histogram1D("alpha for seed check failures", 90, 0., 90.).fill(alpha);
+ continue;
+ }
+
+ // Select mc particles that fail the number of hit cut
+ ignores.add(Ignore.NoMinHitCut);
+ if (findable.isFindable(mcp, slist, ignores)) {
+ aida.histogram1D("Hits for nhit check failures", 20, 0., 20.).fill(nhits);
+ aida.histogram1D("pT for nhit check failures", 100, 0., 10.).fill(pt);
+ aida.histogram1D("cos(theta) for nhit check failures", 100, -1., 1.).fill(cth);
+ aida.histogram1D("d0 for nhit check failures", 100, -100., 100.).fill(d0);
+ aida.histogram1D("z0 for nhit check failures", 100, -100., 100.).fill(z0);
+ aida.histogram1D("alpha for nhit check failures", 90, 0., 90.).fill(alpha);
+ continue;
+ }
+
+ // Select mc particles that fail on the pT cut
+ ignores.add(Ignore.NoPTCut);
+ if (findable.isFindable(mcp, slist, ignores)) {
+ aida.histogram1D("Hits for pT check failures", 20, 0., 20.).fill(nhits);
+ aida.histogram1D("pT for pT check failures", 100, 0., 10.).fill(pt);
+ aida.histogram1D("cos(theta) for pT check failures", 100, -1., 1.).fill(cth);
+ aida.histogram1D("d0 for pT check failures", 100, -100., 100.).fill(d0);
+ aida.histogram1D("z0 for pT check failures", 100, -100., 100.).fill(z0);
+ aida.histogram1D("alpha for pT check failures", 90, 0., 90.).fill(alpha);
+ } else {
+ System.out.println("**** MC Particle is not findable with all ignores set!!");
+ }
+ }
+
+ // Make the normalized plot every 100 events
+ if (nevt % 100 == 0) {
+ nfakes = hf.createHistogram1D("Number of mis-matched hits (normalized)", "", 10, 0., 10.);
+ double wgt = 1. / ntrktot;
+ for (int i = 0; i < 10; i++) {
+ for (int j = 0; j < fakes.binHeight(i); j++) {
+ nfakes.fill(i, wgt);
+ }
+ }
+ }
+
+ return;
+ }
+
+// @Override
+// protected void endOfData() {
+
+ // Make the normalized fake plot
+// double wgt = 100. / ntrktot;
+// for (int i = 0; i < 10; i++) {
+// System.out.println(" Entries: " + fakes.binEntries(i) + " for mismatches: " + i);
+// for (int j = 0; j < fakes.binHeight(i); j++) {
+// nfakes.fill(i, wgt);
+// }
+// }
+// System.out.println("Normalization: " + nfakes.sumAllBinHeights() + " after ntrk = " + ntrktot);
+// }
+
+ private Hep3Vector Thrust(List<MCParticle> mclist) {
+
+ // Make a list of final state particle momenta
+ List<Hep3Vector> plist = new ArrayList<Hep3Vector>();
+ if (mclist.size()>2000) return new BasicHep3Vector(0., 0., 1.0);
+
+ for (MCParticle mcp : mclist) {
+ if (mcp.getGeneratorStatus() == MCParticle.FINAL_STATE)
+ plist.add(mcp.getMomentum());
+ }
+
+ // Caclulate the thrust axis
+ es.setEvent(plist);
+ return es.thrustAxis();
+ }
+}
\ No newline at end of file