LISTSERV mailing list manager LISTSERV 16.5

Help for HPS-SVN Archives


HPS-SVN Archives

HPS-SVN Archives


HPS-SVN@LISTSERV.SLAC.STANFORD.EDU


View:

Message:

[

First

|

Previous

|

Next

|

Last

]

By Topic:

[

First

|

Previous

|

Next

|

Last

]

By Author:

[

First

|

Previous

|

Next

|

Last

]

Font:

Proportional Font

LISTSERV Archives

LISTSERV Archives

HPS-SVN Home

HPS-SVN Home

HPS-SVN  September 2016

HPS-SVN September 2016

Subject:

r4477 - in /java/trunk/users/src/main/java/org/hps/users/spaul: fee/Cleanup.java fee/FeeHistogramDriver.java fee_old/ feecc/ moller/MollerBeamtiltAnalysis.java trident/TridentHistogramDriver.java

From:

[log in to unmask]

Reply-To:

Notification of commits to the hps svn repository <[log in to unmask]>

Date:

Thu, 1 Sep 2016 11:26:09 -0000

Content-Type:

text/plain

Parts/Attachments:

Parts/Attachments

text/plain (1666 lines)

Author: [log in to unmask]
Date: Thu Sep  1 04:26:03 2016
New Revision: 4477

Log: (empty)

Added:
    java/trunk/users/src/main/java/org/hps/users/spaul/fee_old/
      - copied from r4472, java/trunk/users/src/main/java/org/hps/users/spaul/feecc/
Removed:
    java/trunk/users/src/main/java/org/hps/users/spaul/feecc/
Modified:
    java/trunk/users/src/main/java/org/hps/users/spaul/fee/Cleanup.java
    java/trunk/users/src/main/java/org/hps/users/spaul/fee/FeeHistogramDriver.java
    java/trunk/users/src/main/java/org/hps/users/spaul/moller/MollerBeamtiltAnalysis.java
    java/trunk/users/src/main/java/org/hps/users/spaul/trident/TridentHistogramDriver.java

Modified: java/trunk/users/src/main/java/org/hps/users/spaul/fee/Cleanup.java
 =============================================================================
--- java/trunk/users/src/main/java/org/hps/users/spaul/fee/Cleanup.java	(original)
+++ java/trunk/users/src/main/java/org/hps/users/spaul/fee/Cleanup.java	Thu Sep  1 04:26:03 2016
@@ -5,24 +5,34 @@
 import java.util.ArrayList;
 import java.util.List;
 
+import org.hps.recon.tracking.TrackUtils;
 import org.lcsim.event.ReconstructedParticle;
