Author: [log in to unmask] Date: Mon Jul 20 17:52:07 2015 New Revision: 3267 Log: Added user analysis driver. Added: java/trunk/users/src/main/java/org/hps/users/kmccarty/TridentTrackDriver.java Modified: java/trunk/users/src/main/java/org/hps/users/kmccarty/InvariantMassPairDriver.java java/trunk/users/src/main/java/org/hps/users/kmccarty/MTEAnalysis.java Modified: java/trunk/users/src/main/java/org/hps/users/kmccarty/InvariantMassPairDriver.java ============================================================================= --- java/trunk/users/src/main/java/org/hps/users/kmccarty/InvariantMassPairDriver.java (original) +++ java/trunk/users/src/main/java/org/hps/users/kmccarty/InvariantMassPairDriver.java Mon Jul 20 17:52:07 2015 @@ -29,6 +29,8 @@ private IHistogram2D pair2DEnergyHist = aida.histogram2D("Trident Analysis/2D Energy Distribution", 55, 0, 1.1, 55, 0, 1.1); private IHistogram1D pair1MassHist = aida.histogram1D("Trident Analysis/Particle Invariant Mass (1 Hit)", 240, 0.000, 0.120); private IHistogram1D pair1ModMassHist = aida.histogram1D("Trident Analysis/Particle Invariant Mass (2 Hit)", 240, 0.000, 0.120); + private IHistogram1D elasticElectronEnergyHist = aida.histogram1D("Trident Analysis/Trident Electron Energy", 150, 0.000, 1.500); + private IHistogram1D elasticPositronEnergyHist = aida.histogram1D("Trident Analysis/Trident Positron Energy", 150, 0.000, 1.500); @Override public void startOfData() { @@ -67,6 +69,11 @@ @Override public void process(EventHeader event) { + // Skip the event if there is no reconstructed particle list. + if(!event.hasCollection(ReconstructedParticle.class, particleCollectionName)) { + return; + } + // Get a list of all tracks in the event. List<ReconstructedParticle> trackList = event.get(ReconstructedParticle.class, particleCollectionName); @@ -166,6 +173,10 @@ // Populate the invariant mass plot. candidateLoop: for(ReconstructedParticle particle : candidateList) { + // Track the electron and positron momenta. + double electronMomentum = 0.0; + double positronMomentum = 0.0; + // Check that it has component particles that meet the // trident condition. boolean seenPositive = false; @@ -179,6 +190,7 @@ // Otherwise, note that one has been seen. seenNegative = true; + electronMomentum = track.getMomentum().magnitude(); // Reject electrons with a momentum exceeding 900 MeV. if(track.getMomentum().magnitude() > 0.900) { @@ -194,6 +206,7 @@ // Otherwise, note that one has been seen. seenPositive = true; + positronMomentum = track.getMomentum().magnitude(); } // Lastly, reject any particle that produced a photon. @@ -202,6 +215,8 @@ // Populate the plots. pair1MassHist.fill(particle.getMass()); + elasticElectronEnergyHist.fill(electronMomentum); + elasticPositronEnergyHist.fill(positronMomentum); if(passedPair1Mod) { pair1ModMassHist.fill(particle.getMass()); } } } Modified: java/trunk/users/src/main/java/org/hps/users/kmccarty/MTEAnalysis.java ============================================================================= --- java/trunk/users/src/main/java/org/hps/users/kmccarty/MTEAnalysis.java (original) +++ java/trunk/users/src/main/java/org/hps/users/kmccarty/MTEAnalysis.java Mon Jul 20 17:52:07 2015 @@ -7,6 +7,7 @@ import java.util.ArrayList; import java.util.List; +import org.lcsim.event.CalorimeterHit; import org.lcsim.event.Cluster; import org.lcsim.event.EventHeader; import org.lcsim.event.ReconstructedParticle; @@ -18,9 +19,9 @@ private String particleCollectionName = "FinalStateParticles"; private static final AIDA aida = AIDA.defaultInstance(); private IHistogram1D[] chargedTracksPlot = { - aida.histogram1D("MTE Analysis/Møller Event Tracks", 10, 0, 10), - aida.histogram1D("MTE Analysis/Trident Event Tracks", 10, 0, 10), - aida.histogram1D("MTE Analysis/Elastic Event Tracks", 10, 0, 10) + aida.histogram1D("MTE Analysis/Møller Event Tracks", 10, -0.5, 9.5), + aida.histogram1D("MTE Analysis/Trident Event Tracks", 10, -0.5, 9.5), + aida.histogram1D("MTE Analysis/Elastic Event Tracks", 10, -0.5, 9.5) }; private IHistogram1D[] energyPlot = { aida.histogram1D("MTE Analysis/Møller Energy Sum Distribution", 220, 0, 2.2), @@ -36,16 +37,28 @@ aida.histogram2D("MTE Analysis/Møller 2D Energy Distribution", 55, 0, 1.1, 55, 0, 1.1), aida.histogram2D("MTE Analysis/Trident 2D Energy Distribution", 55, 0, 1.1, 55, 0, 1.1), }; + private IHistogram1D timePlot = aida.histogram1D("MTE Analysis/Track Cluster Time Distribution", 4000, 0, 400); + private IHistogram1D timeCoincidencePlot = aida.histogram1D("MTE Analysis/Møller Time Coincidence Distribution", 1000, 0, 100); + private IHistogram1D timeCoincidenceAllCutsPlot = aida.histogram1D("MTE Analysis/Møller Time Coincidence Distribution (All Møller Cuts)", 1000, 0, 100); private static final int MÃLLER = 0; private static final int TRIDENT = 1; private static final int ELASTIC = 2; private boolean verbose = false; + private double timeCoincidenceCut = Double.MAX_VALUE; @Override public void process(EventHeader event) { if(event.hasCollection(ReconstructedParticle.class, particleCollectionName)) { // Get the list of tracks. List<ReconstructedParticle> trackList = event.get(ReconstructedParticle.class, particleCollectionName); + + // Plot the time stamps of all tracks. + for(ReconstructedParticle track : trackList) { + if(track.getClusters().size() != 0) { + Cluster cluster = track.getClusters().get(0); + timePlot.fill(cluster.getCalorimeterHits().get(0).getTime()); + } + } if(verbose) { System.out.println(trackList.size() + " tracks found."); @@ -87,7 +100,19 @@ // Require that the track clusters be within a certain // time window of one another. - if(Math.abs(trackClusters[0].getCalorimeterHits().get(0).getTime() - trackClusters[1].getCalorimeterHits().get(0).getTime()) > 500) { + CalorimeterHit[] seeds = new CalorimeterHit[2]; + seeds[0] = trackClusters[0].getCalorimeterHits().get(0); + seeds[1] = trackClusters[1].getCalorimeterHits().get(0); + timeCoincidencePlot.fill(Math.abs(seeds[0].getTime() - seeds[1].getTime())); + if(Math.abs(trackClusters[0].getCalorimeterHits().get(0).getTime() - trackClusters[1].getCalorimeterHits().get(0).getTime()) > timeCoincidenceCut) { + continue møllerTrackLoop; + } + + // Require both tracks to occur within the range of + // 36.5 and 49 ns. + if(seeds[0].getTime() < 36.5 || seeds[0].getTime() > 49) { + continue møllerTrackLoop; + } if(seeds[1].getTime() < 36.5 || seeds[1].getTime() > 49) { continue møllerTrackLoop; } @@ -104,6 +129,8 @@ if(sum < 0.800 || sum > 1.500) { continue møllerTrackLoop; } + + timeCoincidenceAllCutsPlot.fill(Math.abs(seeds[0].getTime() - seeds[1].getTime())); // Note that this is a Møller event. isMøller = true; @@ -172,6 +199,10 @@ } } + public void setTimeCoincidenceCut(double value) { + timeCoincidenceCut = value; + } + private static final List<ReconstructedParticle[]> getTrackPairs(List<ReconstructedParticle> trackList) { // Create an empty list for the pairs. List<ReconstructedParticle[]> pairs = new ArrayList<ReconstructedParticle[]>(); @@ -186,17 +217,4 @@ // Return the list of tracks. return pairs; } - - private static final double getMagnitude(double[] vector) { - // Store the squares of each component of the vector. - double squareSum = 0; - - // Add the square of each vector component. - for(double d : vector) { - squareSum += d * d; - } - - // Return the square root of the sum. - return Math.sqrt(squareSum); - } } Added: java/trunk/users/src/main/java/org/hps/users/kmccarty/TridentTrackDriver.java ============================================================================= --- java/trunk/users/src/main/java/org/hps/users/kmccarty/TridentTrackDriver.java (added) +++ java/trunk/users/src/main/java/org/hps/users/kmccarty/TridentTrackDriver.java Mon Jul 20 17:52:07 2015 @@ -0,0 +1,205 @@ +package org.hps.users.kmccarty; + +import hep.aida.IHistogram1D; +import hep.aida.IHistogram2D; + +import java.util.ArrayList; +import java.util.List; + +import org.lcsim.event.EventHeader; +import org.lcsim.event.ReconstructedParticle; +import org.lcsim.util.Driver; +import org.lcsim.util.aida.AIDA; + +public class TridentTrackDriver extends Driver { + private String finalStateCollectionName = "FinalStateParticles"; + private String candidateCollectionName = "UnconstrainedV0Candidates"; + + private int tracksCandidate = 0; + private int tracksFinalState = 0; + private int tracksCandidateCluster = 0; + private int tracksFinalStateCluster = 0; + + private static final int ANY_CLUSTER = 0; + private static final int HAS_CLUSTER = 1; + + private AIDA aida = AIDA.defaultInstance(); + private IHistogram1D[] tracks = new IHistogram1D[2]; + private IHistogram1D[] posTracks = new IHistogram1D[2]; + private IHistogram1D[] negTracks = new IHistogram1D[2]; + private IHistogram1D[] posMomentum = new IHistogram1D[2]; + private IHistogram1D[] negMomentum = new IHistogram1D[2]; + private IHistogram1D[] energySum = new IHistogram1D[2]; + private IHistogram1D[] invariantMass = new IHistogram1D[2]; + private IHistogram2D[] energySum2D = new IHistogram2D[2]; + private IHistogram2D[] position = new IHistogram2D[2]; + + @Override + public void startOfData() { + // Instantiate the "any cluster status" plots. + tracks[ANY_CLUSTER] = aida.histogram1D("Trident Analysis/All/Tracks in Event (All)", 20, 0, 20); + posTracks[ANY_CLUSTER] = aida.histogram1D("Trident Analysis/All/Tracks in Event (Positive)", 20, 0, 20); + negTracks[ANY_CLUSTER] = aida.histogram1D("Trident Analysis/All/Tracks in Event (Negative)", 20, 0, 20); + posMomentum[ANY_CLUSTER] = aida.histogram1D("Trident Analysis/All/Momentum (Positive)", 110, 0, 1.1); + negMomentum[ANY_CLUSTER] = aida.histogram1D("Trident Analysis/All/Momentum (Negative)", 110, 0, 1.1); + energySum[ANY_CLUSTER] = aida.histogram1D("Trident Analysis/All/Energy Sum", 220, 0, 2.2); + invariantMass[ANY_CLUSTER] = aida.histogram1D("Trident Analysis/All/Invariant Mass", 240, 0.000, 0.120); + energySum2D[ANY_CLUSTER] = aida.histogram2D("Trident Analysis/All/2D Energy Sum", 55, 0, 1.1, 55, 0, 1.1); + position[ANY_CLUSTER] = aida.histogram2D("Trident Analysis/All/Track Cluster Position", 46, -23, 23, 11, -5.5, 5.5); + + // Instantiate the "has a cluster" plots. + tracks[HAS_CLUSTER] = aida.histogram1D("Trident Analysis/Cluster/Tracks in Event (All)", 20, 0, 20); + posTracks[HAS_CLUSTER] = aida.histogram1D("Trident Analysis/Cluster/Tracks in Event (Positive)", 20, 0, 20); + negTracks[HAS_CLUSTER] = aida.histogram1D("Trident Analysis/Cluster/Tracks in Event (Negative)", 20, 0, 20); + posMomentum[HAS_CLUSTER] = aida.histogram1D("Trident Analysis/Cluster/Momentum (Positive)", 110, 0, 1.1); + negMomentum[HAS_CLUSTER] = aida.histogram1D("Trident Analysis/Cluster/Momentum (Negative)", 110, 0, 1.1); + energySum[HAS_CLUSTER] = aida.histogram1D("Trident Analysis/Cluster/Energy Sum", 220, 0, 2.2); + invariantMass[HAS_CLUSTER] = aida.histogram1D("Trident Analysis/Cluster/Invariant Mass", 240, 0.000, 0.120); + energySum2D[HAS_CLUSTER] = aida.histogram2D("Trident Analysis/Cluster/2D Energy Sum", 55, 0, 1.1, 55, 0, 1.1); + position[HAS_CLUSTER] = aida.histogram2D("Trident Analysis/Cluster/Track Cluster Position", 46, -23, 23, 11, -5.5, 5.5); + } + + @Override + public void endOfData() { + System.out.printf("Tracks (Candidate) :: %d%n", tracksCandidate); + System.out.printf("Tracks (Final State) :: %d%n", tracksFinalState); + System.out.printf("Cluster Tracks (Candidate) :: %d%n", tracksCandidateCluster); + System.out.printf("Cluster Tracks (Final State) :: %d%n", tracksFinalStateCluster); + } + + @Override + public void process(EventHeader event) { + // Check for final state particles. + if(event.hasCollection(ReconstructedParticle.class, finalStateCollectionName)) { + // Get the final state particles. + List<ReconstructedParticle> trackList = event.get(ReconstructedParticle.class, finalStateCollectionName); + + // Get the number of tracks. + tracksFinalState += trackList.size(); + + // Store the positive and negative tracks. + List<ReconstructedParticle> posTrackList = new ArrayList<ReconstructedParticle>(); + List<ReconstructedParticle> negTrackList = new ArrayList<ReconstructedParticle>(); + + // Store the same tracks, but limited to those with clusters. + List<ReconstructedParticle> allClusterTrackList = new ArrayList<ReconstructedParticle>(); + List<ReconstructedParticle> posClusterTrackList = new ArrayList<ReconstructedParticle>(); + List<ReconstructedParticle> negClusterTrackList = new ArrayList<ReconstructedParticle>(); + + // Iterate over the tracks and populate the lists. + for(ReconstructedParticle track : trackList) { + if(track.getCharge() > 0) { + // Increment the counters and populate the momentum plots. + posTrackList.add(track); + posMomentum[ANY_CLUSTER].fill(track.getMomentum().magnitude()); + + // Repeat for the "has clusters" plots if necessary. + if(track.getClusters().size() > 0) { + // Increment the counters and populate the + // momentum plot. + posClusterTrackList.add(track); + allClusterTrackList.add(track); + posMomentum[HAS_CLUSTER].fill(track.getMomentum().magnitude()); + + // Populate the cluster position plot. + int ix = track.getClusters().get(0).getCalorimeterHits().get(0).getIdentifierFieldValue("ix"); + int iy = track.getClusters().get(0).getCalorimeterHits().get(0).getIdentifierFieldValue("iy"); + position[HAS_CLUSTER].fill(ix, iy); + } + } else if(track.getCharge() < 0) { + // Increment the counters and populate the momentum plots. + negTrackList.add(track); + negMomentum[ANY_CLUSTER].fill(track.getMomentum().magnitude()); + + // Repeat for the "has clusters" plots if necessary. + if(track.getClusters().size() > 0) { + // Increment the counters and populate the + // momentum plot. + negClusterTrackList.add(track); + allClusterTrackList.add(track); + negMomentum[HAS_CLUSTER].fill(track.getMomentum().magnitude()); + + // Populate the cluster position plot. + int ix = track.getClusters().get(0).getCalorimeterHits().get(0).getIdentifierFieldValue("ix"); + int iy = track.getClusters().get(0).getCalorimeterHits().get(0).getIdentifierFieldValue("iy"); + position[HAS_CLUSTER].fill(ix, iy); + } + } else { + if(track.getClusters().size() > 0) { + // Increment the counter. + allClusterTrackList.add(track); + + // Populate the cluster position plot. + int ix = track.getClusters().get(0).getCalorimeterHits().get(0).getIdentifierFieldValue("ix"); + int iy = track.getClusters().get(0).getCalorimeterHits().get(0).getIdentifierFieldValue("iy"); + position[HAS_CLUSTER].fill(ix, iy); + } + } + + // Track the number of cluster tracks. + if(!track.getClusters().isEmpty()) { + tracksFinalStateCluster++; + } + } + + // Populate the tracks per event plots. + tracks[ANY_CLUSTER].fill(trackList.size()); + tracks[HAS_CLUSTER].fill(allClusterTrackList.size()); + posTracks[ANY_CLUSTER].fill(posTrackList.size()); + posTracks[HAS_CLUSTER].fill(posClusterTrackList.size()); + negTracks[ANY_CLUSTER].fill(negTrackList.size()); + negTracks[HAS_CLUSTER].fill(negClusterTrackList.size()); + + /// Store track pairs. + List<ReconstructedParticle[]> pairList = new ArrayList<ReconstructedParticle[]>(); + List<ReconstructedParticle[]> pairClusterList = new ArrayList<ReconstructedParticle[]>(); + + // Form track pairs for all tracks. + for(ReconstructedParticle posTrack : posTrackList) { + for(ReconstructedParticle negTrack : negTrackList) { + pairList.add(new ReconstructedParticle[] { posTrack, negTrack }); + } + } + + // Form track pairs for cluster tracks. + for(ReconstructedParticle posTrack : posClusterTrackList) { + for(ReconstructedParticle negTrack : negClusterTrackList) { + pairClusterList.add(new ReconstructedParticle[] { posTrack, negTrack }); + } + } + + // Populate the track pair plots. + for(ReconstructedParticle[] pair : pairList) { + energySum[ANY_CLUSTER].fill(pair[0].getEnergy() + pair[1].getEnergy()); + energySum2D[ANY_CLUSTER].fill(pair[0].getEnergy(), pair[1].getEnergy()); + } + + // Populate the cluster track pair plots. + for(ReconstructedParticle[] pair : pairClusterList) { + energySum[HAS_CLUSTER].fill(pair[0].getEnergy() + pair[1].getEnergy()); + energySum2D[HAS_CLUSTER].fill(pair[0].getEnergy(), pair[1].getEnergy()); + } + } + + // Check for V0 candidates. + if(event.hasCollection(ReconstructedParticle.class, candidateCollectionName)) { + // Get the candidate particles. + List<ReconstructedParticle> trackList = event.get(ReconstructedParticle.class, candidateCollectionName); + + // Increment the counter. + tracksCandidate += trackList.size(); + + // Increment the counter for cluster tracks. + for(ReconstructedParticle track : trackList) { + // Populate the invariant mass plot. + invariantMass[ANY_CLUSTER].fill(track.getMass()); + + // Check for a cluster track. + if(track.getClusters().size() > 0) { + tracksCandidateCluster++; + invariantMass[HAS_CLUSTER].fill(track.getMass()); + } + } + } + } +}