Print

Print


Author: [log in to unmask]
Date: Mon Nov 16 16:39:55 2015
New Revision: 3962

Log:
Add rejection sampling driver for beamspot PDF

Added:
    java/trunk/recon/src/main/java/org/hps/recon/filtering/BeamspotTransformFilter.java

Added: java/trunk/recon/src/main/java/org/hps/recon/filtering/BeamspotTransformFilter.java
 =============================================================================
--- java/trunk/recon/src/main/java/org/hps/recon/filtering/BeamspotTransformFilter.java	(added)
+++ java/trunk/recon/src/main/java/org/hps/recon/filtering/BeamspotTransformFilter.java	Mon Nov 16 16:39:55 2015
@@ -0,0 +1,311 @@
+/**
+ * 
+ */
+package org.hps.recon.filtering;
+
+import hep.aida.IAnalysisFactory;
+import hep.aida.IHistogram1D;
+import hep.aida.IHistogram2D;
+import hep.aida.IPlotter;
+import hep.aida.IPlotterFactory;
+
+import java.util.List;
+import java.util.Random;
+import java.util.logging.Logger;
+
+import org.lcsim.event.EventHeader;
+import org.lcsim.event.MCParticle;
+import org.lcsim.geometry.Detector;
+import org.lcsim.util.Driver;
+import org.lcsim.util.aida.AIDA;
+
+/**
+ * Filter class to create a smaller beamspot based on a sample with fixed, larger, beamspot. 
+ * Uses sampling-rejection MC technique.  
+ * 
+ * @author Per Hansson Adrian <[log in to unmask]>
+ *
+ */
+public class BeamspotTransformFilter extends Driver {
+
+    private AIDA aida = AIDA.defaultInstance();
+    private IPlotter plotter;
+    private IPlotter plotter2;
+    private IPlotter plotter3;
+    private IHistogram2D h_bs_2d;
+    private IHistogram1D h_bs_z;
+    private IHistogram1D h_bs_y;
+    private IHistogram1D h_bs_x;
+    private IHistogram2D h_bs_2d_proposal;
+    private IHistogram2D h_bs_2d_desired;
+    private IHistogram1D h_bs_z_desired;
+    private IHistogram1D h_bs_y_desired;
+    private IHistogram1D h_bs_x_desired;
+    private String MCParticleCollectionName = "MCParticle";
+    private final Logger logger = Logger.getLogger(BeamspotTransformFilter.class.getSimpleName());
+    private double mu1 = 0.0;
+    private double mu2 = 0.0;
+    private double s1 = 0.2;
+    private double s2 = 0.04;
+    private double rho = 0.0;
+    private double mu1_desired = 0.0;
+    private double mu2_desired = 0.0;
+    private double s1_desired = 0.2;
+    private double s2_desired = 0.04;
+    private double rho_desired = 0.0;
+    private Random random = new Random();
+    private boolean show_plots = true; 
+    
+    
+    /**
+     * 
+     */
+    public BeamspotTransformFilter() {
+    }
+
+    protected void detectorChanged(Detector detector) {
+        aida.tree().cd("/");
+        IAnalysisFactory af = aida.analysisFactory();
+        IPlotterFactory pf = af.createPlotterFactory();
+        plotter = pf.create("Beamspot");
+        plotter.createRegions(1, 4);
+        h_bs_2d = aida.histogram2D("h_bs_2d", 50, -0.5 , 0.5, 50,-0.5, 0.5);
+        h_bs_z = aida.histogram1D("h_bs_z", 50, -0.5 , 0.5);
+        h_bs_y = aida.histogram1D("h_bs_y", 50, -0.5 , 0.5);
+        h_bs_x = aida.histogram1D("h_bs_x", 50, -0.5 , 0.5);
+        plotter.region(0).plot(h_bs_2d);
+        plotter.region(0).style().setParameter("hist2DStyle", "colorMap");
+        plotter.region(0).style().dataStyle().fillStyle().setParameter("colorMapScheme", "rainbow");
+        plotter.region(1).plot(h_bs_x);
+        plotter.region(2).plot(h_bs_y);
+        plotter.region(3).plot(h_bs_z);
+        if(show_plots) plotter.show();
+
+        plotter2 = pf.create("Beamspot2");
+        plotter2.createRegions(1, 4);
+        h_bs_2d_proposal = aida.histogram2D("h_bs_2d_proposal", 50, -0.5 , 0.5, 50,-0.5, 0.5);
+        plotter2.region(0).plot(h_bs_2d_proposal);
+        plotter2.region(0).setStyle(plotter.region(0).style());
+        if(show_plots) plotter2.show();
+        
+        plotter3 = pf.create("Beamspot_desired");
+        plotter3.createRegions(1, 4);
+        h_bs_2d_desired = aida.histogram2D("h_bs_2d_desired", 50, -0.5 , 0.5, 50,-0.5, 0.5);
+        h_bs_z_desired = aida.histogram1D("h_bs_z_desired", 50, -0.5 , 0.5);
+        h_bs_y_desired = aida.histogram1D("h_bs_y_desired", 50, -0.5 , 0.5);
+        h_bs_x_desired = aida.histogram1D("h_bs_x_desired", 50, -0.5 , 0.5);
+        plotter3.region(0).plot(h_bs_2d_desired);
+        plotter3.region(0).setStyle(plotter.region(0).style());
+        plotter3.region(1).plot(h_bs_x_desired);
+        plotter3.region(2).plot(h_bs_y_desired);
+        plotter3.region(3).plot(h_bs_z_desired);
+        if(show_plots) plotter3.show();
+        
+    }
+    
+    protected void process(EventHeader event) {
+
+        if ( !event.hasCollection(MCParticle.class, this.MCParticleCollectionName ) ) {
+            logger.info("No MC particle collection found.");
+            throw new Driver.NextEventException();
+        }
+        
+        List<MCParticle> mcParticles = event.get(MCParticle.class, this.MCParticleCollectionName );        
+        if( mcParticles.size() == 0) {
+            logger.info("MC particle collection is empty.");
+            throw new Driver.NextEventException();
+        }
+        
+        logger.fine("found " + mcParticles.size() + " MC particles.");
+        
+        MCParticle aprime = getAprime(mcParticles);
+        
+        if( aprime == null) {
+            logger.info("No A' found in particle collection.");
+            throw new Driver.NextEventException();
+        }
+        
+        // Find origin of the A'
+        double origin[] = new double[3];
+        origin[0] = aprime.getOriginX();
+        origin[1] = aprime.getOriginY();
+        origin[2] = aprime.getOriginZ();
+
+        // Fill origin to histograms
+        logger.fine("A' origin (" + origin[0] + "," + origin[1] + "," + origin[2]);
+        h_bs_2d.fill(origin[0], origin[1]);
+        h_bs_x.fill(origin[0]);
+        h_bs_y.fill(origin[1]);
+        h_bs_z.fill(origin[2]);
+        
+
+        // Calculate the PDF density for the proposal distribution
+        double dens = density(origin[0], origin[1],mu1,s1,mu2,s2,rho);
+        h_bs_2d_proposal.fill(origin[0],origin[1],dens);
+
+        // Throw a random number and scale it to the range of the proposal distribution
+        double r = random.nextDouble()*dens;
+
+        // Calculate the PDF density for the desired distribution
+        double dens_desired = density(origin[0], origin[1],mu1_desired,s1_desired,mu2_desired,s2_desired,rho_desired);        
+        logger.fine("point (" + origin[0] + "," + origin[1] + ") for r " + r + " dens " + dens + " dens_desired " + dens_desired );
+
+        // Reject the event if the density is larger than the desired PDF
+        if( r > dens_desired) {
+            logger.fine("reject point");
+            throw new Driver.NextEventException();
+        }
+        logger.fine("accept point");
+
+        
+        // Fill some histograms
+        h_bs_2d_desired.fill(origin[0],origin[1]);
+        h_bs_x_desired.fill(origin[0]);
+        h_bs_y_desired.fill(origin[1]);
+        h_bs_z_desired.fill(origin[2]);
+
+        return;
+    }
+    
+    /**
+     * Calculate the density for a bivariate normal distribution
+     * @param x1 
+     * @param x2
+     * @param mu1 - mean
+     * @param s1 - sigma
+     * @param mu2 - mean 
+     * @param s2 - sigma
+     * @param rho - correlation coefficient between the variables
+     * @return density for this point
+     */
+    private double density(double x1, double x2, double mu1, double s1, double mu2, double s2, double rho) {
+        double z = (x1-mu1)*(x1-mu1)/(s1*s1) - 2*rho*(x1-mu1)*(x2-mu2)/(s1*s2) + (x2-mu2)*(x2-mu2)/(s2*s2);
+        double C = 1/(2*Math.PI *s1*s2*Math.sqrt(1-rho*rho));
+        double e = Math.exp(-z/(2*(1-rho*rho)));
+        return C*e;
+    }
+    
+//    private double density1D(double x1,  double mu1, double s1) {
+//        double e = Math.exp(-1*(x1-mu1)*(x1-mu1)/(2*s1*s1));
+//        double C = 1/(Math.sqrt(2*Math.PI)*s1);
+//        return C*e;
+//    }
+    
+    
+    
+    /**
+     * Find the A' amond the list of MC partiles
+     * @param mcParticles - list of particles
+     * @return A' particle, else null
+     */
+    private MCParticle getAprime(List<MCParticle> mcParticles) {
+        MCParticle ap = null;
+        for (MCParticle mcp : mcParticles) {
+            String s = "";
+            for (MCParticle parent : mcp.getParents()) s += " <- " + Integer.toString(parent.getPDGID());
+            String s1 = "";
+            for (MCParticle parent : mcp.getDaughters()) s1 += " <- " + Integer.toString(parent.getPDGID());            
+            logger.fine("mcp " + mcp.getPDGID() + " with " + mcp.getParents().size() + " parents " + s + " and with " + mcp.getDaughters().size() + " daughters " + s1);
+            
+            if( Math.abs(mcp.getPDGID()) == 622) {
+                ap = mcp;
+                break;
+            }
+        }
+        return ap;
+    }
+        
+
+   
+
+    public double getMu1() {
+        return mu1;
+    }
+
+    public void setMu1(double mu1) {
+        this.mu1 = mu1;
+    }
+
+    public double getMu2() {
+        return mu2;
+    }
+
+    public void setMu2(double mu2) {
+        this.mu2 = mu2;
+    }
+
+    public double getS1() {
+        return s1;
+    }
+
+    public void setS1(double s1) {
+        this.s1 = s1;
+    }
+
+    public double getS2() {
+        return s2;
+    }
+
+    public void setS2(double s2) {
+        this.s2 = s2;
+    }
+
+    public double getRho() {
+        return rho;
+    }
+
+    public void setRho(double rho) {
+        this.rho = rho;
+    }
+
+    public double getMu1_desired() {
+        return mu1_desired;
+    }
+
+    public void setMu1_desired(double mu1_desired) {
+        this.mu1_desired = mu1_desired;
+    }
+
+    public double getMu2_desired() {
+        return mu2_desired;
+    }
+
+    public void setMu2_desired(double mu2_desired) {
+        this.mu2_desired = mu2_desired;
+    }
+
+    public double getS1_desired() {
+        return s1_desired;
+    }
+
+    public void setS1_desired(double s1_desired) {
+        this.s1_desired = s1_desired;
+    }
+
+    public double getS2_desired() {
+        return s2_desired;
+    }
+
+    public void setS2_desired(double s2_desired) {
+        this.s2_desired = s2_desired;
+    }
+
+    public double getRho_desired() {
+        return rho_desired;
+    }
+
+    public void setRho_desired(double rho_desired) {
+        this.rho_desired = rho_desired;
+    }
+
+    public boolean isShow_plots() {
+        return show_plots;
+    }
+
+    public void setShow_plots(boolean show_plots) {
+        this.show_plots = show_plots;
+    }
+    
+}
+
+