+import org.lcsim.event.Track;
 
 public class Cleanup {
 
-	public static void purgeDuplicates(List<ReconstructedParticle> particles) {
+	public static void purgeParticlesWithSameCluster(List<ReconstructedParticle> particles) {
 		ArrayList<ReconstructedParticle> trashcan = new ArrayList();
 		outer : for(ReconstructedParticle p1 : particles){
 			if(trashcan.contains(p1))
 				continue;
+			if(p1.getClusters().size() == 0){
+				trashcan.add(p1);
+				continue;
+			}
 			for(ReconstructedParticle p2 : particles){
 				if(p1 == p2) continue;
 				if(trashcan.contains(p2))
 					continue;
+				if(p2.getClusters().size() == 0)
+				{
+					trashcan.add(p2);
+					continue;
+				}
 				if((p1.getType()>31)^(p2.getType()>31)){ //one is GBL, the other is seed.  
 					continue;
 				}
-				
-				if(p1.getEnergy() == p2.getEnergy()){ //tracks matched to same cluster
+				if(p1.getClusters().get(0) == p2.getClusters().get(0)){ //tracks matched to same cluster
 					ReconstructedParticle loser = getWorseParticle(p1, p2);
 					trashcan.add(loser);
 				}
@@ -36,18 +46,41 @@
 	}
 	
 	static ReconstructedParticle getWorseParticle(ReconstructedParticle p1, ReconstructedParticle p2){
-		if(p1.getTracks().get(0).getChi2() < p2.getTracks().get(0).getChi2())
+		//first check if the tracks come from the target:
+		
+		if(p1.getTracks().size() == 0)
+			return p1;
+		if(p2.getTracks().size() == 0)
+			return p2;
+		
+		Track t1 = p1.getTracks().get(0);
+		Track t2 = p2.getTracks().get(0);
+		
+		
+		//first see if there is some clue that one of the tracks is better than the other:
+		if(Math.abs(TrackUtils.getDoca(t1))>1 && Math.abs(TrackUtils.getDoca(t2))<1)
+			return p2;
+		if(Math.abs(TrackUtils.getDoca(t2))>1 && Math.abs(TrackUtils.getDoca(t1))<1)
+			return p1;
+		
+		//if they are both ok, use the one with the track that extrapolates closes to the cluster.  
+		if(Math.hypot(FeeHistogramDriver.getDx(p1), FeeHistogramDriver.getDy(p1))
+				< Math.hypot(FeeHistogramDriver.getDx(p2), FeeHistogramDriver.getDy(p2)))
 			return p2;
 		return p1;
+		
+		
+		//if they are both ok, then just use whichever one has the smaller chi2
+		//if(p1.getTracks().get(0).getChi2() < p2.getTracks().get(0).getChi2())
+			//return p2;
+		//return p1;
+		
 	}
 	
 	
 	
 	
 	
-	static double angle(Hep3Vector v1, Hep3Vector v2){
-		return Math.acos(v1.x()*v2.x() + v1.y()*v2.y() + v1.z()*v2.z())
-			/(v1.magnitude()*v2.magnitude());
-	}
+	
 
 }

Modified: java/trunk/users/src/main/java/org/hps/users/spaul/fee/FeeHistogramDriver.java
 =============================================================================
--- java/trunk/users/src/main/java/org/hps/users/spaul/fee/FeeHistogramDriver.java	(original)
+++ java/trunk/users/src/main/java/org/hps/users/spaul/fee/FeeHistogramDriver.java	Thu Sep  1 04:26:03 2016
@@ -24,338 +24,399 @@
 
 
 public class FeeHistogramDriver extends Driver{
-	
+
 	double d0cut = 1;
 	double z0cut = .5;
-	
+
 	//determined by beam energy
-    double eMin, eMax, beamEnergy, seedEnergyCut;
-    double pMin, pMax;
-    
-
-    double beamTiltX = .0295;
-    double beamTiltY = -.0008;
-    
-    double maxChi2 = 50;
-    //maximum difference between the reconstructed energy and momentum
-    //double maxdE = .5;
-    int nMin = 3;
-
-    IHistogram1D theta;
-    IHistogram1D thetaInRange;
-    IHistogram2D thetaVsPhi;
-    IHistogram2D thetaVsPhiInRange;
-    IHistogram2D d0VsZ0, d0VsZ0_top, d0VsZ0_bottom;
-    IHistogram1D d0;
-    IHistogram1D z0;
-    IHistogram1D timeHist;
-    IHistogram1D chi2Hist;
-    
-    
-    @Override
-    public void detectorChanged(Detector det){
-        BeamEnergyCollection beamEnergyCollection = 
-            this.getConditionsManager().getCachedConditions(BeamEnergyCollection.class, "beam_energies").getCachedData();        
-        beamEnergy = beamEnergyCollection.get(0).getBeamEnergy();
-        eMin = .75*beamEnergy;
-        eMax = 1.15*beamEnergy;
-        
-        pMin = .75*beamEnergy;
-        pMax = 1.15*beamEnergy;
-        
-        seedEnergyCut = .38*beamEnergy; 
-        setupHistograms();
-        
-    }
-    
-    AIDA aida = AIDA.defaultInstance();
-
-
-    private IHistogram1D thetaTopOnly;
-
-
-    private IHistogram1D thetaTopOnlyInRange;
-
-
-    private IHistogram1D thetaBottomOnlyInRange;
-    
-    
-    private IHistogram1D energy, seedEnergy, energyTop, seedEnergyTop, energyBottom, seedEnergyBottom;
-    private IHistogram2D clusterVsSeedEnergy, clusterVsSeedEnergyTop, clusterVsSeedEnergyBottom;
-
-    private IHistogram1D thetaBottomOnly;
-    
-    private IHistogram1D charge;
-    
-    
-    void setupHistograms(){
-
-
-        energy = aida.histogram1D("cluster energy", 100, 0, 1.5*beamEnergy);
-        energyTop = aida.histogram1D("cluster energy top", 100, 0, 1.5*beamEnergy);
-        energyBottom = aida.histogram1D("cluster energy bottom", 100, 0, 1.5*beamEnergy);
-        
-        seedEnergy = aida.histogram1D("seed energy", 100, 0, beamEnergy);
-        seedEnergyTop = aida.histogram1D("seed energy top", 100, 0, beamEnergy);
-        seedEnergyBottom = aida.histogram1D("seed energy bottom", 100, 0, beamEnergy);
-        
-        clusterVsSeedEnergy = aida.histogram2D("cluster vs seed energy", 100, 0, 1.5*beamEnergy, 100, 0, beamEnergy);
-        clusterVsSeedEnergyTop = aida.histogram2D("cluster vs seed energy top", 100, 0, 1.5*beamEnergy, 100, 0, beamEnergy);
-        clusterVsSeedEnergyBottom = aida.histogram2D("cluster vs seed energy bottom", 100, 0, 1.5*beamEnergy, 100, 0, beamEnergy);
-        
-        
-        int nBinsPhi = 400;
-        thetaVsPhi = aida.histogram2D("theta vs phi", nBinsPhi, 0, .2, 628, -3.14, 3.14);
-        thetaVsPhiInRange = aida.histogram2D("theta vs phi in range", nBinsPhi, 0, .2, 628, -3.14, 3.14);
-        
-        theta = aida.histogram1D("theta", nBinsPhi, 0, .2);
-        thetaInRange = aida.histogram1D("theta in range", nBinsPhi, 0, .2);
-        
-        thetaTopOnly = aida.histogram1D("theta top", nBinsPhi, 0, .2);
-        thetaTopOnlyInRange = aida.histogram1D("theta top in range", nBinsPhi, 0, .2);
-        
-        thetaBottomOnly = aida.histogram1D("theta bottom", nBinsPhi, 0, .2);
-        thetaBottomOnlyInRange = aida.histogram1D("theta bottom in range", nBinsPhi, 0, .2);
-        uxVsUy = aida.histogram2D("ux vs uy", 300, -.16, .24, 300, -.2, .2);
-        uxVsUyInRange = aida.histogram2D("ux vs uy in range", 300, -.16, .24, 300, -.2, .2);
-        d0VsZ0 = aida.histogram2D("d0 vs z0", 100, -5, 5, 100, -5, 5);
-        d0 = aida.histogram1D("d0", 100, -5, 5);
-        z0 = aida.histogram1D("z0", 100, -5, 5);
-        
-        d0VsZ0_top = aida.histogram2D("d0 vs z0 top", 100, -5, 5, 100, -5, 5);
-        d0VsZ0_bottom = aida.histogram2D("d0 vs z0 bottom", 100, -5, 5, 100, -5, 5);
-        
-        
-        pHist = aida.histogram1D("momentum", 100, 0, 1.5*beamEnergy);
-        
-        charge = aida.histogram1D("charge", 6, -3, 3);
-        
-        
-        timeHist = aida.histogram1D("cluster time", 400, 0, 400);
-        chi2Hist = aida.histogram1D("chi2", 200, 0, 200);
-        clustSize = aida.histogram1D("cluster size", 20, 0, 20);
-        
-        z0VsTanLambda = aida.histogram2D("z0 vs tan lambda", 100, -5, 5, 100, -.1, .1);
-        z0VsChi2 = aida.histogram2D("z0 vs chi2", 100, -5, 5, 100, 0, 100);
-        
-    }
-    
-    
-    IHistogram2D uxVsUy, uxVsUyInRange;
-    
-    IHistogram1D pHist;
-    IHistogram1D clustSize;
-    
-    @Override
-    public void process(EventHeader event){
-    	
-    	
-    	
-    	//removed this criterion from this driver.
-    	//instead use a trigger filter driver preceding this driver in the steering file. 
-    	//
-    	
-        /*for (GenericObject gob : event.get(GenericObject.class,"TriggerBank"))
-        {
-            if (!(AbstractIntData.getTag(gob) == TIData.BANK_TAG)) continue;
-            TIData tid = new TIData(gob);
-            if (!tid.isSingle1Trigger())
-            {
-                return;
-            }
-        }*/
-        
-        List<ReconstructedParticle> particles = event.get(ReconstructedParticle.class, "FinalStateParticles");
-        Cleanup.purgeDuplicates(particles);
-        for(ReconstructedParticle p : particles){
-            processParticle(p);
-        }
-    }
-
-   
-	private void processParticle(ReconstructedParticle part) {
-        
-        //reject duplicate particles that use seed tracks instead of GBL
-        if(!TrackType.isGBL(part.getType()) && part.getTracks().size() >0)
-            return;
-        
-        //reject particles that have no cluster in the Ecal
-        if(part.getClusters().size() == 0)
-            return;
-        Cluster c = part.getClusters().get(0);
-        
-      //cluster time
-        double time = c.getCalorimeterHits().get(0).getTime();
-        timeHist.fill(time);
-        
-        if(!(time>minClustTime && time <maxClustTime))
-            return;
-        
-        
-        //find seed hit energy
-        double seedEnergy = 0;
-        for(CalorimeterHit hit : c.getCalorimeterHits()){
-            if(hit.getCorrectedEnergy() > seedEnergy)
-                seedEnergy = hit.getCorrectedEnergy();
-        }
-        double energy = c.getEnergy();
-        
-        
-        //these are the histograms of seed and cluster energy before
-        //the cuts on these variables 
-        this.seedEnergy.fill(seedEnergy);
-        this.energy.fill(energy);
-        this.clusterVsSeedEnergy.fill(energy, seedEnergy);
-        
-        if(part.getMomentum().y()> 0){
-            this.seedEnergyTop.fill(seedEnergy);
-            this.energyTop.fill(energy);
-            this.clusterVsSeedEnergyTop.fill(energy, seedEnergy);
-        } else {
-            this.seedEnergyBottom.fill(seedEnergy);
-            this.energyBottom.fill(energy);
-            this.clusterVsSeedEnergyBottom.fill(energy, seedEnergy);
-        }
-        
-        
-        //seed energy cut
-        if(seedEnergy < seedEnergyCut)
-            return;
-        
-        //cluster energy cut
-        if(energy > eMax || energy< eMin)
-            return;
-        
-        clustSize.fill(c.getCalorimeterHits().size());
-        if(c.getCalorimeterHits().size() < nMin)
-            return;
-        
-        
-        
-        charge.fill(part.getCharge());
-        if(part.getCharge() != -1)
-            return;
-        
-        if(part.getTracks().size() == 0)
-            return;
-        
-        
-        
-        
-
-        Hep3Vector p = part.getMomentum();
-
-        double pmag = part.getMomentum().magnitude();
-        pHist.fill(pmag);
-        if(pmag > pMax || pmag < pMin)
-            return;
-        
-        double d = TrackUtils.getDoca(part.getTracks().get(0));
-        d0.fill(d);
-        double z = TrackUtils.getZ0(part.getTracks().get(0));
-        z0.fill(z);
-        d0VsZ0.fill(d, z);
-        
-        if(p.y() > 0)
-        	d0VsZ0_top.fill(d,z);
-        else
-        	d0VsZ0_bottom.fill(d,z);
-        
-        z0VsTanLambda.fill(z, TrackUtils.getTanLambda(part.getTracks().get(0)));
-        z0VsChi2.fill(z, part.getTracks().get(0).getChi2());
-        
-        if(abs(TrackUtils.getDoca(part.getTracks().get(0)))> d0cut)
-        	return;
-        if(abs(TrackUtils.getZ0(part.getTracks().get(0)))> z0cut)
-        	return;
-        
-        
-        
-        chi2Hist.fill(part.getTracks().get(0).getChi2());
-        if(part.getTracks().get(0).getChi2()>maxChi2)
-            return;
-        
-
-
-/*
+	double eMin, eMax, beamEnergy, seedEnergyCut;
+	public double getSeedEnergyCutFrac() {
+		return seedEnergyCutFrac;
+	}
+
+	public void setSeedEnergyCutFrac(double seedEnergyCut) {
+		this.seedEnergyCutFrac = seedEnergyCut;
+	}
+
+	double pMin, pMax;
+
+
+	double beamTiltX = .0295;
+	double beamTiltY = -.0008;
+
+	double maxChi2 = 50;
+	//maximum difference between the reconstructed energy and momentum
+	//double maxdE = .5;
+	int nMin = 3;
+
+	IHistogram1D theta;
+	IHistogram1D thetaInRange;
+	IHistogram2D[] thetaVsPhi;
+	IHistogram2D[] thetaVsPhiNoTrackQualityCuts;
+	IHistogram2D[] thetaVsPhiInRange;
+	IHistogram2D d0VsZ0, d0VsZ0_top, d0VsZ0_bottom;
+	IHistogram1D d0;
+	IHistogram1D z0;
+	IHistogram1D timeHist;
+	IHistogram1D chi2Hist;
+	private double seedEnergyCutFrac = .38;
+
+
+	@Override
+	public void detectorChanged(Detector det){
+		BeamEnergyCollection beamEnergyCollection = 
+			this.getConditionsManager().getCachedConditions(BeamEnergyCollection.class, "beam_energies").getCachedData();        
+		beamEnergy = beamEnergyCollection.get(0).getBeamEnergy();
+		eMin = .75*beamEnergy;
+		eMax = 1.15*beamEnergy;
+
+		pMin = .75*beamEnergy;
+		pMax = 1.15*beamEnergy;
+
+		seedEnergyCut = seedEnergyCutFrac *beamEnergy; 
+		setupHistograms();
+
+	}
+
+	AIDA aida = AIDA.defaultInstance();
+
+
+	private IHistogram1D thetaTopOnly;
+
+
+	private IHistogram1D thetaTopOnlyInRange;
+
+
+	private IHistogram1D thetaBottomOnlyInRange;
+
+
+	private IHistogram1D energy, seedEnergy, energyTop, seedEnergyTop, energyBottom, seedEnergyBottom;
+	private IHistogram2D clusterVsSeedEnergy, clusterVsSeedEnergyTop, clusterVsSeedEnergyBottom;
+
+	private IHistogram1D thetaBottomOnly;
+
+	private IHistogram1D charge;
+	private IHistogram1D clustSizeGTP;
+
+
+	void setupHistograms(){
+
+
+		energy = aida.histogram1D("cluster energy", 100, 0, 1.5*beamEnergy);
+		energyTop = aida.histogram1D("cluster energy top", 100, 0, 1.5*beamEnergy);
+		energyBottom = aida.histogram1D("cluster energy bottom", 100, 0, 1.5*beamEnergy);
+
+		seedEnergy = aida.histogram1D("seed energy", 100, 0, beamEnergy);
+		seedEnergyTop = aida.histogram1D("seed energy top", 100, 0, beamEnergy);
+		seedEnergyBottom = aida.histogram1D("seed energy bottom", 100, 0, beamEnergy);
+
+		clusterVsSeedEnergy = aida.histogram2D("cluster vs seed energy", 100, 0, 1.5*beamEnergy, 100, 0, beamEnergy);
+		clusterVsSeedEnergyTop = aida.histogram2D("cluster vs seed energy top", 100, 0, 1.5*beamEnergy, 100, 0, beamEnergy);
+		clusterVsSeedEnergyBottom = aida.histogram2D("cluster vs seed energy bottom", 100, 0, 1.5*beamEnergy, 100, 0, beamEnergy);
+
+
+		int nBinsPhi = 400;
+		
+		String[] regionNames = {"", " r1", " r2", " r3", " r4"};
+		
+		thetaVsPhi = new IHistogram2D[regionNames.length];
+		thetaVsPhiInRange= new IHistogram2D[regionNames.length];
+		thetaVsPhiNoTrackQualityCuts = new IHistogram2D[regionNames.length];
+		thetaVsPhiChi2Cut= new IHistogram2D[regionNames.length];
+		thetaVsPhiTrackExtrapCut = new IHistogram2D[regionNames.length];
+		thetaVsPhiMomentumCut = new IHistogram2D[regionNames.length];		
+		for(int i = 0; i< regionNames.length; i++){
+			thetaVsPhi[i] = aida.histogram2D("theta vs phi" + regionNames[i], nBinsPhi, 0, .2, 628, -3.14, 3.14);
+			thetaVsPhiInRange[i] = aida.histogram2D("theta vs phi in range" + regionNames[i], nBinsPhi, 0, .2, 628, -3.14, 3.14);
+			thetaVsPhiNoTrackQualityCuts[i] = aida.histogram2D("theta vs phi no track quality cuts" + regionNames[i], nBinsPhi, 0, .2, 628, -3.14, 3.14);
+			thetaVsPhiChi2Cut[i] = aida.histogram2D("theta vs phi chi2 cut" + regionNames[i], nBinsPhi, 0, .2, 628, -3.14, 3.14);
+			thetaVsPhiTrackExtrapCut[i] = aida.histogram2D("theta vs phi track extrap cut" + regionNames[i], nBinsPhi, 0, .2, 628, -3.14, 3.14);
+			thetaVsPhiMomentumCut[i] = aida.histogram2D("theta vs phi chi2 momentum cut" + regionNames[i], nBinsPhi, 0, .2, 628, -3.14, 3.14);
+		}
+		theta = aida.histogram1D("theta", nBinsPhi, 0, .2);
+		thetaInRange = aida.histogram1D("theta in range", nBinsPhi, 0, .2);
+
+		thetaTopOnly = aida.histogram1D("theta top", nBinsPhi, 0, .2);
+		thetaTopOnlyInRange = aida.histogram1D("theta top in range", nBinsPhi, 0, .2);
+
+		thetaBottomOnly = aida.histogram1D("theta bottom", nBinsPhi, 0, .2);
+		thetaBottomOnlyInRange = aida.histogram1D("theta bottom in range", nBinsPhi, 0, .2);
+		uxVsUy = aida.histogram2D("ux vs uy", 300, -.16, .24, 300, -.2, .2);
+		uxVsUyInRange = aida.histogram2D("ux vs uy in range", 300, -.16, .24, 300, -.2, .2);
+		d0VsZ0 = aida.histogram2D("d0 vs z0", 100, -5, 5, 100, -5, 5);
+		d0 = aida.histogram1D("d0", 100, -5, 5);
+		z0 = aida.histogram1D("z0", 100, -5, 5);
+
+		d0VsZ0_top = aida.histogram2D("d0 vs z0 top", 100, -5, 5, 100, -5, 5);
+		d0VsZ0_bottom = aida.histogram2D("d0 vs z0 bottom", 100, -5, 5, 100, -5, 5);
+
+
+		pHist = aida.histogram1D("momentum", 100, 0, 1.5*beamEnergy);
+
+		charge = aida.histogram1D("charge", 6, -3, 3);
+
+
+		timeHist = aida.histogram1D("cluster time", 400, 0, 400);
+		chi2Hist = aida.histogram1D("chi2", 200, 0, 200);
+		chi2RedHist = aida.histogram1D("chi2 red", 200, 0, 40);
+		clustSize = aida.histogram1D("cluster size", 20, 0, 20);
+		clustSizeGTP = aida.histogram1D("cluster size gtp (>55% beam energy)", 20, 0, 20);
+
+		z0VsTanLambda = aida.histogram2D("z0 vs tan lambda", 100, -5, 5, 100, -.1, .1);
+		z0VsChi2 = aida.histogram2D("z0 vs chi2", 100, -5, 5, 100, 0, 100);
+		nPassCutsPerEvent = aida.histogram1D("n pass cuts", 10, 0, 10);
+		nPassCutsPerEventFiducial = aida.histogram1D("n pass cuts fiducial", 10, 0, 10);
+		thetaVsMomentum = aida.histogram2D("theta vs energy", 100, 0, .2, 100, 0, 1.2*beamEnergy);
+		thetaVsMomentumFid = aida.histogram2D("theta vs energy fiducial", 100, 0, .2, 100, 0, 1.2*beamEnergy);
+	}
+
+
+	IHistogram2D uxVsUy, uxVsUyInRange;
+
+	IHistogram1D pHist;
+	IHistogram1D clustSize;
+
+	IHistogram1D nPassCutsPerEvent;
+	IHistogram1D nPassCutsPerEventFiducial;
+	private IHistogram1D chi2RedHist;
+	private IHistogram2D thetaVsPhiChi2Cut[];
+	private IHistogram2D thetaVsPhiMomentumCut[];
+	private IHistogram2D thetaVsPhiTrackExtrapCut[];
+	@Override
+	public void process(EventHeader event){
+		
+		fillHistogramsGTP(event);
+		
+		//int col = getColumn(event);
+
+		List<ReconstructedParticle> particles = event.get(ReconstructedParticle.class, "FinalStateParticles");
+		Cleanup.purgeParticlesWithSameCluster(particles);
+		int nPassFidCuts = 0, nPassCuts = 0;
+		for(ReconstructedParticle part : particles){
+
+			
+			//reject duplicate particles that use seed tracks instead of GBL
+			if(!TrackType.isGBL(part.getType()) && part.getTracks().size() >0)
+				continue;
+
+			//reject particles that have no cluster in the Ecal
+			if(part.getClusters().size() == 0)
+				continue;
+			Cluster c = part.getClusters().get(0);
+
+			//cluster time
+			double time = c.getCalorimeterHits().get(0).getTime();
+			timeHist.fill(time);
+
+			if(!(time>minClustTime && time <maxClustTime))
+				continue;
+
+
+			//find seed hit energy
+			double seedEnergy = 0;
+			int col = 0;
+			for(CalorimeterHit hit : c.getCalorimeterHits()){
+				if(hit.getCorrectedEnergy() > seedEnergy){
+					seedEnergy = hit.getCorrectedEnergy();
+					col = hit.getIdentifierFieldValue("ix");
+				}
+			}
+			double energy = c.getEnergy();
+
+
+			//these are the histograms of seed and cluster energy before
+			//the cuts on these variables 
+			this.seedEnergy.fill(seedEnergy);
+			this.energy.fill(energy);
+			this.clusterVsSeedEnergy.fill(energy, seedEnergy);
+
+			if(part.getMomentum().y()> 0){
+				this.seedEnergyTop.fill(seedEnergy);
+				this.energyTop.fill(energy);
+				this.clusterVsSeedEnergyTop.fill(energy, seedEnergy);
+			} else {
+				this.seedEnergyBottom.fill(seedEnergy);
+				this.energyBottom.fill(energy);
+				this.clusterVsSeedEnergyBottom.fill(energy, seedEnergy);
+			}
+
+
+			//seed energy cut
+			if(seedEnergy < seedEnergyCut)
+				continue;
+
+			//cluster energy cut
+			if(energy > eMax || energy< eMin)
+				continue;
+
+			clustSize.fill(c.getCalorimeterHits().size());
+			if(c.getCalorimeterHits().size() < nMin)
+				continue;
+
+
+
+			charge.fill(part.getCharge());
+			if(part.getCharge() != -1)
+				continue;
+
+			if(part.getTracks().size() == 0)
+				continue;
+
+
+			Hep3Vector p = part.getMomentum();
+			double px = p.x(), py = p.y(), pz = p.z();
+
+			double cx = cos(beamTiltX);
+			double sy = sin(beamTiltY);
+			double cy = cos(beamTiltY);
+			double sx = sin(beamTiltX);
+
+			double pxtilt = px*cx              -pz*sx;
+			double pytilt = -py*sx*sy + py*cy  -pz*sy*cx;
+			double pztilt = px*cy*sx  + py*sy  +pz*cy*cx;
+
+
+			double theta = atan(hypot(pxtilt, pytilt)/pztilt);
+			double phi =atan2(pytilt, pxtilt);
+			fill(thetaVsPhiNoTrackQualityCuts,theta, phi, col);
+
+			if(abs(getDx(part))>trackExtrapCut || abs(getDy(part))> trackExtrapCut)
+				continue;
+			fill(thetaVsPhiTrackExtrapCut, theta, phi, col);
+			
+			chi2Hist.fill(part.getTracks().get(0).getChi2());
+			chi2RedHist.fill(part.getTracks().get(0).getChi2()/(2*part.getTracks().get(0).getTrackerHits().size()-5));
+
+			if(part.getTracks().get(0).getChi2()>maxChi2)
+				continue;
+			fill(thetaVsPhiChi2Cut, theta, phi, col);
+			
+			double pmag = part.getMomentum().magnitude();
+			pHist.fill(pmag);
+			if(pmag > pMax || pmag < pMin)
+				continue;
+			fill(thetaVsPhiMomentumCut, theta, phi, col);
+
+			double d = TrackUtils.getDoca(part.getTracks().get(0));
+			d0.fill(d);
+			double z = TrackUtils.getZ0(part.getTracks().get(0));
+			z0.fill(z);
+			d0VsZ0.fill(d, z);
+
+			if(p.y() > 0)
+				d0VsZ0_top.fill(d,z);
+			else
+				d0VsZ0_bottom.fill(d,z);
+
+			z0VsTanLambda.fill(z, TrackUtils.getTanLambda(part.getTracks().get(0)));
+			z0VsChi2.fill(z, part.getTracks().get(0).getChi2());
+
+			if(abs(TrackUtils.getDoca(part.getTracks().get(0)))> d0cut)
+				continue;
+			if(abs(TrackUtils.getZ0(part.getTracks().get(0)))> z0cut)
+				continue;
+
+
+
+			
+
+
+
+			/*
         double px = p.x(), pz = p.z();
         double pxtilt = px*cos(beamTiltX)-pz*sin(beamTiltX);
         double py = p.y();
         double pztilt = pz*cos(beamTiltX)+px*sin(beamTiltX);
-        
+
         double pytilt = py*cos(beamTiltY)-pztilt*sin(beamTiltY);
         pztilt = pz*cos(beamTiltY) + pytilt*sin(beamTiltY);
-*/
-        double px = p.x(), py = p.y(), pz = p.z();
-        
-        double cx = cos(beamTiltX);
-        double sy = sin(beamTiltY);
-        double cy = cos(beamTiltY);
-        double sx = sin(beamTiltX);
-        
-        double pxtilt = px*cx              -pz*sx;
-        double pytilt = -py*sx*sy + py*cy  -pz*sy*cx;
-        double pztilt = px*cy*sx  + py*sy  +pz*cy*cx;
-        
-
-        double theta = atan(hypot(pxtilt, pytilt)/pztilt);
-        double phi =atan2(pytilt, pxtilt);
-        
-        uxVsUy.fill(pxtilt/pztilt, pytilt/pztilt);
-        thetaVsPhi.fill(theta, phi);
-        this.theta.fill(theta);
-        if(phi > 0)
-            thetaTopOnly.fill(theta);
-        else
-            thetaBottomOnly.fill(theta);
-        if(cb.inRange(theta, phi)){
-            thetaVsPhiInRange.fill(theta, phi);
-            thetaInRange.fill(theta);
-            if(phi > 0)
-                thetaTopOnlyInRange.fill(theta);
-            else
-                thetaBottomOnlyInRange.fill(theta);
-            uxVsUyInRange.fill(pxtilt/pztilt, pytilt/pztilt);
-        }
-    }
-    
-    public void setBinning(String binning){
-        System.out.println("binning scheme:\n" + binning);
-        this.cb = new CustomBinning(binning);
-    }
-    /*
-    @Override
-    protected void endOfData(){
-        createRenormalizationHistogram();
-    }
-    
-    private void createRenormalizationHistogram(){
-    	
-        //the purpose of this histogram is so that there is a simple histogram
-        //that each bin in the theta histograms can be normalized to the 
-        //angular range in phi that I am using for the cut inside of that theta bin.
-        
-        int xbins = thetaVsPhi.xAxis().bins();
-        double xmin = thetaVsPhi.xAxis().lowerEdge();
-        double xmax = thetaVsPhi.xAxis().upperEdge();
-        double ymin = thetaVsPhi.xAxis().lowerEdge();
-        double ymax = thetaVsPhi.xAxis().upperEdge();
-        
-        IHistogram1D phiHist = aida.histogram1D("phiWidth", xbins, xmin, xmax);
-
-        for(int i = 0; i< cb.nTheta; i++){
-            double phiWidth = cb.getPhiWidth(i);
-            for(int j = 0; j<phiWidth*1000; j++){
-                phiHist.fill(cb.thetaMin[i]+.001);
-            }
-        }
-
-        
-    }*/
-    
-    CustomBinning cb;
-    double minClustTime = 40;
-    double maxClustTime = 50;
+			 */
+			
+
+			uxVsUy.fill(pxtilt/pztilt, pytilt/pztilt);
+			fill(thetaVsPhi, theta, phi, col);
+			this.theta.fill(theta);
+			if(phi > 0)
+				thetaTopOnly.fill(theta);
+			else
+				thetaBottomOnly.fill(theta);
+			nPassCuts++;
+			thetaVsMomentum.fill(theta, pz);
+			if(cb.inRange(theta, phi)){
+				fill(thetaVsPhiInRange, theta, phi, col);
+				thetaInRange.fill(theta);
+				if(phi > 0)
+					thetaTopOnlyInRange.fill(theta);
+				else
+					thetaBottomOnlyInRange.fill(theta);
+				uxVsUyInRange.fill(pxtilt/pztilt, pytilt/pztilt);
+				nPassFidCuts++;
+				thetaVsMomentumFid.fill(theta, pz);
+			}
+		}
+		nPassCutsPerEvent.fill(nPassCuts);
+		nPassCutsPerEventFiducial.fill(nPassFidCuts);
+	}
+	//returns the column of the seed hit of the trigger cluster in the GTP
+	/*private int getColumn(EventHeader event) {
+	    for (GenericObject gob : event.get(GenericObject.class,"TriggerBank"))
+	    {
+	      if (!(AbstractIntData.getTag(gob) == TIData.BANK_TAG)) continue;
+	      TIData tid = new TIData(gob);
+	      
+	    }
+		
+		
+		List<Cluster> l = event.get(Cluster.class, "EcalClusters");
+		double maxClusterEnergy = 0;
+		int col = 0;
+		for(Cluster c : l){
+			if(c.getEnergy()>maxClusterEnergy){
+				maxClusterEnergy = c.getEnergy();
+				double maxHitEnergy = 0;
+				for(CalorimeterHit hit : c.getCalorimeterHits()){
+					if(hit.getCorrectedEnergy() > maxHitEnergy){
+						col = hit.getIdentifierFieldValue("ix");
+						maxHitEnergy = hit.getCorrectedEnergy();
+					}
+				}
+			}
+		}
+		
+		return col;
+	}*/
+
+	private void fill(IHistogram2D[] thetaVsPhiHist, double theta,
+			double phi, int col) {
+		thetaVsPhiHist[0].fill(theta, phi);
+		if(col <= -13 || col>=6)
+			thetaVsPhiHist[1].fill(theta, phi);
+		else if (col <= -9 || col >= 2)
+			thetaVsPhiHist[2].fill(theta, phi);
+		else if (col <= -7 || col >= -2)
+			thetaVsPhiHist[3].fill(theta, phi);
+		else 
+			thetaVsPhiHist[4].fill(theta, phi);
+		
+	}
+
+	private void fillHistogramsGTP(EventHeader event) {
+		if(event.hasCollection(Cluster.class, "EcalClusters"))
+		for(Cluster c : event.get(Cluster.class, "EcalClusters")){
+			double energy = c.getEnergy();
+			if(energy>beamEnergy*.55)
+				clustSizeGTP.fill(c.getSize());
+		}
+	}
+
+	public void setBinning(String binning){
+		System.out.println("binning scheme:\n" + binning);
+		this.cb = new CustomBinning(binning);
+	}
+	
+	CustomBinning cb;
+	double minClustTime = 40;
+	double maxClustTime = 50;
 
 
 	public double getMinClustTime() {
@@ -379,8 +440,22 @@
 	public void setMaxClustTime(double maxClustTime) {
 		this.maxClustTime = maxClustTime;
 	}
-    
+
 	IHistogram2D z0VsTanLambda;
 	IHistogram2D z0VsChi2;
+	IHistogram2D thetaVsMomentumFid;
+	IHistogram2D thetaVsMomentum;
 	
+	public double trackExtrapCut = 10;
+	public static double getDx(ReconstructedParticle p){
+		double xc = p.getClusters().get(0).getPosition()[0];
+		double xt = TrackUtils.getTrackPositionAtEcal(p.getTracks().get(0)).x();
+		return xt-xc;
+	}
+
+	public static double getDy(ReconstructedParticle p) {
+		double yc = p.getClusters().get(0).getPosition()[1];
+		double yt = TrackUtils.getTrackPositionAtEcal(p.getTracks().get(0)).y();
+		return yt-yc;
+	}
 }

Modified: java/trunk/users/src/main/java/org/hps/users/spaul/moller/MollerBeamtiltAnalysis.java
 =============================================================================
--- java/trunk/users/src/main/java/org/hps/users/spaul/moller/MollerBeamtiltAnalysis.java	(original)
+++ java/trunk/users/src/main/java/org/hps/users/spaul/moller/MollerBeamtiltAnalysis.java	Thu Sep  1 04:26:03 2016
@@ -1,14 +1,18 @@
 package org.hps.users.spaul.moller;
+
+import static java.lang.Math.atan;
+import static java.lang.Math.atan2;
+import static java.lang.Math.cos;
+import static java.lang.Math.hypot;
+import static java.lang.Math.sin;
 
 import java.util.List;
 
 import hep.aida.IHistogram1D;
 import hep.aida.IHistogram2D;
-import hep.aida.IPlotter;
-import hep.aida.IProfile1D;
+import hep.physics.vec.Hep3Vector;
 
 import org.hps.recon.tracking.TrackType;
-import org.hps.users.spaul.StyleUtil;
 import org.lcsim.event.EventHeader;
 import org.lcsim.event.ReconstructedParticle;
 import org.lcsim.event.Vertex;
@@ -28,9 +32,12 @@
     public void process(EventHeader event){
         for(int i = 0; i< mollerCollections.length; i++){
             List<Vertex> mollers = event.get(Vertex.class, mollerCollections[i]);
+            Cleanup.purgeDuplicates(mollers);
+            int nPassCuts = 0;
             for(Vertex v : mollers){
-                if(!passesCuts(v))
+                if(!passesBradleysCuts(v))
                     continue;
+                nPassCuts ++;
                 ReconstructedParticle m = v.getAssociatedParticle();
                 ReconstructedParticle top;
                 ReconstructedParticle bottom;
@@ -55,75 +62,81 @@
                 double sum = m.getMomentum().z();//top.getMomentum().z()+bottom.getMomentum().z();
                 double mass = m.getMass();
 
-                if(diff > -.05 && diff < .05){
-                    hpypz_mid[i].fill(pypz);
-                    hpxpz_mid[i].fill(pxpz);
-                }
-
-                if(diff > .2 && diff < .3){
-                    hpypz_topHighE[i].fill(pypz);
-                    hpxpz_topHighE[i].fill(pxpz);
-                }
-
-                if(diff > -.3 && diff < -.2){
-                    hpypz_botHighE[i].fill(pypz);
-                    hpxpz_botHighE[i].fill(pxpz);
-                }
+               
 
 
                 this.diff[i].fill(diff);
                 this.sum[i].fill(sum);
                 this.mass[i].fill(mass);
-                pypz_vs_diff[i].fill(diff,pypz );
-                pxpz_vs_diff[i].fill(diff, pxpz );
-
-
-
-                pxpz_vs_sum[i].fill(sum, pxpz );
-                pypz_vs_sum[i].fill(sum, pypz );
-
-                pxpz_vs_mass[i].fill(mass, pxpz );
-                pypz_vs_mass[i].fill(mass, pypz );
-                timediff[i].fill(top.getClusters().get(0).getCalorimeterHits().get(0).getTime()
+                pypz_vs_diff[i].fill(pypz, diff );
+                pxpz_vs_diff[i].fill(pxpz, diff );
+
+
+
+                pxpz_vs_sum[i].fill(pxpz, sum );
+                pypz_vs_sum[i].fill(pypz, sum );
+
+                pxpz_vs_mass[i].fill(pxpz, mass);
+                pypz_vs_mass[i].fill(pypz, mass);
+                //only do this if both tracks have associated clusters:
+                if(top.getClusters().size()*bottom.getClusters().size()>0){
+                	timediff[i].fill(top.getClusters().get(0).getCalorimeterHits().get(0).getTime()
                         -bottom.getClusters().get(0).getCalorimeterHits().get(0).getTime());
-                
-                
-                double theta, phi;
-                double pxpz_top = top.getMomentum().x()/top.getMomentum().z();
-                double pypz_top = top.getMomentum().y()/top.getMomentum().z();
-                
-                theta = Math.hypot(pypz_top-(-.0008), pxpz_top-.0295);
-                phi = Math.atan2(pypz_top-(-.0008), pxpz_top-.0295);
-                thetaPhi[i].fill(theta, phi);
-                
-                double pxpz_bot = bottom.getMomentum().x()/bottom.getMomentum().z();
-                double pypz_bot = bottom.getMomentum().y()/bottom.getMomentum().z();
-                
-                theta = Math.hypot(pypz_bot-(-.0008), pxpz_bot-.0295);
-                phi = Math.atan2(pypz_bot-(-.0008), pxpz_bot-.0295);
-                thetaPhi[i].fill(theta, phi);
-                
-                /*if(moreEnergetic.getMomentum().y() > 0)
-            {
-                pypz_tophighE.fill(pypz);
-                pxpz_tophighE.fill(pxpz);
+                	meanClusterTime[i].fill((top.getClusters().get(0).getCalorimeterHits().get(0).getTime()
+                            +bottom.getClusters().get(0).getCalorimeterHits().get(0).getTime())/2.);
+                }
+                
+                double [] res = getThetaAndPhi(top.getMomentum());
+                double theta1 = res[0];
+                double phi1 = res[1];
+                thetaPhi[i].fill(theta1, phi1);
+                
+                res = getThetaAndPhi(bottom.getMomentum());
+                double theta2 = res[0];
+                double phi2 = res[1];
+                thetaPhi[i].fill(theta2, phi2);
+                
+                vtxchi2[i].fill(v.getChi2());
+                trkchi2[i].fill(top.getTracks().get(0).getChi2());
+                trkchi2[i].fill(bottom.getTracks().get(0).getChi2());
+                
+                vtx_xy[i].fill(v.getPosition().x(), v.getPosition().y());
+                
+                double dPhi = phi1-phi2 + Math.PI;
+                while(dPhi > Math.PI)
+                	dPhi-= 2*Math.PI;
+                while(dPhi< -Math.PI)
+                	dPhi += 2*Math.PI;
+                dphi[i].fill(dPhi*180/Math.PI);
+                dphi_vs_dtheta[i].fill(dPhi*180/Math.PI, theta1-theta2);
+                
+                theta_theta[i].fill(sin(theta1/2)*sin(theta2/2));
+                
             }
-            if(moreEnergetic.getMomentum().y() < 0)
-            {
-                pypz_bottomhighE.fill(pypz);
-                pxpz_bottomhighE.fill(pxpz);
-            }*/
-            }
+            this.nPassCuts[i].fill(nPassCuts);
         }
     }
 
-    private double _maxVtxChi2 = 15;
-    private double _maxTrkChi2 = 30;
+    //private double _maxVtxChi2 = 15;
+    //private double _maxTrkChi2 = 30;
+    private double _maxVtxChi2 = 30;
+    private double _maxTrkChi2 = 50;
     private double _maxMass = .037;
     private double _minMass = .030;
     private double _minPz = 1.0;
     private double _maxPz = 1.1;
-    private boolean passesCuts(Vertex vertex){
+    private double _maxTrkPz = .8;
+    public double get_maxTrkPz() {
+		return _maxTrkPz;
+	}
+
+
+	public void set_maxTrkPz(double _maxTrkPz) {
+		this._maxTrkPz = _maxTrkPz;
+	}
+
+
+	private boolean passesCuts(Vertex vertex){
         ReconstructedParticle m = vertex.getAssociatedParticle();
         if(!TrackType.isGBL(m.getType()))
             return false;
@@ -132,6 +145,7 @@
         if(m.getMass() > _maxMass || m.getMass() < _minMass)
             return false;
 
+        
         if(m.getParticles().get(0).getCharge() != -1 
                 || m.getParticles().get(1).getCharge() != -1 )
             return false;
@@ -149,15 +163,61 @@
             return false;
         if(m.getParticles().get(1).getTracks().get(0).getChi2() > _maxTrkChi2)
             return false;
+        
+        if(m.getParticles().get(0).getMomentum().z()>_maxTrkPz )
+        	return false;
+        if(m.getParticles().get(1).getMomentum().z()>_maxTrkPz )
+        	return false;
+        
+        //very loose cut around the nominal beam direction
+        if(Math.abs(m.getMomentum().x()/m.getMomentum().z()-.030)> .01)
+        	return false;
+        if(Math.abs(m.getMomentum().y()/m.getMomentum().z()-.000)> .01)
+        	return false;
+        
         return true;
     }
-
-    private IHistogram1D hpypz[], hpxpz[], diff[], sum[], mass[],
-        hpypz_topHighE[], hpxpz_topHighE[],
-        hpypz_botHighE[], hpxpz_botHighE[],
-        hpypz_mid[], hpxpz_mid[];
-
-    private IHistogram2D[] thetaPhi;
+	
+	private boolean passesBradleysCuts(Vertex vertex){
+		ReconstructedParticle m = vertex.getAssociatedParticle();
+        if(!TrackType.isGBL(m.getType()))
+            return false;
+        if(m.getMomentum().z() < .95 || m.getMomentum().z() > 1.15)
+            return false;
+        
+        //both particles must have clusters
+        if(m.getParticles().get(0).getClusters().size()==0 || m.getParticles().get(1).getClusters().size()==0)
+        	return false;
+        
+        
+        ReconstructedParticle p1 = m.getParticles().get(0);
+        ReconstructedParticle p2 = m.getParticles().get(1);
+        
+        //timing difference cut (2 ns)
+        if(Math.abs(p1.getClusters().get(0).getCalorimeterHits().get(0).getTime()-
+        		p2.getClusters().get(0).getCalorimeterHits().get(0).getTime())>2)
+        	return false;
+        
+        
+        double phi1 = getThetaAndPhi(p1.getMomentum())[1];
+        double phi2 = getThetaAndPhi(p2.getMomentum())[1];
+        
+        double dPhi = phi1-phi2 + Math.PI;
+        while(dPhi>Math.PI)
+        	dPhi-= 2*Math.PI;
+        while(dPhi<-Math.PI)
+        	dPhi+= 2*Math.PI;
+        
+        if(Math.abs(dPhi)>.35) //about 20 degrees
+        	return false;
+		return true;
+	}
+
+    private IHistogram1D hpypz[], hpxpz[], diff[], sum[], mass[], trkchi2[], vtxchi2[], dphi[];
+
+    private IHistogram2D[] thetaPhi, dphi_vs_dtheta;
+    
+    private IHistogram1D[] meanClusterTime;
     
     public double getMaxVtxChi2() {
         return _maxVtxChi2;
@@ -172,6 +232,8 @@
     public double getMaxTrkChi2() {
         return _maxTrkChi2;
     }
+    
+   
 
 
     public void setMaxTrkChi2(double _maxTrkChi2) {
@@ -219,9 +281,12 @@
     }
 
 
-    private IHistogram1D vtx_x[], vtx_y[], timediff[];
-
-    private IProfile1D pxpz_vs_diff[], pypz_vs_diff[], pxpz_vs_sum[], pypz_vs_sum[],
+    private IHistogram2D vtx_xy[];
+    private IHistogram1D timediff[];
+    private IHistogram1D nPassCuts[], theta_theta[];
+    
+
+    private IHistogram2D pxpz_vs_diff[], pypz_vs_diff[], pxpz_vs_sum[], pypz_vs_sum[],
     pxpz_vs_mass[], pypz_vs_mass[];
 
 
@@ -237,31 +302,36 @@
         
         hpypz = new IHistogram1D[3];
         hpxpz = new IHistogram1D[3];
-        hpypz_mid = new IHistogram1D[3];
-        hpxpz_mid = new IHistogram1D[3];
-        hpypz_topHighE = new IHistogram1D[3];
-        hpxpz_topHighE = new IHistogram1D[3];
-        hpypz_botHighE = new IHistogram1D[3];
-        hpxpz_botHighE = new IHistogram1D[3];
-        
-        
-        pxpz_vs_diff= new IProfile1D[3];
-        pypz_vs_diff= new IProfile1D[3];
+        
+        
+        pxpz_vs_diff= new IHistogram2D[3];
+        pypz_vs_diff= new IHistogram2D[3];
 
         diff= new IHistogram1D[3];
 
         sum= new IHistogram1D[3];
 
-        pxpz_vs_sum= new IProfile1D[3];
-        pypz_vs_sum= new IProfile1D[3];
-
-        pxpz_vs_mass= new IProfile1D[3];
-        pypz_vs_mass= new IProfile1D[3];
+        pxpz_vs_sum= new IHistogram2D[3];
+        pypz_vs_sum= new IHistogram2D[3];
+
+        pxpz_vs_mass= new IHistogram2D[3];
+        pypz_vs_mass= new IHistogram2D[3];
 
         //vtx_x= new IHistogram1D[3];
         //vtx_y= new IHistogram1D[3];
         mass= new IHistogram1D[3];
         timediff= new IHistogram1D[3];
+        nPassCuts = new IHistogram1D[3];
+        vtx_xy = new IHistogram2D[3];
+        trkchi2 = new IHistogram1D[3];
+        vtxchi2 = new IHistogram1D[3];
+        meanClusterTime = new IHistogram1D[3];
+        
+        dphi = new IHistogram1D[3];
+        
+        theta_theta = new IHistogram1D[3];
+        
+        dphi_vs_dtheta = new IHistogram2D[3];
         
         for(int i = 0; i< 3; i++){
         	
@@ -270,94 +340,57 @@
             hpypz[i] = aida.histogram1D(mollerCollections[i]+"/"+"pypz", 60, -.005,.005);
             hpxpz[i] = aida.histogram1D(mollerCollections[i]+"/"+"pxpz", 60, .025,.035);
 
-
-            hpypz_mid[i] = aida.histogram1D(mollerCollections[i]+"/"+"pypz mid", 60, -.005,.005);
-            hpxpz_mid[i] = aida.histogram1D(mollerCollections[i]+"/"+"pxpz mid", 60, .025,.035);
-
-            hpypz_topHighE[i] = aida.histogram1D(mollerCollections[i]+"/"+"pypz top", 30, -.005,.005);
-            hpxpz_topHighE[i] = aida.histogram1D(mollerCollections[i]+"/"+"pxpz top", 30, .025,.035);
-
-            hpypz_botHighE[i] = aida.histogram1D(mollerCollections[i]+"/"+"pypz bot", 30, -.005,.005);
-            hpxpz_botHighE[i] = aida.histogram1D(mollerCollections[i]+"/"+"pxpz bot", 30, .025,.035);
-
-
-            pxpz_vs_diff[i] = aida.profile1D(mollerCollections[i]+"/"+"pxpz vs diff", 25, -.60, .60);
-            pypz_vs_diff[i] = aida.profile1D(mollerCollections[i]+"/"+"pypz vs diff", 25, -.60, .60);
+            pxpz_vs_diff[i] = aida.histogram2D(mollerCollections[i]+"/"+"pxpz vs diff", 50, .025, .035, 50, -.60, .60);
+            pypz_vs_diff[i] = aida.histogram2D(mollerCollections[i]+"/"+"pypz vs diff", 50, -.005, .005, 50, -.60, .60);
 
             diff[i] = aida.histogram1D(mollerCollections[i]+"/"+"diff", 50, -.60, .60);
 
-            sum[i] = aida.histogram1D(mollerCollections[i]+"/"+"sum", 50, 1.0, 1.1);
-
-            pxpz_vs_sum[i] = aida.profile1D(mollerCollections[i]+"/"+"pxpz vs sum", 25, 1.0, 1.1);
-            pypz_vs_sum[i] = aida.profile1D(mollerCollections[i]+"/"+"pypz vs sum", 25, 1.0, 1.1);
-
-            pxpz_vs_mass[i] = aida.profile1D(mollerCollections[i]+"/"+"pxpz vs mass", 25, .03, .037);
-            pypz_vs_mass[i] = aida.profile1D(mollerCollections[i]+"/"+"pypz vs mass", 25, .03, .037);
-
-            //vtx_x[i] = aida.histogram1D(mollerCollections[i]+"/"+"vtx x", 60, -1, 1);
-            //vtx_y[i] = aida.histogram1D(mollerCollections[i]+"/"+"vtx y", 60, -1, 1);
-            mass[i] = aida.histogram1D(mollerCollections[i]+"/"+"mass", 60, .030, .037);
+            sum[i] = aida.histogram1D(mollerCollections[i]+"/"+"sum", 50, .95, 1.15);
+
+            pxpz_vs_sum[i] = aida.histogram2D(mollerCollections[i]+"/"+"pxpz vs sum", 50, .025, .035, 50, .95, 1.15);
+            pypz_vs_sum[i] = aida.histogram2D(mollerCollections[i]+"/"+"pypz vs sum", 50, -.005, .005, 50, .95, 1.15);
+
+            pxpz_vs_mass[i] = aida.histogram2D(mollerCollections[i]+"/"+"pxpz vs mass", 50, .025, .035, 50,.03, .037);
+            pypz_vs_mass[i] = aida.histogram2D(mollerCollections[i]+"/"+"pypz vs mass", 50, -.005, .005, 50, .03, .037);
+
+            vtx_xy[i] = aida.histogram2D(mollerCollections[i]+"/"+"vtx xy", 50, -5, 5, 50, -5, 5);
+            
+            mass[i] = aida.histogram1D(mollerCollections[i]+"/"+"mass", 300, 0, .060);
             timediff[i] = aida.histogram1D(mollerCollections[i]+"/"+"time diff", 60, -6, 6);
+            
+            trkchi2[i] = aida.histogram1D(mollerCollections[i]+"/"+"trk chi2", 100, 0, 100);
+            vtxchi2[i] = aida.histogram1D(mollerCollections[i]+"/"+"vtx chi2", 100, 0, 100);
+            
+            nPassCuts[i] = aida.histogram1D(mollerCollections[i]+"/"+"moller events pass cut per event", 20, 0, 20);
+            meanClusterTime[i] = aida.histogram1D(mollerCollections[i]+"/"+"mean cluster time", 200, 0, 200);
+            
+            dphi[i] = aida.histogram1D(mollerCollections[i]+"/"+"dphi (degrees)", 90, -180, 180);
+            theta_theta[i] = aida.histogram1D(mollerCollections[i]+"/"+"sin(theta1_2)sin(theta2_2)", 100, 0, .002);
+            dphi_vs_dtheta[i] = aida.histogram2D(mollerCollections[i]+"/"+"dphi vs dtheta", 180, -180, 180, 100, 0, .05);
         }
 
-        /*pypz_tophighE = aida.histogram1D("topHighE pypz", 60, -.005,.005);
-        pxpz_tophighE = aida.histogram1D("topHighE pxpz", 60,  .025,.035);
-        pypz_bottomhighE = aida.histogram1D("bottomHighE pypz", 60, -.005,.005);
-        pxpz_bottomhighE = aida.histogram1D("bottomHighE pxpz", 60, .025,.035);*/
-        /*if(display){
-            IPlotter p = aida.analysisFactory().createPlotterFactory().create();
-            StyleUtil.setSize(p, 1300, 900);
-            //p.createRegions(3, 2);
-            p.createRegions(4, 3);
-
-            p.region(0).plot(hpypz);
-            p.region(1).plot(hpxpz);
-            p.region(2).plot(timediff);
-            p.region(3).plot(pypz_vs_diff);
-            p.region(4).plot(pxpz_vs_diff);
-            p.region(5).plot(diff);
-            p.region(6).plot(pypz_vs_sum);
-            p.region(7).plot(pxpz_vs_sum);
-            p.region(8).plot(sum);
-
-            p.region(9).plot(pypz_vs_mass);
-            p.region(10).plot(pxpz_vs_mass);
-            p.region(11).plot(mass);
-            StyleUtil.stylize(p.region(0),"py/pz", "py/pz", "#");
-            StyleUtil.stylize(p.region(1),"px/pz", "px/pz", "#");
-            StyleUtil.stylize(p.region(2),"time diff (t-b)", "diff (ns)", "#");
-            StyleUtil.stylize(p.region(3),"py/pz vs diff", "diff (GeV)", "py/pz");
-            StyleUtil.stylize(p.region(4),"px/pz vs diff", "diff (GeV)", "px/pz");
-            StyleUtil.stylize(p.region(5),"diff", "diff (GeV)", "#");
-
-            StyleUtil.stylize(p.region(6),"py/pz vs sum", "sum (GeV)", "py/pz");
-            StyleUtil.stylize(p.region(7),"px/pz vs sum", "sum (GeV)", "px/pz");
-            StyleUtil.stylize(p.region(8),"sum", "sum (GeV)", "#");
-
-            StyleUtil.stylize(p.region(9),"py/pz vs mass", "mass (GeV)", "py/pz");
-            StyleUtil.stylize(p.region(10),"px/pz vs mass", "mass (GeV)", "px/pz");
-            StyleUtil.stylize(p.region(11),"mass", "mass (GeV)", "#");
-
-            p.show();
-
-            IPlotter p2 = aida.analysisFactory().createPlotterFactory().create();
-
-            p2.createRegions(2, 1);
-
-
-            p2.region(0).plot(hpypz_botHighE);
-            p2.region(1).plot(hpxpz_botHighE);
-            p2.region(0).plot(hpypz_mid);
-            p2.region(1).plot(hpxpz_mid);
-            p2.region(0).plot(hpypz_topHighE);
-            p2.region(1).plot(hpxpz_topHighE);
-
-            StyleUtil.stylize(p2.region(0),"py/pz", "py/pz", "#");
-            StyleUtil.stylize(p2.region(1),"px/pz", "py/pz", "#");
-            StyleUtil.noFillHistogramBars(p2.region(0));
-            StyleUtil.noFillHistogramBars(p2.region(1));
-            p2.show();
-        }
-         */
+        
+    }
+    
+    
+    double beamTiltX = .0295;
+    double beamTiltY = -.0008;
+    
+    double[] getThetaAndPhi(Hep3Vector p){
+    	double px = p.x(), py = p.y(), pz = p.z();
+        
+        double cx = cos(beamTiltX);
+        double sy = sin(beamTiltY);
+        double cy = cos(beamTiltY);
+        double sx = sin(beamTiltX);
+        
+        double pxtilt = px*cx              -pz*sx;
+        double pytilt = -py*sx*sy + py*cy  -pz*sy*cx;
+        double pztilt = px*cy*sx  + py*sy  +pz*cy*cx;
+        
+
+        double theta = atan(hypot(pxtilt, pytilt)/pztilt);
+        double phi = atan2(pytilt, pxtilt);
+        return new double[]{theta, phi};
     }
 }

Modified: java/trunk/users/src/main/java/org/hps/users/spaul/trident/TridentHistogramDriver.java
 =============================================================================
--- java/trunk/users/src/main/java/org/hps/users/spaul/trident/TridentHistogramDriver.java	(original)
+++ java/trunk/users/src/main/java/org/hps/users/spaul/trident/TridentHistogramDriver.java	Thu Sep  1 04:26:03 2016
@@ -9,6 +9,7 @@
 
 import org.hps.recon.tracking.TrackType;
 import org.hps.users.spaul.StyleUtil;
+import org.lcsim.event.Cluster;
 import org.lcsim.event.EventHeader;
 import org.lcsim.event.ReconstructedParticle;
 import org.lcsim.event.Vertex;
@@ -28,22 +29,25 @@
     public void process(EventHeader event){
         for(int i = 0; i< tridentCollections.length; i++){
             List<Vertex> tridents = event.get(Vertex.class, tridentCollections[i]);
+            
             for(Vertex v : tridents){
+            	
+            		
                 if(!passesCuts(v))
                     continue;
-                ReconstructedParticle m = v.getAssociatedParticle();
-                ReconstructedParticle top;
-                ReconstructedParticle bottom;
-                if(m.getParticles().get(0).getMomentum().y()>0){
-                    top = m.getParticles().get(0);
-                    bottom = m.getParticles().get(1);
+                ReconstructedParticle part = v.getAssociatedParticle();
+                ReconstructedParticle plus;
+                ReconstructedParticle minus;
+                if(part.getParticles().get(0).getCharge()>0){
+                    plus = part.getParticles().get(0);
+                    minus = part.getParticles().get(1);
                 }else{
-                    top = m.getParticles().get(1);
-                    bottom = m.getParticles().get(0);
+                    plus = part.getParticles().get(1);
+                    minus = part.getParticles().get(0);
                 }
 
-                double pypz = m.getMomentum().y()/m.getMomentum().z();
-                double pxpz = m.getMomentum().x()/m.getMomentum().z();
+                double pypz = part.getMomentum().y()/part.getMomentum().z();
+                double pxpz = part.getMomentum().x()/part.getMomentum().z();
                 //double pypz = (top.getMomentum().y()+bottom.getMomentum().y())/(top.getMomentum().z()+bottom.getMomentum().z());
                 //double pxpz = (top.getMomentum().x()+bottom.getMomentum().x())/(top.getMomentum().z()+bottom.getMomentum().z());
 
@@ -51,71 +55,104 @@
                 hpxpz[i].fill(pxpz);
 
 
-                double diff = top.getMomentum().z()-bottom.getMomentum().z();
-                double sum = m.getMomentum().z();//top.getMomentum().z()+bottom.getMomentum().z();
-                double mass = m.getMass();
-
-                
-
-                this.diff[i].fill(diff);
-                this.sum[i].fill(sum);
+                double diff = plus.getMomentum().z()-minus.getMomentum().z();
+                double sum = part.getMomentum().z();
+                double mass = part.getMass();
+
+                
+
+                this.pz_diff[i].fill(diff);
+                this.pz_sum[i].fill(sum);
                 this.mass[i].fill(mass);
-                pypz_vs_diff[i].fill(diff,pypz );
-                pxpz_vs_diff[i].fill(diff, pxpz );
-
-
-
-                pxpz_vs_sum[i].fill(sum, pxpz );
-                pypz_vs_sum[i].fill(sum, pypz );
-
-                pxpz_vs_mass[i].fill(mass, pxpz );
-                pypz_vs_mass[i].fill(mass, pypz );
-                timediff[i].fill(top.getClusters().get(0).getCalorimeterHits().get(0).getTime()
-                        -bottom.getClusters().get(0).getCalorimeterHits().get(0).getTime());
-                /*if(moreEnergetic.getMomentum().y() > 0)
-            {
-                pypz_tophighE.fill(pypz);
-                pxpz_tophighE.fill(pxpz);
-            }
-            if(moreEnergetic.getMomentum().y() < 0)
-            {
-                pypz_bottomhighE.fill(pypz);
-                pxpz_bottomhighE.fill(pxpz);
-            }*/
+                
+                double energy = v.getAssociatedParticle().getEnergy();
+                this.mass_vs_energy[i].fill(mass, energy);
+                this.mass_vs_pz[i].fill(mass, part.getMomentum().z());
+                
+                timediff[i].fill(plus.getClusters().get(0).getCalorimeterHits().get(0).getTime()
+                		-minus.getClusters().get(0).getCalorimeterHits().get(0).getTime());
+                this.chi2Vtx[i].fill(v.getChi2());
+                this.chi2TrkPlus[i].fill(plus.getTracks().get(0).getChi2());
+                this.chi2TrkMinus[i].fill(minus.getTracks().get(0).getChi2());
+                
+                this.vtx_x[i].fill(v.getPosition().x());
+                this.vtx_y[i].fill(v.getPosition().y());
+                this.vtx_xy[i].fill(v.getPosition().x(), v.getPosition().y());
+                
+                this.pz_vs_pz[i].fill(minus.getMomentum().z(), plus.getMomentum().z());
             }
         }
     }
 
-    static double BIG_NUMBER = Double.POSITIVE_INFINITY; 
-    double _maxVtxChi2 = 10;
-    double _maxTrkChi2 = 15;
-    double _maxMass = 1.0;
+    
+    double _maxVtxChi2 = 100;
+    double _maxTrkChi2 = 150;
+    double _maxMass = .2;
     double _minMass = 0;
-    double _minVtxPz = 2.0;
-    double _maxVtxPz = 4.0;
-    double _maxTrkPz = 0;
+    double _minVtxPz = 0.0;
+    double _maxVtxPz = 3.0;
+    
+    double _maxTrkPz = 1.9;
     double _maxPzDiff = 4.0;
+    double _timeDiffCut = 1.2;
     boolean passesCuts(Vertex vertex){
         ReconstructedParticle part = vertex.getAssociatedParticle();
+        
+        ReconstructedParticle p1 = part.getParticles().get(0);
+        ReconstructedParticle p2 = part.getParticles().get(1);
+        
+        
+        //first make sure the track type is GBL
         if(!TrackType.isGBL(part.getType()))
             return false;
+        // make sure both tracks are matched to clusters
+        if(p1.getClusters().size() == 0)
+            return false;
+        if(p2.getClusters().size() == 0)
+            return false;
+
+        Cluster c1 = p1.getClusters().get(0);
+        Cluster c2 = p2.getClusters().get(0);
+        
+        
+        //make sure the clusters are on opposite sides of detector.  
+        if(c1.getPosition()[1]*c2.getPosition()[1] >0)
+        	return false;
+        
+        //plot the time difference (top minus bottom) versus the energy sum
+        double dt = c1.getCalorimeterHits().get(0).getTime()
+		-c2.getCalorimeterHits().get(0).getTime();
+        timediff_vs_esum[0].fill(Math.signum(c1.getPosition()[1])*dt,
+        	part.getEnergy());
+        
+        //and that they are from the same beam bunch
+        
+        if(Math.abs(dt)>_timeDiffCut)
+        	return false;
+        
+        
+        //make sure the total momentum is a reasonable range.   
         if(part.getMomentum().z() > _maxVtxPz || part.getMomentum().z() < _minVtxPz)
             return false;
+        
+        // mass within a proper window.
         if(part.getMass() > _maxMass || part.getMass() < _minMass)
             return false;
-
-        if(part.getParticles().get(0).getCharge()*part.getParticles().get(1).getCharge() != -1 )
-            return false;
-
+        
+        //fee momentum cut
+        if(p1.getMomentum().z() > 1.9 || p2.getMomentum().z() > 1.9)
+        	return false;
+        
+        //oppositely charged particles.
+        if(part.getParticles().get(0).getCharge()
+        		+ part.getParticles().get(1).getCharge() != 0)
+            return false;
+
+        // make sure the chi^2 of the vertex fit is reasonable 
         if(vertex.getChi2() > _maxVtxChi2)
             return false;
-
-
-        if(part.getParticles().get(0).getClusters().size() == 0)
-            return false;
-        if(part.getParticles().get(1).getClusters().size() == 0)
-            return false;
-
+        
+        //and also the chi^2 of the individual tracks are reasonable as well.
         if(part.getParticles().get(0).getTracks().get(0).getChi2() > _maxTrkChi2)
             return false;
         if(part.getParticles().get(1).getTracks().get(0).getChi2() > _maxTrkChi2)
@@ -123,13 +160,20 @@
         return true;
     }
 
-    IHistogram1D hpypz[], hpxpz[], diff[], sum[], mass[];
+    IHistogram1D hpypz[], hpxpz[], pz_diff[], pz_sum[], mass[];
     
     IHistogram1D chi2TrkPlus[];
     IHistogram1D chi2TrkMinus[];
     IHistogram1D chi2Vtx[];
     
-
+    IHistogram1D vtx_x[], vtx_y[], timediff[];
+
+    
+	private IHistogram2D[] mass_vs_energy;
+	private IHistogram2D[] vtx_xy;
+	private IHistogram2D[] pz_vs_pz;
+	private IHistogram2D[] mass_vs_pz;
+	private IHistogram2D[] timediff_vs_esum;
 
 
 
@@ -191,10 +235,7 @@
         this._maxVtxPz = _maxPz;
     }
 
-    IHistogram1D vtx_x[], vtx_y[], timediff[];
-
-    IProfile1D pxpz_vs_diff[], pypz_vs_diff[], pxpz_vs_sum[], pypz_vs_sum[],
-    pxpz_vs_mass[], pypz_vs_mass[];
+    
 
 
     //IHistogram1D pypz_tophighE, pxpz_tophighE;
@@ -206,51 +247,59 @@
         hpxpz = new IHistogram1D[3];
         
         
-        pxpz_vs_diff= new IProfile1D[3];
-        pypz_vs_diff= new IProfile1D[3];
-
-        diff= new IHistogram1D[3];
-
-        sum= new IHistogram1D[3];
-
-        pxpz_vs_sum= new IProfile1D[3];
-        pypz_vs_sum= new IProfile1D[3];
-
-        pxpz_vs_mass= new IProfile1D[3];
-        pypz_vs_mass= new IProfile1D[3];
-
-        //vtx_x= new IHistogram1D[3];
-        //vtx_y= new IHistogram1D[3];
+        pz_diff= new IHistogram1D[3];
+
+        pz_sum= new IHistogram1D[3];
+
+
+        
+
+        vtx_x= new IHistogram1D[3];
+        vtx_y= new IHistogram1D[3];
+        
+        vtx_xy = new IHistogram2D[3]; 
+        
         mass= new IHistogram1D[3];
         timediff= new IHistogram1D[3];
-        
+        timediff_vs_esum = new IHistogram2D[3];
+        mass_vs_energy = new IHistogram2D[3];
+        mass_vs_pz = new IHistogram2D[3];
+        chi2Vtx = new IHistogram1D[3];
+        chi2TrkPlus = new IHistogram1D[3];
+        chi2TrkMinus = new IHistogram1D[3];
+        pz_vs_pz = new IHistogram2D[3]; 
         for(int i = 0; i< 3; i++){
             
-            hpypz[i] = aida.histogram1D(tridentCollections[i]+"/"+"pypz", 60, -.005,.005);
-            hpxpz[i] = aida.histogram1D(tridentCollections[i]+"/"+"pxpz", 60, .025,.035);
-
-
+            hpypz[i] = aida.histogram1D(tridentCollections[i]+"/"+"pypz", 80, -.020,.020);
+            hpxpz[i] = aida.histogram1D(tridentCollections[i]+"/"+"pxpz", 80, .010,.050);
+
+            vtx_x[i] = aida.histogram1D(tridentCollections[i]+"/"+"vtx x", 200, -2, 2);
+            vtx_y[i] = aida.histogram1D(tridentCollections[i]+"/"+"vtx y", 200, -2, 2);
+
+
+            vtx_xy[i] = aida.histogram2D(tridentCollections[i]+"/"+"vtx xy", 200, -2, 2, 200, -2, 2);
+        
+            pz_diff[i] = aida.histogram1D(tridentCollections[i]+"/"+"pz pos - ele",120, -_maxPzDiff, _maxPzDiff);
+
+            pz_sum[i] = aida.histogram1D(tridentCollections[i]+"/"+"pz sum", 100, _minVtxPz, _maxVtxPz);
            
-
-            pxpz_vs_diff[i] = aida.profile1D(tridentCollections[i]+"/"+"pxpz vs diff", 25, -.60, .60);
-            pypz_vs_diff[i] = aida.profile1D(tridentCollections[i]+"/"+"pypz vs diff", 25, -.60, .60);
-
-            diff[i] = aida.histogram1D(tridentCollections[i]+"/"+"diff", 50, -.60, .60);
-
-            sum[i] = aida.histogram1D(tridentCollections[i]+"/"+"sum", 50, 1.0, 1.1);
-
-            pxpz_vs_sum[i] = aida.profile1D(tridentCollections[i]+"/"+"pxpz vs sum", 25, 1.0, 1.1);
-            pypz_vs_sum[i] = aida.profile1D(tridentCollections[i]+"/"+"pypz vs sum", 25, 1.0, 1.1);
-
-            pxpz_vs_mass[i] = aida.profile1D(tridentCollections[i]+"/"+"pxpz vs mass", 25, .03, .037);
-            pypz_vs_mass[i] = aida.profile1D(tridentCollections[i]+"/"+"pypz vs mass", 25, .03, .037);
-
             //vtx_x[i] = aida.histogram1D(tridentCollections[i]+"/"+"vtx x", 60, -1, 1);
             //vtx_y[i] = aida.histogram1D(tridentCollections[i]+"/"+"vtx y", 60, -1, 1);
-            mass[i] = aida.histogram1D(tridentCollections[i]+"/"+"mass", 60, .030, .037);
+            
+            //for 0-200 MeV, this yields 0.1 MeV mass bins
+            mass[i] = aida.histogram1D(tridentCollections[i]+"/"+"mass", 2000, _minMass, _maxMass); 
+            //
+            mass_vs_energy[i] = aida.histogram2D(tridentCollections[i]+"/"+"mass vs energy sum", 2000, _minMass, _maxMass, 100, 0, 5); 
+            mass_vs_pz[i] = aida.histogram2D(tridentCollections[i]+"/"+"mass vs pz sum", 2000, _minMass, _maxMass, 100, 0, 5); 
+            
+            
             timediff[i] = aida.histogram1D(tridentCollections[i]+"/"+"time diff", 60, -6, 6);
+            timediff_vs_esum[i] = aida.histogram2D(tridentCollections[i]+"/"+"time diff vs energy sum", 60, -6, 6, 100, 0, 3);
+            
+            chi2Vtx[i] = aida.histogram1D(tridentCollections[i]+"/"+"chi2 vertex", 100, 0, 100);
+            chi2TrkPlus[i] = aida.histogram1D(tridentCollections[i]+"/"+"chi2 track plus", 100, 0, 100);
+            chi2TrkMinus[i] = aida.histogram1D(tridentCollections[i]+"/"+"chi2 track minus", 100, 0, 100);   
+            pz_vs_pz[i] = aida.histogram2D(tridentCollections[i]+"/"+"pz ele vs pos", 100, 0, 4, 100, 0, 4);
         }
-
-        
     }
 }

Top of Message | Previous Page | Permalink

Advanced Options


Options

Log In

Log In

Get Password

Get Password


Search Archives

Search Archives


Subscribe or Unsubscribe

Subscribe or Unsubscribe


Archives

November 2017
August 2017
July 2017
January 2017
December 2016
November 2016
October 2016
September 2016
August 2016
July 2016
June 2016
May 2016
April 2016
March 2016
February 2016
January 2016
December 2015
November 2015
October 2015
September 2015
August 2015
July 2015
June 2015
May 2015
April 2015
March 2015
February 2015
January 2015
December 2014
November 2014
October 2014
September 2014
August 2014
July 2014
June 2014
May 2014
April 2014
March 2014
February 2014
January 2014
December 2013
November 2013

ATOM RSS1 RSS2



LISTSERV.SLAC.STANFORD.EDU

Secured by F-Secure Anti-Virus CataList Email List Search Powered by the LISTSERV Email List Manager

Privacy Notice, Security Notice and Terms of Use