Author: [log in to unmask] Date: Sun Jan 3 10:18:03 2016 New Revision: 4075 Log: (empty) Added: java/trunk/users/src/main/java/org/hps/users/spaul/feecc/FEESpectrumGenerator.java java/trunk/users/src/main/java/org/hps/users/spaul/feecc/FormFactor.java java/trunk/users/src/main/java/org/hps/users/spaul/feecc/MottIntegral.java java/trunk/users/src/main/java/org/hps/users/spaul/feecc/MultipleScattering.java java/trunk/users/src/main/java/org/hps/users/spaul/feecc/ShowCustomBinningXY.java Removed: java/trunk/users/src/main/java/org/hps/users/spaul/feecc/analysis/ Modified: java/trunk/users/src/main/java/org/hps/users/spaul/StyleUtil.java java/trunk/users/src/main/java/org/hps/users/spaul/SumEverything.java java/trunk/users/src/main/java/org/hps/users/spaul/feecc/BinGenerator.java java/trunk/users/src/main/java/org/hps/users/spaul/feecc/CustomBinning.java java/trunk/users/src/main/java/org/hps/users/spaul/feecc/DisplayHistograms.java java/trunk/users/src/main/java/org/hps/users/spaul/feecc/EcalUtil.java java/trunk/users/src/main/java/org/hps/users/spaul/feecc/MakeHistograms.java java/trunk/users/src/main/java/org/hps/users/spaul/feecc/ShowCustomBinning.java Modified: java/trunk/users/src/main/java/org/hps/users/spaul/StyleUtil.java ============================================================================= --- java/trunk/users/src/main/java/org/hps/users/spaul/StyleUtil.java (original) +++ java/trunk/users/src/main/java/org/hps/users/spaul/StyleUtil.java Sun Jan 3 10:18:03 2016 @@ -1,10 +1,9 @@ package org.hps.users.spaul; import java.util.Arrays; +import java.util.Random; -import hep.aida.IAnalysisFactory; -import hep.aida.IFunction; -import hep.aida.IPlotterRegion; +import hep.aida.*; public class StyleUtil { @@ -27,18 +26,20 @@ r.style().yAxisStyle().setLabel(ly); r.style().yAxisStyle().labelStyle().setFontSize(16); r.style().yAxisStyle().tickLabelStyle().setFontSize(14); - r.style().statisticsBoxStyle().setParameter("backgroundColor", "white"); - r.style().statisticsBoxStyle().boxStyle().backgroundStyle().setColor("White"); - r.style().statisticsBoxStyle().boxStyle().backgroundStyle().setParameter("color", "white"); - r.style().statisticsBoxStyle().boxStyle().backgroundStyle().setOpacity(100); - System.out.println(Arrays.toString(r.style().dataStyle().availableParameters())); + // r.style().statisticsBoxStyle().set; + //System.out.println(Arrays.toString()); + r.style().legendBoxStyle().textStyle().setFontSize(16); + + //r.style().dataStyle().showInLegendBox(false); + r.style().legendBoxStyle().boxStyle().foregroundStyle().setOpacity(1.0); r.style().dataStyle().fillStyle().setParameter("colorMapScheme", "rainbow"); r.style().dataStyle().fillStyle().setParameter("showZeroHeightBins", "false"); + System.out.println(Arrays.toString(r.style().statisticsBoxStyle().boxStyle().backgroundStyle().availableParameters())); //r.style().dataStyle().setParameter("showDataInStatisticsBox", "false"); r.style().setParameter("hist2DStyle", "colorMap"); //r.style().dataBoxStyle() } - static void addHorizontalLine(IPlotterRegion r, double y, String name){ + public static void addHorizontalLine(IPlotterRegion r, double y, String name){ IAnalysisFactory af = IAnalysisFactory.create(); IFunction f = af.createFunctionFactory(af.createTreeFactory().create()).createFunctionByName(name, "p0"); f.setParameter("p0", y); @@ -53,4 +54,54 @@ f.setParameter("p2", p2); region.plot(f); } + public static void noFillHistogramBars(IPlotterRegion region) { + region.style().dataStyle().setParameter("fillHistogramBars", "false"); + region.style().dataStyle().fillStyle().setVisible(false); + + + region.style().dataStyle().lineStyle().setParameter("colorRotateMethod", "regionOverlayIndex"); + region.style().dataStyle().lineStyle().setParameter("colorRotate", "black, red, green, blue"); + region.style().dataStyle().lineStyle().setParameter("thickness", "3"); + region.style().dataStyle().errorBarStyle().setVisible(false); + System.out.println(Arrays.toString(region.style().dataStyle().lineStyle().availableParameterOptions("colorRotateMethod"))); + } + + public static void main(String arg[]){ + IAnalysisFactory af = IAnalysisFactory.create(); + IHistogramFactory hf = af.createHistogramFactory(af.createTreeFactory().create()); + + IPlotter p = af.createPlotterFactory().create(); + p.createRegions(1, 2); + IHistogram1D h1 = hf.createHistogram1D("blah", 100, -5, 5); + IHistogram1D h2 = hf.createHistogram1D("bleh", 100, -5, 5); + Random random = new Random(); + for(int i = 0; i< 100000; i++){ + h1.fill(random.nextGaussian()); + h2.fill(random.nextGaussian()*2); + } + hideLegendAndStats(p.region(1)); + noFillHistogramBars(p.region(0)); + stylize(p.region(0), "title", "x axis label", "y axis label"); + stylize(p.region(1), "stuff", "x axis label", "y axis label"); + p.region(0).plot(h1); + p.region(0).plot(h2); + + + IHistogram2D h3 = hf.createHistogram2D("blah", 100, -5, 5, 100, -5,5); + + for(int i = 0; i< 100000; i++){ + h3.fill(random.nextGaussian(), random.nextGaussian()); + } + + p.region(1).plot(h3); + + + + p.show(); + + } + public static void hideLegendAndStats(IPlotterRegion r){ + r.style().statisticsBoxStyle().setVisible(false); + r.style().legendBoxStyle().setVisible(false); + } } Modified: java/trunk/users/src/main/java/org/hps/users/spaul/SumEverything.java ============================================================================= --- java/trunk/users/src/main/java/org/hps/users/spaul/SumEverything.java (original) +++ java/trunk/users/src/main/java/org/hps/users/spaul/SumEverything.java Sun Jan 3 10:18:03 2016 @@ -2,6 +2,7 @@ import java.io.File; import java.io.IOException; +import java.util.ArrayList; import hep.aida.IAnalysisFactory; import hep.aida.IHistogram1D; @@ -23,20 +24,44 @@ oneArg(arg[0]); } } - static void oneArg(String indir) throws IllegalArgumentException, IOException{ + static void oneArg(final String indir) throws IllegalArgumentException, IOException{ File outdir = new File(indir + "/sums"); outdir.mkdir(); - for(File subdirf : new File(indir).listFiles()){ - String subdir = subdirf.getAbsolutePath(); - if(subdir.matches(".*/sums/?")) - continue; - String split[] = subdir.split("/"); - String outfile = indir + "/sums/" + split[split.length-1] + ".aida"; - twoArg(subdir, outfile); + ArrayList<Thread> threads = new ArrayList<Thread>(); + for(final File subdirf : new File(indir).listFiles()){ + Thread t = new Thread(){ + public void run(){ + + String subdir = subdirf.getAbsolutePath(); + if(subdir.matches(".*/sums/?")) + return; + String split[] = subdir.split("/"); + String outfile = indir + "/sums/" + split[split.length-1] + ".aida"; + try { + twoArg(subdir, outfile); + } catch (IllegalArgumentException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + }; + threads.add(t); + t.start(); + } + for(Thread t : threads){ + try { + t.join(); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } } new File(indir + "/sums/total.aida").delete(); twoArg(outdir.getAbsolutePath(), indir + "/sums/total.aida"); - + } static void twoArg(String indir, String out) throws IllegalArgumentException, IOException{ @@ -45,45 +70,56 @@ new File(out).delete(); ITree tree0 = tf.create(out, "xml", false, true); IHistogramFactory hf = af.createHistogramFactory(tree0); - + int j = 0; for(File s : new File(indir).listFiles()){ - ITree tree = af.createTreeFactory().create(s.getAbsolutePath(),"xml"); + if(!s.getAbsolutePath().endsWith("aida")) + continue; + try{ + ITree tree = af.createTreeFactory().create(s.getAbsolutePath(),"xml"); - - if(j == 0){ - String [] names = tree.listObjectNames(); - tree0.mount("/tmp", tree, "/"); - for(String name : names){ - Object o = tree.find(name); - if(o instanceof IHistogram1D || o instanceof IHistogram2D) - tree0.cp("/tmp/" + name, name); + + if(j == 0){ + String [] names = tree.listObjectNames(); + tree0.mount("/tmp", tree, "/"); + for(String name : names){ + Object o = tree.find(name); + if(o instanceof IHistogram1D || o instanceof IHistogram2D) + tree0.cp("/tmp/" + name, name); + } + tree0.unmount("/tmp"); + tree.close(); + } - tree0.unmount("/tmp"); + else{ + //tree. + String [] names = tree.listObjectNames(); + tree0.mount("/tmp", tree, "/"); + for(String name : names){ + Object o = tree.find(name); + if(o instanceof IHistogram1D) + ((IHistogram1D)tree0.find(name)).add((IHistogram1D)o); + if(o instanceof IHistogram2D) + ((IHistogram2D)tree0.find(name)).add((IHistogram2D)o); + } + tree0.unmount("/tmp"); + tree.close(); + } + tree.close(); - + j++; + System.out.println(j + " files have been read"); + + + } catch(IllegalArgumentException e){ + //print the filename + System.out.println("Exception happened at file " + s.getAbsolutePath()); + + e.printStackTrace(); } - else{ - //tree. - String [] names = tree.listObjectNames(); - tree0.mount("/tmp", tree, "/"); - for(String name : names){ - Object o = tree.find(name); - if(o instanceof IHistogram1D) - ((IHistogram1D)tree0.find(name)).add((IHistogram1D)o); - if(o instanceof IHistogram2D) - ((IHistogram2D)tree0.find(name)).add((IHistogram2D)o); - } - tree0.unmount("/tmp"); - tree.close(); - } - - tree.close(); - j++; - System.out.println(j + " files have been read"); + tree0.commit(); } - tree0.commit(); } } Modified: java/trunk/users/src/main/java/org/hps/users/spaul/feecc/BinGenerator.java ============================================================================= --- java/trunk/users/src/main/java/org/hps/users/spaul/feecc/BinGenerator.java (original) +++ java/trunk/users/src/main/java/org/hps/users/spaul/feecc/BinGenerator.java Sun Jan 3 10:18:03 2016 @@ -6,7 +6,7 @@ public class BinGenerator { public static void main(String arg[]) throws FileNotFoundException{ - int nBins = 20; + int nBins = 32; PrintStream pw = new PrintStream("generatedbins.txt"); pw.println(nBins); @@ -33,17 +33,21 @@ bins[i] = thetaMin+dTheta*i; } return bins; */ - double thetaMax = .145; - double thetaMin = .035; + double thetaMax = .200; + double thetaMin = .040; double[] bins = new double[nBins +1]; - double xMin = 1/(thetaMax*thetaMax); + for(int i = 0; i<nBins+1; i++){ + bins[i] = thetaMin+i*(thetaMax-thetaMin)/nBins; + } + return bins; + /*double xMin = 1/(thetaMax*thetaMax); double xMax = 1/(thetaMin*thetaMin); for(int i = 0; i< nBins+1; i++){ double x = xMax - i*(xMax-xMin)/nBins; bins[i] = Math.pow(x, -.5); } - return bins; + return bins;*/ } private static double[] getPhiBounds(double thetaMin, double thetaMax){ double phiBins[] = new double[6]; @@ -52,8 +56,14 @@ boolean prevInRange = false; for(double phi = 0; phi< 3.14; phi+= dphi){ - boolean inRange = EcalUtil.fid_ECal_spherical(thetaMin, phi) && EcalUtil.fid_ECal_spherical(thetaMax, phi) - && EcalUtil.fid_ECal_spherical(thetaMin, -phi) && EcalUtil.fid_ECal_spherical(thetaMax, -phi); + + // make the angular cuts on the tracks such that the particles that go into that cut + // are expected to be within 4 mm (~= 2 times the angular resolution of 1.5 mrad) of + // the ecal cuts. + double d = 4; + + boolean inRange = EcalUtil.fid_ECal_spherical_more_strict(thetaMin, phi, d) && EcalUtil.fid_ECal_spherical_more_strict(thetaMax, phi, d) + && EcalUtil.fid_ECal_spherical_more_strict(thetaMin, -phi, d) && EcalUtil.fid_ECal_spherical_more_strict(thetaMax, -phi, d); if(inRange && !prevInRange) phiBins[edgeNumber++] = phi; if(prevInRange && !inRange) Modified: java/trunk/users/src/main/java/org/hps/users/spaul/feecc/CustomBinning.java ============================================================================= --- java/trunk/users/src/main/java/org/hps/users/spaul/feecc/CustomBinning.java (original) +++ java/trunk/users/src/main/java/org/hps/users/spaul/feecc/CustomBinning.java Sun Jan 3 10:18:03 2016 @@ -76,21 +76,5 @@ } return tot; } - /** - * @param bin - * @param a = 2E/M - * @return the integral of 1/sin^4(th/2)*cos^2(th/2)/(1+a*sin^2(th/2)) times dPhi, - * which appears in the integral of mott scattering. - */ - public double mottIntegralFactor(double a, int bin){ - double dPhi = 0; - for(int i = 0; i< phiMax[bin].length; i++) - dPhi += 2*(phiMax[bin][0] - phiMin[bin][0]); //factor of 2 from top and bottom - - double csc2 = Math.pow(Math.sin(thetaMax[bin]/2), -2); - double Imax = (-csc2+(1+a)*Math.log(a+2*csc2)); - csc2 = Math.pow(Math.sin(thetaMin[bin]/2), -2); - double Imin = (-csc2+(1+a)*Math.log(a+2*csc2)); - return 2*dPhi*(Imax-Imin); - } + } Modified: java/trunk/users/src/main/java/org/hps/users/spaul/feecc/DisplayHistograms.java ============================================================================= --- java/trunk/users/src/main/java/org/hps/users/spaul/feecc/DisplayHistograms.java (original) +++ java/trunk/users/src/main/java/org/hps/users/spaul/feecc/DisplayHistograms.java Sun Jan 3 10:18:03 2016 @@ -4,6 +4,7 @@ public class DisplayHistograms { public static void main(String arg[]) throws IllegalArgumentException, IOException{ + //System.out.println("dognabo"); MakeHistograms.main(new String[]{arg[0]}); } } Modified: java/trunk/users/src/main/java/org/hps/users/spaul/feecc/EcalUtil.java ============================================================================= --- java/trunk/users/src/main/java/org/hps/users/spaul/feecc/EcalUtil.java (original) +++ java/trunk/users/src/main/java/org/hps/users/spaul/feecc/EcalUtil.java Sun Jan 3 10:18:03 2016 @@ -12,6 +12,45 @@ import org.lcsim.event.Cluster; public class EcalUtil { + + static int[] getCrystalIndex(Cluster c){ + if(map == null){ + try{ + readMap(); + }catch(Exception e){ + e.printStackTrace(); + } + } + c.getPosition(); + int bestix = 0, bestiy = 0; + double bestdist = 100000; + + double cx = c.getPosition()[0]; + double cy = c.getPosition()[1]; + for(int ix = -23; ix<= 23; ix++){ + if(!map.containsKey(200+ix)) + continue; + double x = map.get(200+ix)[0]; + if(Math.abs(x-cx)<bestdist){ + bestdist = Math.abs(x-cx); + bestix = ix; + } + } + + bestdist = 100000; + for(int iy = -5; iy<= 5; iy++){ + if(!map.containsKey(100*iy + bestix)) + continue; + double y = map.get(100*iy + bestix)[1]; + if(Math.abs(y-cy)<bestdist){ + bestdist = Math.abs(y-cy); + bestiy = iy; + } + } + return new int[]{bestix, bestiy}; + } + + /** * Holly's algorithm. * @param x x position of cluster @@ -83,6 +122,40 @@ return in_fid; } + /** + * + * @param x + * @param y + * @param d the additional distance from the edge of the ecal in addition + * to what is required by fid_Cal(double, double) + * @return + */ + public static boolean fid_ecal_more_strict(double x, double y, double d){ + y = Math.abs(y); + + boolean in_fid = false; + + double x_edge_low = -262.74 + d; + double x_edge_high = 347.7 - d; + double y_edge_low = 33.54 + d; + double y_edge_high = 75.18 - d; + + double x_gap_low = -106.66 - d; + double x_gap_high = 42.17 + d; + double y_gap_high = 47.18 + d; + + y = Math.abs(y); + + if( x > x_edge_low && x < x_edge_high && y > y_edge_low && y < y_edge_high ) + { + if( !(x > x_gap_low && x < x_gap_high && y > y_edge_low && y < y_gap_high) ) + { + in_fid = true; + } + } + + return in_fid; + } static double[] toSphericalFromBeam(double pxpz, double pypz){ double x = pxpz, y = pypz, z = 1; double beamTilt = .03057; @@ -96,10 +169,10 @@ return new double[]{theta, phi}; } - static Map<Integer, double[]> map = new HashMap(); + static Map<Integer, double[]> map ; static void readMap() throws FileNotFoundException{ - Scanner s = new Scanner(new File("ecal_positions.txt")); - + Scanner s = new Scanner(new File(System.getenv("HOME") + "/ecal_positions.txt")); + map = new HashMap(); while(s.hasNext()){ int ix =s.nextInt(); @@ -154,6 +227,12 @@ double y = xy[1]; return fid_ECal(x, y); } + public static boolean fid_ECal_spherical_more_strict(double theta, double phi, double d){ + double[] xy = getXY(theta, phi); + double x = xy[0]; + double y = xy[1]; + return fid_ecal_more_strict(x, y, d); + } public static void main(String arg[]){ double x = 0, y = 0; double sp[] = getThetaPhiSpherical(x,y); Added: java/trunk/users/src/main/java/org/hps/users/spaul/feecc/FEESpectrumGenerator.java ============================================================================= --- java/trunk/users/src/main/java/org/hps/users/spaul/feecc/FEESpectrumGenerator.java (added) +++ java/trunk/users/src/main/java/org/hps/users/spaul/feecc/FEESpectrumGenerator.java Sun Jan 3 10:18:03 2016 @@ -0,0 +1,294 @@ +package org.hps.users.spaul.feecc; + +import hep.aida.*; +import hep.io.stdhep.StdhepEvent; +import hep.io.stdhep.StdhepRecord; +import hep.io.stdhep.StdhepWriter; + +import java.io.File; +import java.io.IOException; +import java.util.Random; +import static java.lang.Math.*; + +public class FEESpectrumGenerator { + /************* + * CONSTANTS * + *************/ + static double alpha = 1/137., hbarc = .197, q = 1.6e-19, Na= 6.022e23; + static double me = .000511; + static double amu = 931.4941; + + private static double sqrt2 = Math.sqrt(2); + + /*************** + * OTHER STUFF * + ***************/ + + static int counter = 0; + + static Random random = new Random(); + static double thetaMax = .1; + static double thetaMin = .03; + /** + * + * @return a random angle theta, with no form factor. + */ + public static double getRandomThetaBare(){ + double r = random.nextDouble(); + double dTheta = (thetaMax-thetaMin)/4; + double theta = (thetaMax+thetaMin)/2; + int nIter = 11; + for(int i = 0; i< nIter; i++){ + double x = MottIntegral.integral(a, theta); + double f = (x-xmin)/(xmax-xmin); + if(f<r){ + theta += dTheta; + } else if(f> r){ + theta -= dTheta; + } + dTheta /= 2; + } + return theta; + + + } + + static double combine(double theta, double rms){ + return theta + sqrt2 *rms*random.nextGaussian(); + } + + + /** + * + * @param a recoil factor = 2*E/M + * @return a random angle theta, with no form factor. + */ + public static double getRandomThetaWithFormFactor(FormFactor f){ + while(true){ + double theta = getRandomThetaBare(); + double trigstuff = pow(sin(theta/2), 2); + double Q2 = 4*E*E*trigstuff/(1+a*trigstuff); + counter ++; + double f2 = f.getFormFactorSquared(Q2); + if(f2 > random.nextDouble()) + return theta; + } + } + + + + static double b = -1; + + + + + static boolean radCorrections = false; + static int Nevents; + static double M, E, Q, aDensity; + static int Z; + static double a, xmax, xmin; + static boolean display; + + + private static CustomBinning cb; + public static void main(String arg[]) throws IOException{ + String filename = arg[0]; + M = Double.parseDouble(arg[1]); + E = Double.parseDouble(arg[2]); + thetaMin = Double.parseDouble(arg[3]); + thetaMax = Double.parseDouble(arg[4]); + Z = Integer.parseInt(arg[5]); + + String outfile = null; + aDensity = Double.parseDouble(arg[6]); + Q = Double.parseDouble(arg[7]); + + radCorrections = Boolean.parseBoolean(arg[8]); + + if(arg.length>9){ + display = true; + cb = new CustomBinning(new File(arg[9])); + outfile = arg[10]; + } + + + a = 2*E/(M*amu); + xmin = MottIntegral.integral(a, thetaMin); + xmax = MottIntegral.integral(a, thetaMax); + + double scale = Math.pow((Z*alpha*hbarc)/(2*E), 2)/100; //this should be in barns + double sigma = MottIntegral.mottIntegralWithFormFactor(a, scale, thetaMin, thetaMax, FormFactor.get(Z), 1000, E); + + double luminosity = Q*1e-9/q*aDensity/(M/Na)*1e-24; + Nevents = (int)(sigma*luminosity); + + + System.out.println(Nevents); + + String title = "fee"; + String comment = "fee"; + StdhepWriter writer = new StdhepWriter(filename, title, comment, Nevents); + IAnalysisFactory af = null; + ITree tree = null; + + if(display){ + af = IAnalysisFactory.create(); + tree = af.createTreeFactory().create(outfile,"xml",false,true); + IHistogramFactory hf = af.createHistogramFactory(tree); + + double thetaBins[] = new double[cb.nTheta+1]; + for(int i = 0; i<cb.nTheta; i++){ + thetaBins[i] = cb.thetaMin[i]; + } + + thetaBins[thetaBins.length-1] = cb.thetaMax[cb.nTheta-1]; + + thetaHist = hf.createHistogram1D("theta", "theta", thetaBins); + + EHist = hf.createHistogram1D("energy", 50, 0, 1.3); + IPlotter p = af.createPlotterFactory().create(); + p.createRegions(2,1); + p.region(0).plot(thetaHist); + p.region(1).plot(EHist); + p.show(); + } + + for(int i = 1; i<= Nevents; i++){ + int nevhep = i; + int nhep = 1; + int[] isthep = {1}; + int[] idhep = {11}; + int[] jmohep = {0,0}; + int[] jdahep = {0,0}; + double[] phep = randomMomentum(); + double[] vhep = {0,0,0,0}; + + + if(phep[3] > .5*E){ + StdhepEvent event = new StdhepEvent(nevhep, nhep, isthep, idhep, jmohep, jdahep, phep, vhep); + if(display) + EHist.fill(phep[3]*(1+random.nextGaussian()*.045)); + writer.writeRecord(event); + } + else{ // if the event has enough energy loss, + // write it out as a blank event. This way, + // slic doesnt have to deal with low energy electrons + // + StdhepEvent event = new StdhepEvent(i, 0, + new int[0], + new int[0], + new int[0], + new int[0], + new double[0], + new double[0]); + writer.writeRecord(event); + } + if(i%1000 == 0) + System.out.println("event " + i); + } + writer.close(); + if(tree != null) + tree.commit(); + + /* + String title = arg[0+10*set]; + String inputFile = arg[1+10*set]; + CustomBinning cb = new CustomBinning(new File(arg[2+10*set])); + + + double Q = Double.parseDouble(arg[3+10*set]); //in nC + double E = Double.parseDouble(arg[4+10*set]); //in GeV + double aDensity = Double.parseDouble(arg[5+10*set]); //in g/cm^2 + double M = Double.parseDouble(arg[6+10*set]); // in amu + double Z = Double.parseDouble(arg[7+10*set]); + double r = Double.parseDouble(arg[8+10*set]); + double prescale = Math.pow(2,Double.parseDouble(arg[9+10*set])); + */ + if(display){ + ExtractFormFactors.main(new String[]{ + "generated", + outfile, + arg[9], + Double.toString(Q), + Double.toString(E), + Double.toString(aDensity), + Double.toString(M), + Double.toString(Z), + "3", //not used + "0" //no prescale + + }); + + displayResiduals(); + + } + } + + private static void displayResiduals() { + IAnalysisFactory af = IAnalysisFactory.create(); + IDataPointSetFactory dpsf = af.createDataPointSetFactory(af.createTreeFactory().create()); + IDataPointSet residuals = dpsf.create("residuals", 2); + for(int i = 0; i<ExtractFormFactors.dpsMeasured[0].size(); i++){ + IDataPoint gen = ExtractFormFactors.dpsMeasured[0].point(i); + IDataPoint the = ExtractFormFactors.dpsTheory.point(i); + + IDataPoint res = residuals.addPoint(); + res.coordinate(0).setValue(gen.coordinate(0).value()); + res.coordinate(1).setValue(gen.coordinate(1).value()-the.coordinate(1).value()); + double err = Math.hypot(gen.coordinate(1).errorMinus(), the.coordinate(1).errorMinus()); + res.coordinate(1).setErrorMinus(err); + res.coordinate(1).setErrorPlus(err); + } + IPlotter p = af.createPlotterFactory().create(); + p.region(0).plot(residuals); + p.show(); + + } + + + + static IHistogram1D thetaHist = null, EHist; + + + + private static double[] randomMomentum() { + double theta = getRandomThetaWithFormFactor(FormFactor.get(Z)); + double phi = random.nextDouble()*2*PI-PI; + if(thetaHist != null) + if(cb.inRange(theta, phi)) + thetaHist.fill(theta); + double trigstuff = pow(sin(theta/2.), 2); + double Ep = E/(1+a*trigstuff); + double m = .000511; + + + + if(radCorrections){ + + // L.W. Mo, Y.S. Tsai, Radiative Corrections to Elastic and inelastic ep and $\mu$p scattering + // Stanford Linear Accelerator Center, Stanford University, Stanford, CA + // Reviews of Modern Physics Volume 41 Number 1, January 1969 + + //otherwise apply radiative corrections + double Q2 = 4*E*Ep*trigstuff; + + //effective number of pre and post radiation lengths caused by radiative effects + double t = 3/4.*(alpha/Math.PI)*(Math.log(Q2/(me*me)-1)); + + // rms theta for + double theta_rms = MultipleScattering.getThetaRMS(t, E); + theta = combine(theta, theta_rms); + + if(b == -1){ + b = MultipleScattering.b(Z); + } + double bt = b*t; + Ep *= MultipleScattering.getRandomEnergyFraction(bt)*MultipleScattering.getRandomEnergyFraction(bt); + + } + if(Double.isNaN(Ep)) + return null; + double p = sqrt(Ep*Ep-m*m); + return new double[]{p*sin(theta)*cos(phi), p*sin(theta)*sin(phi), p*cos(theta), Ep, m}; + } +} Added: java/trunk/users/src/main/java/org/hps/users/spaul/feecc/FormFactor.java ============================================================================= --- java/trunk/users/src/main/java/org/hps/users/spaul/feecc/FormFactor.java (added) +++ java/trunk/users/src/main/java/org/hps/users/spaul/feecc/FormFactor.java Sun Jan 3 10:18:03 2016 @@ -0,0 +1,43 @@ +package org.hps.users.spaul.feecc; + +public abstract class FormFactor { + + abstract double getFormFactor(double q2); + + double getFormFactorSquared(double q2){ + return Math.pow(getFormFactor(q2), 2); + } + static double hbarc = .197; + static FormFactor carbon = new FormFactor(){ + + @Override + public double getFormFactor(double Q2) { + double Z= 6; + double rp = 0.8786; + double a = 1.64; + double b = Math.sqrt(a*a*(1-1/12.)+rp*rp); + return (1-(Z-2)/(6*Z)*a*a*Q2/(hbarc*hbarc))*Math.exp(-1/4.*b*b*Q2/(hbarc*hbarc)); + } + + }; + static FormFactor tungsten = new FormFactor(){ + + @Override + public double getFormFactor(double Q2) { + double Z= 74; + double r = 6.87; + double x = Math.sqrt(Q2*r*r/(hbarc*hbarc)); + double F_calc = 3/(x*x*x)*(Math.sin(x)-x*Math.cos(x)); + return F_calc; + } + + }; + static FormFactor get(int Z){ + if(Z == 6) + return carbon; + if(Z == 74) + return tungsten; + System.err.println("Form Factor for " + Z + " not implemented"); + return null; + } +} Modified: java/trunk/users/src/main/java/org/hps/users/spaul/feecc/MakeHistograms.java ============================================================================= --- java/trunk/users/src/main/java/org/hps/users/spaul/feecc/MakeHistograms.java (original) +++ java/trunk/users/src/main/java/org/hps/users/spaul/feecc/MakeHistograms.java Sun Jan 3 10:18:03 2016 @@ -2,12 +2,15 @@ import java.io.File; import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.Date; import java.util.List; import org.hps.conditions.ConditionsDriver; +import org.hps.recon.tracking.TrackType; import org.hps.record.triggerbank.AbstractIntData; import org.hps.record.triggerbank.TIData; import org.lcsim.event.CalorimeterHit; @@ -15,9 +18,12 @@ import org.lcsim.event.EventHeader; import org.lcsim.event.GenericObject; import org.lcsim.event.ReconstructedParticle; +import org.lcsim.event.Track; +import org.lcsim.event.TrackState; import org.lcsim.lcio.LCIOReader; import hep.aida.IAnalysisFactory; +import hep.aida.IDataPointSetFactory; import hep.aida.IHistogram1D; import hep.aida.IHistogram2D; import hep.aida.IHistogramFactory; @@ -29,6 +35,9 @@ import org.hps.users.spaul.StyleUtil; public class MakeHistograms { + + + static boolean display = false; static CustomBinning cb; public static void main(String arg[]) throws IllegalArgumentException, IOException{ @@ -40,11 +49,11 @@ path = "temp.aida"; } IAnalysisFactory af = IAnalysisFactory.create(); - ITreeFactory tf = af.createTreeFactory(); + ITreeFactory tf = af.createTreeFactory(); ITree tree0 = tf.create(path, "xml"); extractHistograms(tree0); setupPlotter(af); - + } else{ String input = arg[0]; @@ -86,104 +95,206 @@ } } - + static IHistogram2D h1, h2, h2a, h2b, h2c; static IHistogram2D h4,h4a; - static IHistogram1D h3, h3a; - static IHistogram1D h5, h6; - + static IHistogram1D h3, h3a, h3_t, h3_b; + static IHistogram1D h5, h5a; + static IHistogram2D h6, h6a; + static IHistogram1D h7, h7a; + static IHistogram1D h8; + static IHistogram1D h9_t, h9_b; + static IHistogram1D h10_t, h10_b; + private static void extractHistograms(ITree tree0) { + h1 = (IHistogram2D) tree0.find("theta vs energy"); + h2 = (IHistogram2D) tree0.find("theta vs phi"); h2a = (IHistogram2D) tree0.find("theta vs phi cut"); h2b = (IHistogram2D) tree0.find("theta vs phi cut alt"); h2c = (IHistogram2D) tree0.find("theta vs phi alt"); - + h3 = (IHistogram1D) tree0.find("theta"); + h3a = (IHistogram1D) tree0.find("theta isolated "); + h3_t = (IHistogram1D) tree0.find("theta top"); + h3_b = (IHistogram1D) tree0.find("theta bottom"); + h4 = (IHistogram2D) tree0.find("px\\/pz vs py\\/pz"); h4a = (IHistogram2D) tree0.find("px\\/pz vs py\\/pz cut"); - h5 = (IHistogram1D) tree0.find("energy"); - + System.out.println(h4a.xAxis().bins()); + h5 = (IHistogram1D) tree0.find("energy top"); + h5 = (IHistogram1D) tree0.find("energy bottom"); + + h6 = (IHistogram2D) tree0.find("cluster"); + h6a = (IHistogram2D) tree0.find("cluster matched"); + h7 = (IHistogram1D) tree0.find("y top"); + h7a = (IHistogram1D) tree0.find("y bottom"); + h8 = (IHistogram1D) tree0.find("seed energy"); + + + h9_t = (IHistogram1D) tree0.find("pz top"); + h9_b = (IHistogram1D) tree0.find("pz bottom"); + + + h10_t = (IHistogram1D) tree0.find("clustsize top"); + h10_b = (IHistogram1D) tree0.find("clustsize bottom"); + } static void setupHistograms(IHistogramFactory hf){ //h1 = hf.createHistogram2D("px\\/pz vs py\\/pz", 160, -.16, .24, 160, -.2, .2); - - - - + + + + h2 = hf.createHistogram2D("theta vs phi", 300, 0, .3, 314, -3.14, 3.14); - + h2a = hf.createHistogram2D("theta vs phi cut", 300, 0, .3, 314, -3.14, 3.14); double thetaBins[] = new double[cb.nTheta+1]; for(int i = 0; i<cb.nTheta; i++){ thetaBins[i] = cb.thetaMin[i]; } - + thetaBins[thetaBins.length-1] = cb.thetaMax[cb.nTheta-1]; double phiBins[] = new double[315]; for(int i = 0; i<315; i++){ phiBins[i] = i/50.-3.14; //every 10 mrad; } - + + double eBins[] = new double[66]; + for(int i = 0; i<66; i++){ + eBins[i] = i/50.; //every 20 MeV up to 1300 MeV + } + + + h1 = hf.createHistogram2D("theta vs energy", "theta vs energy", thetaBins, eBins); + + //identical to h2a, except different binning h2b = hf.createHistogram2D("theta vs phi cut alt", "theta vs phi cut alt", thetaBins, phiBins); h2c = hf.createHistogram2D("theta vs phi alt", "theta vs phi alt", thetaBins, phiBins); - + h3 = hf.createHistogram1D("theta", "theta", thetaBins); - - h4 = hf.createHistogram2D("px\\/pz vs py\\/pz", 160, -.16, .24, 160, -.2, .2); - h4a = hf.createHistogram2D("px\\/pz vs py\\/pz cut", 160, -.16, .24, 160, -.2, .2); - - h5 = hf.createHistogram1D("energy", 75, 0, 1.5); + h3a = hf.createHistogram1D("theta isolated ", "theta isolated", thetaBins); + + h3_t = hf.createHistogram1D("theta top", "theta top", thetaBins); + h3_b = hf.createHistogram1D("theta bottom", "theta bottom", thetaBins); + + + h4 = hf.createHistogram2D("px\\/pz vs py\\/pz", 300, -.16, .24, 300, -.2, .2); + h4a = hf.createHistogram2D("px\\/pz vs py\\/pz cut", 300, -.16, .24, 300, -.2, .2); + + h5 = hf.createHistogram1D("energy top", 75, 0, 1.5); + h5a = hf.createHistogram1D("energy bottom", 75, 0, 1.5); + + + h9_t = hf.createHistogram1D("pz top", 75, 0, 1.5); + h9_b = hf.createHistogram1D("pz bottom", 75, 0, 1.5); + + h6 = hf.createHistogram2D("cluster", 47, -23.5, 23.5, 11, -5.5, 5.5); + h6a = hf.createHistogram2D("cluster matched", 47, -23.5, 23.5, 11, -5.5, 5.5); + + h7 = hf.createHistogram1D("y top", 500, 0, 100); + + h7a = hf.createHistogram1D("y bottom", 500, 0, 100); + + h8 = hf.createHistogram1D("seed energy", 120, 0, 1.2); + + h10_t = hf.createHistogram1D("clustsize top", 10,0, 10); + h10_b = hf.createHistogram1D("clustsize bottom", 10,0, 10); } static void setupPlotter(IAnalysisFactory af){ IPlotterFactory pf = af.createPlotterFactory(); IPlotter p = pf.create(); p.createRegions(2,2); p.region(0).plot(h2); - StyleUtil.stylize(p.region(0), "theta", "phi"); - p.region(1).plot(h2a); - StyleUtil.stylize(p.region(1), "theta", "phi"); + p.region(1).plot(h3a); + StyleUtil.stylize(p.region(1), "theta", "# of particles"); p.region(2).plot(h3); StyleUtil.stylize(p.region(2), "theta", "# of particles"); p.region(3).plot(h5); + p.region(3).plot(h5a); StyleUtil.stylize(p.region(3), "energy", "# of particles"); - + p.show(); + //new window for the next plot IPlotter p2 = pf.create(); p2.region(0).plot(h2b); + //IDataPointSetFactory dpsf = af.createDataPointSetFactory(af.createTreeFactory().create()); + StyleUtil.stylize(p2.region(0), "theta", "phi"); - + p2.show(); - + //new window for the next plot IPlotter p3 = pf.create(); p3.region(0).plot(h2c); StyleUtil.stylize(p3.region(0), "theta", "phi"); - + p3.show(); - + //new window for the next plot IPlotter p4 = pf.create(); p4.region(0).plot(h4); StyleUtil.stylize(p4.region(0), "px/pz", "py/pz"); - + p4.show(); - + //new window for the next plot IPlotter p5 = pf.create(); p5.region(0).plot(h4a); StyleUtil.stylize(p5.region(0), "px/pz", "py/pz"); - + p5.show(); + + IPlotter p6 = pf.create("efficiency"); + p6.createRegions(1,2); + p6.region(0).plot(h6); + StyleUtil.stylize(p6.region(0), "ix", "iy"); + p6.region(1).plot(h6a); + StyleUtil.stylize(p6.region(1), "ix", "iy"); + p6.show(); + + IPlotter p7 = pf.create("theta vs energy"); + //p6.createRegions(1,2); + p7.region(0).plot(h1); + StyleUtil.stylize(p7.region(0), "theta", "energy"); + // StyleUtil.stylize(p6.region(1), "ix", "iy"); + p7.show(); + + IPlotter p8 = pf.create("y"); + //p6.createRegions(1,2); + p8.region(0).plot(h7); + p8.region(0).plot(h7a); + StyleUtil.stylize(p8.region(0), "y", "# of particles"); + // StyleUtil.stylize(p6.region(1), "ix", "iy"); + p8.show(); + + IPlotter p9 = pf.create("theta: top vs. bottom"); + //p6.createRegions(1,2); + p9.region(0).plot(h3_t); + p9.region(0).plot(h3_b); + StyleUtil.stylize(p9.region(0), "theta", "theta", "# of particles"); + StyleUtil.noFillHistogramBars(p9.region(0)); + StyleUtil.stylize(p6.region(1), "ix", "iy"); + p9.show(); + + IPlotter p10 = pf.create("seed energy"); + //p6.createRegions(1,2); + p10.region(0).plot(h8); + StyleUtil.stylize(p10.region(0), "seed energy", "seed energy (GeV)", "# of particles"); + //StyleUtil.noFillHistogramBars(p10.region(0)); + StyleUtil.stylize(p6.region(1), "ix", "iy"); + p10.show(); + } private static void processEvent(EventHeader event) { - if(event.getEventNumber() %1000 == 0) + if(event.getEventNumber() %10000 == 0) System.out.println("event number " + event.getEventNumber()); - + for (GenericObject gob : event.get(GenericObject.class,"TriggerBank")) { if (!(AbstractIntData.getTag(gob) == TIData.BANK_TAG)) continue; @@ -194,11 +305,61 @@ } } List<ReconstructedParticle> particles = event.get(ReconstructedParticle.class, "FinalStateParticles"); - - for(ReconstructedParticle p : particles){ + particles = RemoveDuplicateParticles.removeDuplicateParticles(particles); + outer : for(ReconstructedParticle p : particles){ + //check if this is a duplicate particle (ie, different track same cluster) + /*for(ParticleInfo cand : candidates){ + if(p.getEnergy() == cand.E && cand.isGood == true) + continue outer; + }*/ boolean isGood = addParticle(p); - + if(!isGood){ + if(p.getClusters().size()!= 0) + candidates.add(new ParticleInfo(0, p.getEnergy(), p.getClusters().get(0).getCalorimeterHits().get(0).getTime(), false)); + + } + + } + for(ParticleInfo c : candidates){ + if(c.isGood){ + boolean isIsolated = true; + for(ParticleInfo c2 :candidates){ + //try to remove events that have possible mollers in them. + //correct for this later. + if(Math.abs(c2.t - c.t) < 2.5 && c2.E < .3 && c2 != c){ + isIsolated = false; + break; + } + } + if(isIsolated){ + h3a.fill(c.theta); + } + } + } + candidates.clear(); + processEventEfficiency(particles); + } + + private static void processEventEfficiency(List<ReconstructedParticle> parts) { + for(ReconstructedParticle p : parts){ + if(p.getClusters().size() == 0) + continue; + if(!(p.getEnergy() > eMin && p.getEnergy() < eMax)) + continue; + Cluster c = p.getClusters().get(0); + if(!EcalUtil.fid_ECal(c) || c.getCalorimeterHits().size() < 3) + continue; + //good cluster? now continue + int ixiy[] = EcalUtil.getCrystalIndex(c); + + h6.fill(ixiy[0], ixiy[1]); + if(p.getTracks().size() == 0) + continue; + Track t = p.getTracks().get(0); + if(t.getChi2()> maxChi2) + continue; + h6a.fill(ixiy[0], ixiy[1]); } } @@ -209,44 +370,129 @@ static double beamTilt = .03057; static double maxChi2 = 50; + //maximum difference between the reconstructed energy and momentum + static double maxdE = .3; + + static double seedEnergyCut = .4; + + + static ArrayList<ParticleInfo> candidates = new ArrayList(); static boolean addParticle(ReconstructedParticle part){ - - if(part.getTracks().size() == 0) + + + + if(part.getCharge() != -1) return false; - if(part.getTracks().get(0).getChi2()>maxChi2){ - return false; - } if(part.getClusters().size() == 0) return false; Cluster c = part.getClusters().get(0); double time = c.getCalorimeterHits().get(0).getTime(); + + if(!(time>40 && time <50)) + return false; + double seedEnergy = 0; + for(CalorimeterHit hit : c.getCalorimeterHits()){ + if(hit.getCorrectedEnergy() > seedEnergy) + seedEnergy = hit.getCorrectedEnergy(); + } + h8.fill(seedEnergy); + + + if(seedEnergy < seedEnergyCut) + return false; + + if(c.getPosition()[1] > 0){ + h10_t.fill(c.getSize()); + } + else{ + h10_b.fill(c.getSize()); + } + + + if(c.getCalorimeterHits().size() < 3) + return false; + + + if(c.getEnergy() > eMin && c.getEnergy() < eMax){ + if(c.getPosition()[1] > 0) + h7.fill(c.getPosition()[1]); + else if(c.getPosition()[1] < 0) + h7a.fill(-c.getPosition()[1]); + } + if(EcalUtil.fid_ECal(c)){ - if(c.getCalorimeterHits().size() < 3) + + if(part.getTracks().size() == 0) return false; - if(time>40 && time <48) + Track t = part.getTracks().get(0); + if(t.getChi2()>maxChi2){ + return false; + } + if(!TrackType.isGBL(t.getType())) + return false; + if(c.getPosition()[1] > 0){ h5.fill(c.getEnergy()); - if(c.getEnergy() > eMin && c.getEnergy() < eMax && (time >40 && time < 48)) { - - Hep3Vector p = part.getMomentum(); - - double px = p.x(), pz = p.z(); - double pxtilt = px*Math.cos(beamTilt)-pz*Math.sin(beamTilt); - double py = p.y(); - double pztilt = pz*Math.cos(beamTilt)+px*Math.sin(beamTilt); - - double theta = Math.atan(Math.hypot(pxtilt, py)/pztilt); - double phi =Math.atan2(py, pxtilt); + } + else{ + h5a.fill(c.getEnergy()); + } + + + Hep3Vector p = part.getMomentum(); + + + + double px = p.x(), pz = p.z(); + double pxtilt = px*Math.cos(beamTilt)-pz*Math.sin(beamTilt); + double py = p.y(); + double pztilt = pz*Math.cos(beamTilt)+px*Math.sin(beamTilt); + + if(Math.abs(pztilt - c.getEnergy()) > maxdE) + return false; + if(c.getPosition()[1] > 0) + h9_t.fill(pztilt); + else + h9_b.fill(pztilt); + + double theta = Math.atan(Math.hypot(pxtilt, py)/pztilt); + double phi =Math.atan2(py, pxtilt); + boolean inRange = cb.inRange(theta, phi); + if(inRange) + h1.fill(theta, c.getEnergy()); + + + + if(c.getEnergy() > eMin && c.getEnergy() < eMax) { + + h2.fill(theta, phi); h2c.fill(theta, phi); - + h4.fill(px/pz, py/pz); - - if(cb.inRange(theta, phi)){ + + if(inRange){ + + //System.out.println(c.getEnergy() + " " + t.getType()); + /*for(TrackState ts : t.getTrackStates()){ + if(ts.getLocation() == TrackState.AtIP) + System.out.println(Arrays.toString( + ts.getReferencePoint())); + }*/ h2a.fill(theta, phi); h2b.fill(theta, phi); + h3.fill(theta); + if(py > 0) + h3_t.fill(theta); + else + h3_b.fill(theta); + //if(h3_t.sumBinHeights()+h3_b.sumBinHeights() != h3.sumBinHeights()) + //System.out.println("NABO ERROR"); + + h4a.fill(px/pz, py/pz); + candidates.add(new ParticleInfo(theta, c.getEnergy(), c.getCalorimeterHits().get(0).getTime(), true)); } @@ -256,5 +502,16 @@ } return false; } - + static class ParticleInfo{ + double theta; + double E; + double t; + boolean isGood; + ParticleInfo(double theta, double E, double t, boolean isGood){ + this.theta = theta; + this.E = E; + this.t = t; + this.isGood = isGood; + } + } } Added: java/trunk/users/src/main/java/org/hps/users/spaul/feecc/MottIntegral.java ============================================================================= --- java/trunk/users/src/main/java/org/hps/users/spaul/feecc/MottIntegral.java (added) +++ java/trunk/users/src/main/java/org/hps/users/spaul/feecc/MottIntegral.java Sun Jan 3 10:18:03 2016 @@ -0,0 +1,66 @@ +package org.hps.users.spaul.feecc; + +public class MottIntegral { + /** + * @param bin + * @param scale = Z^2alpha^2/(4*E^2) + * @param recoil = 2E/M + * @return the integral of 1/sin^4(th/2)*cos^2(th/2)/(1+a*sin^2(th/2)) times dPhi*sin(theta), + * which appears in the integral of mott scattering. + * + * NOTE the sin(theta) is because dOmega = dTheta*dPhi*sin(theta) + */ + static double mottIntegral(double recoil, double scale, int bin, CustomBinning cb){ + double dPhi = 0; + for(int i = 0; i< cb.phiMax[bin].length; i++) + dPhi += 2*(cb.phiMax[bin][i] - cb.phiMin[bin][i]); //factor of 2 from top and bottom + + double Imax = integral(recoil, cb.thetaMax[bin]); + + double Imin = integral(recoil, cb.thetaMin[bin]); + double dI = Imax-Imin; + + + double retval = scale*dPhi*dI; + return retval; + } + + static double mottIntegral(double recoil, double scale, double thetaMin, double thetaMax){ + double Imax = integral(recoil, thetaMax); + + double Imin = integral(recoil, thetaMin); + double dI = Imax-Imin; + + double dPhi = 2*Math.PI; //full range in phi + double retval = scale*dPhi*dI; + return retval; + } + + static double integral(double a, double th){ + double sinth22 = Math.pow(Math.sin(th/2), 2); + return 2*(-1/sinth22+(1+a)*(Math.log(2/sinth22+2*a))); + } + + static double mottIntegralWithFormFactor(double recoil, double scale, double thetaMin, double thetaMax, FormFactor ff, int nsteps, double E){ + double sum = 0; + double prev = -1; + + double dTheta = (thetaMax-thetaMin)/nsteps; + for(int i = 0; i<nsteps; i++){ + double theta = i*(thetaMax-thetaMin)/nsteps+thetaMin; + double I = integral(recoil, theta); + if(i != 0) + { + double ts = Math.pow(Math.sin(theta/2),2); + double q2 = 4*E*E*ts/(1+recoil*ts); + double f2 = ff.getFormFactorSquared(q2); + sum+= (I-prev)*f2; + } + prev = I; + + } + double dPhi = 2*Math.PI; //full range in phi + double retval = scale*dPhi*sum; + return retval; + } +} Added: java/trunk/users/src/main/java/org/hps/users/spaul/feecc/MultipleScattering.java ============================================================================= --- java/trunk/users/src/main/java/org/hps/users/spaul/feecc/MultipleScattering.java (added) +++ java/trunk/users/src/main/java/org/hps/users/spaul/feecc/MultipleScattering.java Sun Jan 3 10:18:03 2016 @@ -0,0 +1,106 @@ +package org.hps.users.spaul.feecc; + +import hep.aida.IAnalysisFactory; +import hep.aida.IHistogram1D; +import hep.aida.IHistogramFactory; +import hep.aida.IPlotter; + +import java.util.Random; + +public class MultipleScattering { + + + /* + V.L. Highland, Nucl. Instrum. Methods 129, 497 (1975); Nucl. Instrum. Methods 161, 171 (1979) + + G.R. Lynch and O.I. Dahl, Nucl. Instrum. Methods B58, 6 (1991). + + */ + /** + * @param t number of scattering lengths + * @param p momentum in GeV/c + * @return the rms scattering angle of an electron with beta == 1. + */ + static double getThetaRMS(double t, double p){ + return .0136/p*Math.sqrt(t)*(1+.038*Math.log(t)); + } + /** + * Mo Tsai equations A.4-5 + * @param Z + * @return + */ + static double b(int Z){ + double xi = Math.log(1440.*Math.pow(Z, -2/3.))/Math.log(183.*Math.pow(Z,-1/3.)); + System.out.println(xi); + return 4/3.*(1+1/9.*(Z+1.)/(Z+xi)/Math.log(183.*Math.pow(Z,-1/3.))); + + + } + + + public static void main(String arg[]){ + + System.out.println(b(6)); + System.out.println(b(74)); + + double bt = 0.03; + + IAnalysisFactory af = IAnalysisFactory.create(); + IHistogramFactory hf = af.createHistogramFactory(af.createTreeFactory().create()); + IHistogram1D h = hf.createHistogram1D("x", 100, 0, 1.5); + IPlotter p = af.createPlotterFactory().create(); + p.region(0).plot(h); + p.show(); + for(int i = 0; i< 100000; i++){ + h.fill(getRandomEnergyFraction(bt)*getRandomEnergyFraction(bt)*(1+r.nextGaussian()*.045)*1.056); + } + } + + static double pdf(double x, double bt){ + return bt/(1-x)*(x+3/4.*(1-x)*(1-x))*Math.pow(Math.log(1./x), bt); + } + static Random r = new Random(); + /************************** + * CONFIGURABLE VARIABLES * + **************************/ + /** + * step size in x + */ + static double dx = .001; + /** + * starting distance from peak to begin numerical integration + */ + static double delta0 = .05; + + /** + * fraction of the energy to cut off at. (all events with less than this energy will be blanked out, + * and therefore not simulated in slic. Slic was having problems dealing with low energy events. + */ + static double xCutoff = .5; + + static double getRandomEnergyFraction(double bt){ + double p = r.nextDouble(); + if(p< Math.pow(delta0, bt)){ + return 1-Math.pow(p, 1/bt); + } + double sum = Math.pow(delta0,bt); + if(sum > p){ + return 1; + } + double x = 1-delta0; + while(true){ + double contribution = pdf(x, bt)*dx; + if(sum + contribution > p) + { + return x - (p-sum)/contribution*dx; + } + if(x < 0) + { + return 0; + } + x -= dx; + sum += contribution; + } + //return 1; + } +} Modified: java/trunk/users/src/main/java/org/hps/users/spaul/feecc/ShowCustomBinning.java ============================================================================= --- java/trunk/users/src/main/java/org/hps/users/spaul/feecc/ShowCustomBinning.java (original) +++ java/trunk/users/src/main/java/org/hps/users/spaul/feecc/ShowCustomBinning.java Sun Jan 3 10:18:03 2016 @@ -2,10 +2,16 @@ import java.awt.Canvas; import java.awt.Color; +import java.awt.Container; +import java.awt.Font; import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.image.BufferedImage; import java.io.File; import java.io.FileNotFoundException; - +import java.io.IOException; + +import javax.imageio.ImageIO; import javax.swing.JFrame; import hep.aida.IAnalysisFactory; @@ -27,15 +33,47 @@ public static void main(String arg[]) throws FileNotFoundException{ JFrame frame = new JFrame(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); - frame.add(new ShowCustomBinning(new File(arg[0]))); - frame.setSize(800, 800); + Canvas c = new ShowCustomBinning(new File(arg[0])); + String outdir = arg[1]; + frame.add(c); + frame.setSize(1200, 800); frame.setVisible(true); + + try { + BufferedImage im = new BufferedImage(c.getWidth(), c.getHeight(), BufferedImage.TYPE_INT_ARGB); + c.paint(im.getGraphics()); + ImageIO.write(im, "PNG", new File(outdir +"/bins.png")); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + frame = new JFrame(); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + c = new ShowCustomBinningXY(new File(arg[0])); + frame.add(c); + frame.setSize(1200, 615); + frame.setVisible(true); + + try { + BufferedImage im = new BufferedImage(c.getWidth(), c.getHeight(), BufferedImage.TYPE_INT_ARGB); + c.paint(im.getGraphics()); + ImageIO.write(im, "PNG", new File(outdir + "/bins_xy.png")); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } } public void paint(Graphics g){ + g.setFont(new Font(Font.DIALOG, Font.PLAIN, 24)); + drawEcalOutline(g); drawFidEcalOutline(g); drawCustomBinRectangles(g); + g.setColor(Color.BLACK); + drawXAxis(g); + drawYAxis(g); } void drawFidEcalOutline(Graphics g){ @@ -95,15 +133,24 @@ } void drawEcalOutline(Graphics g){ + /*double x_edge_low = -262.74; + double x_edge_high = 347.7; + double y_edge_low = 33.54; + double y_edge_high = 75.18; + + double x_gap_low = -106.66; + double x_gap_high = 42.17; + double y_gap_high = 47.18;*/ + g.setColor(Color.BLACK); - double x_edge_low = -276.50; - double x_edge_high = 361.55; - double y_edge_low = 20.17; - double y_edge_high = 89; - - double x_gap_low = -93.30; - double x_gap_high = 28.93; - double y_gap_high = 33.12; + double x_edge_low = -269.56; + double x_edge_high = 354.52; + double y_edge_low = 26.72; + double y_edge_high = 82; + + double x_gap_low = -99.84; + double x_gap_high = 33.35; + double y_gap_high = 40.36; double x1,y1, x2, y2; double nPoints = 500; for(int i = 0; i< nPoints-1; i++){ @@ -157,6 +204,8 @@ } Color altBin1 = new Color(0, 0, 128); Color altBin2 = new Color(0,128,0); + Color fillBin1 = new Color(196, 196, 255); + Color fillBin2 = new Color(196,255,196); void drawCustomBinRectangles(Graphics g){ for(int i = 0; i<binning.nTheta; i++){ g.setColor(i%2 == 0 ? altBin1 : altBin2); @@ -167,13 +216,45 @@ double theta2 = binning.thetaMax[i]; int x =getX(theta1)+1, y = getY(phi1), w = getX(theta2)-getX(theta1), h = getY(phi2)-getY(phi1); + + g.setColor(i%2 == 0 ? fillBin1 : fillBin2); + g.fillRect(x, y, w, h); + g.setColor(i%2 == 0 ? altBin1 : altBin2); g.drawRect(x, y, w, h); x =getX(theta1)+1; y = getY(-phi2); w = getX(theta2)-getX(theta1); h = getY(-phi1)-getY(-phi2); - - g.drawRect(x, y, w, h); - - + g.setColor(i%2 == 0 ? fillBin1 : fillBin2); + g.fillRect(x, y, w, h); + g.setColor(i%2 == 0 ? altBin1 : altBin2); + g.drawRect(x, y, w, h); } + + } + } + void drawXAxis(Graphics g){ + //x axis + g.drawString("θ", getX(.28), getY(0) - 40); + g.drawLine(getX(0), getY(0), getX(.28), getY(0)); + for(int i = 0; i< 28; i++){ + if(i%5 == 0 && i != 0){ + g.drawString(i/100.+"", getX(i/100.)-15, getY(0)-20); + g.drawLine(getX(i/100.), getY(0), getX(i/100.), getY(0)-15); + } + g.drawLine(getX(i/100.), getY(0), getX(i/100.), getY(0)-5); + } + } + void drawYAxis(Graphics g){ + g.drawString("Ï", getX(0)+70, getY(3)); + g.drawLine(getX(0), getY(-3), getX(0), getY(3)); + for(int i = -30; i<= 30; i++){ + if(i%5 == 0 && i != 0){ + g.drawString(i/10.+"", getX(0)+20, getY(i/10.) + 5); + + g.drawLine(getX(0), getY(i/10.), getX(0) + 15, getY(i/10.)); + } + if(i == 0){ + //g.drawString(i/10.+"", getX(0)+10, getY(i/10.) - 15); + } + g.drawLine(getX(0), getY(i/10.), getX(0) + 5, getY(i/10.)); } } @@ -186,8 +267,9 @@ } int getX(double theta){ - return (int)(this.getWidth()*theta/.3); - } + return (int)(this.getWidth()*theta/.3)+left_margin; + } + int left_margin = 20; int getY(double phi){ return (int)(this.getHeight()*(3.2-phi)/6.4); } Added: java/trunk/users/src/main/java/org/hps/users/spaul/feecc/ShowCustomBinningXY.java ============================================================================= --- java/trunk/users/src/main/java/org/hps/users/spaul/feecc/ShowCustomBinningXY.java (added) +++ java/trunk/users/src/main/java/org/hps/users/spaul/feecc/ShowCustomBinningXY.java Sun Jan 3 10:18:03 2016 @@ -0,0 +1,227 @@ +package org.hps.users.spaul.feecc; + +import java.awt.Canvas; +import java.awt.Color; +import java.awt.Graphics; +import java.awt.Polygon; +import java.io.File; +import java.io.FileNotFoundException; + +public class ShowCustomBinningXY extends ShowCustomBinning{ + ShowCustomBinningXY(File file) throws FileNotFoundException + { + super(file); + } + @Override + void drawCustomBinRectangles(Graphics g){ + for(int i = 0; i<binning.nTheta; i++){ + g.setColor(i%2 == 0 ? altBin1 : altBin2); + for(int j = 0; j<binning.phiMax[i].length; j++){ + double phi1 = binning.phiMax[i][j]; + double phi2 = binning.phiMin[i][j]; + double theta1 = binning.thetaMin[i]; + double theta2 = binning.thetaMax[i]; + + double nK = 10; + for(int sign = -1; sign <=1; sign +=2){ + for(int k = 0; k< nK; k++){ + drawLineFromPolar(theta1, sign*(phi1+(phi2-phi1)*k/nK), theta1, sign*(phi1+(phi2-phi1)*(k+1)/nK),g); + } + for(int k = 0; k< nK; k++){ + drawLineFromPolar(theta1 + (theta2-theta1)*k/nK, sign*phi2, theta1 + (theta2-theta1)*(k+1)/nK, sign*phi2,g); + } + for(int k = 0; k< nK; k++){ + drawLineFromPolar(theta2, sign*(phi2+(phi1-phi2)*k/nK), theta2, sign*(phi2+(phi1-phi2)*(k+1)/nK),g); + } + for(int k = 0; k< nK; k++){ + drawLineFromPolar(theta2 + (theta1-theta2)*k/nK, sign*phi1, theta2 + (theta1-theta2)*(k+1)/nK, sign*phi1,g); + } + + closePolarFigure(g, i%2 == 0 ? altBin1 : altBin2, i%2 == 0 ? fillBin1 : fillBin2); + } + + } + } + } + Polygon p = null; + private void drawLineFromPolar(double theta1, double phi1, double theta2, + double phi2, Graphics g) { + double[] xy1 = toXY(theta1, phi1); + double[] xy2 = toXY(theta2, phi2); + + if(p == null) + p = new Polygon(); + /*g.drawLine(getX(xy1[0]), + getY(xy1[1]), + getX(xy2[0]), + getY(xy2[1]));*/ + p.addPoint(getX(xy2[0]), getY(xy2[1])); + } + private void closePolarFigure(Graphics g, Color outlineColor, Color fillColor){ + g.setColor(fillColor); + g.fillPolygon(p); + g.setColor(outlineColor); + g.drawPolygon(p); + p = null; + + } + double tilt = .03057; + double[] toXY(double theta, double phi){ + double ux = Math.cos(phi)*Math.sin(theta)*Math.cos(tilt)+Math.cos(theta)*Math.sin(tilt); + double uy = Math.sin(phi)*Math.sin(theta); + double uz = Math.cos(theta)*Math.cos(tilt)-Math.cos(phi)*Math.sin(theta)*Math.sin(tilt); + double pxpz = ux/uz; + double pypz = uy/uz; + return new double[]{pxpz, pypz}; + } + int getX(double pxpz){ + //return (int)((pxpz -(-.16))/(.34-(-.16))*getWidth()); + return (int)((.32-pxpz)/(.32-(-.18))*getWidth()); + } + int getY(double pypz){ + return getHeight()-(int)((pypz -(-.125))/(.125-(-.125))*getHeight()); + } + void drawFidEcalOutline(Graphics g){ + g.setColor(Color.GRAY); + double x_edge_low = -262.74; + double x_edge_high = 347.7; + double y_edge_low = 33.54; + double y_edge_high = 75.18; + + double x_gap_low = -106.66; + double x_gap_high = 42.17; + double y_gap_high = 47.18; + double x1,y1, x2, y2; + double nPoints = 500; + for(int i = 0; i< nPoints-1; i++){ + x1 = x_gap_high+i/nPoints*(x_edge_high-x_gap_high); + x2 = x_gap_high+(i+1)/nPoints*(x_edge_high-x_gap_high); + y1 = y_edge_low; + y2 = y1; + drawEcalFaceLine(g, x1, y1, x2, y2); + drawEcalFaceLine(g, x1, -y1, x2, -y2); + + + x1 = x_edge_low+i/nPoints*(x_gap_low-x_edge_low); + x2 = x_edge_low+(i+1)/nPoints*(x_gap_low-x_edge_low); + y1 = y2 = y_edge_low; + drawEcalFaceLine(g, x1, y1, x2, y2); + drawEcalFaceLine(g, x1, -y1, x2, -y2); + + + + x1 = x_gap_low+i/nPoints*(x_gap_high-x_gap_low); + x2 = x_gap_low+(i+1)/nPoints*(x_gap_high-x_gap_low); + y1 = y2 = y_gap_high; + drawEcalFaceLine(g, x1, y1, x2, y2); + drawEcalFaceLine(g, x1, -y1, x2, -y2); + + x1 = x_edge_low+i/nPoints*(x_edge_high-x_edge_low); + x2 = x_edge_low+(i+1)/nPoints*(x_edge_high-x_edge_low); + y1 = y2 = y_edge_high; + drawEcalFaceLine(g, x1, y1, x2, y2); + drawEcalFaceLine(g, x1, -y1, x2, -y2); + } + drawEcalFaceLine(g, x_gap_low, y_edge_low, x_gap_low, y_gap_high); + drawEcalFaceLine(g, x_gap_high, y_edge_low, x_gap_high, y_gap_high); + + drawEcalFaceLine(g, x_edge_low, y_edge_low, x_edge_low, y_edge_high); + drawEcalFaceLine(g, x_edge_high, y_edge_low, x_edge_high, y_edge_high); + + + drawEcalFaceLine(g, x_gap_low, -y_edge_low, x_gap_low, -y_gap_high); + drawEcalFaceLine(g, x_gap_high, -y_edge_low, x_gap_high, -y_gap_high); + + drawEcalFaceLine(g, x_edge_low, -y_edge_low, x_edge_low, -y_edge_high); + drawEcalFaceLine(g, x_edge_high, -y_edge_low, x_edge_high, -y_edge_high); + + } + + void drawEcalOutline(Graphics g){ + g.setColor(Color.BLACK); + double x_edge_low = -269.56; + double x_edge_high = 354.52; + double y_edge_low = 26.72; + double y_edge_high = 82; + + double x_gap_low = -99.84; + double x_gap_high = 33.35; + double y_gap_high = 40.36; + double x1,y1, x2, y2; + x1 = x_gap_high; + x2 = x_edge_high; + y1 = y_edge_low; + y2 = y1; + drawEcalFaceLine(g, x1, y1, x2, y2); + drawEcalFaceLine(g, x1, -y1, x2, -y2); + + + x1 = x_edge_low; + x2 = x_gap_low; + y1 = y2 = y_edge_low; + drawEcalFaceLine(g, x1, y1, x2, y2); + drawEcalFaceLine(g, x1, -y1, x2, -y2); + + + + x1 = x_gap_low; + x2 = x_gap_high; + y1 = y2 = y_gap_high; + drawEcalFaceLine(g, x1, y1, x2, y2); + drawEcalFaceLine(g, x1, -y1, x2, -y2); + + x1 = x_edge_low; + x2 = x_edge_high; + y1 = y2 = y_edge_high; + drawEcalFaceLine(g, x1, y1, x2, y2); + drawEcalFaceLine(g, x1, -y1, x2, -y2); + + drawEcalFaceLine(g, x_gap_low, y_edge_low, x_gap_low, y_gap_high); + drawEcalFaceLine(g, x_gap_high, y_edge_low, x_gap_high, y_gap_high); + + drawEcalFaceLine(g, x_edge_low, y_edge_low, x_edge_low, y_edge_high); + drawEcalFaceLine(g, x_edge_high, y_edge_low, x_edge_high, y_edge_high); + + + drawEcalFaceLine(g, x_gap_low, -y_edge_low, x_gap_low, -y_gap_high); + drawEcalFaceLine(g, x_gap_high, -y_edge_low, x_gap_high, -y_gap_high); + + drawEcalFaceLine(g, x_edge_low, -y_edge_low, x_edge_low, -y_edge_high); + drawEcalFaceLine(g, x_edge_high, -y_edge_low, x_edge_high, -y_edge_high); + } + void drawEcalFaceLine(Graphics g, double x1, double y1, double x2, double y2){ + + double[] h1 = EcalUtil.toHollysCoordinates(x1, y1, 1.057, 11); + double[] h2 = EcalUtil.toHollysCoordinates(x2, y2, 1.057, 11); + g.drawLine(getX(Math.tan(h1[1])), getY(Math.tan(h1[0])), getX(Math.tan(h2[1])), getY(Math.tan(h2[0]))); + + } + + void drawXAxis(Graphics g){ + //x axis + g.drawString("px/pz", getX(.30)-10, getY(0) - 45); + g.drawLine(getX(-.15), getY(0), getX(.30), getY(0)); + for(int i = -15; i<= 30; i++){ + if(i%5 == 0 && i != 0){ + g.drawString(i/100.+"", getX(i/100.)-15, getY(0)-20); + g.drawLine(getX(i/100.), getY(0), getX(i/100.), getY(0)-15); + } + g.drawLine(getX(i/100.), getY(0), getX(i/100.), getY(0)-5); + } + } + void drawYAxis(Graphics g){ + g.drawString("py/pz", getX(0), getY(.1)-20); + g.drawLine(getX(0), getY(-.1), getX(0), getY(.1)); + for(int i = -10; i<= 10; i++){ + if(i%5 == 0 && i != 0){ + g.drawString(i/100.+"", getX(0)+15, getY(i/100.) + 5); + + g.drawLine(getX(0), getY(i/100.), getX(0) + 10, getY(i/100.)); + } + if(i == 0){ + //g.drawString(i/10.+"", getX(0)+10, getY(i/10.) - 15); + } + g.drawLine(getX(0), getY(i/100.), getX(0) + 5, getY(i/100.)); + } + } +}