Print

Print


Commit in lcsim-analysis/src/main/java/org/lcsim/analysis on MAIN
SinglePhotonAnalysis.java+388added 1.1
Single Photon Energy Resolution analysis code.

lcsim-analysis/src/main/java/org/lcsim/analysis
SinglePhotonAnalysis.java added at 1.1
diff -N SinglePhotonAnalysis.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ SinglePhotonAnalysis.java	17 Jun 2010 17:12:11 -0000	1.1
@@ -0,0 +1,388 @@
+package org.lcsim.analysis;
+
+import hep.aida.IAnalysisFactory;
+import hep.aida.ICloud1D;
+import hep.aida.IDataPoint;
+import hep.aida.IDataPointSet;
+import hep.aida.IDataPointSetFactory;
+import hep.aida.IFitFactory;
+import hep.aida.IFitResult;
+import hep.aida.IFitter;
+import hep.aida.IFunction;
+import hep.aida.IFunctionFactory;
+import hep.aida.IHistogram1D;
+import hep.aida.IPlotter;
+import hep.aida.IPlotterStyle;
+import hep.aida.ITree;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import org.lcsim.event.EventHeader;
+import org.lcsim.event.MCParticle;
+import org.lcsim.event.ReconstructedParticle;
+import org.lcsim.util.Driver;
+import org.lcsim.util.aida.AIDA;
+
+import static java.lang.Math.sqrt;
+
+/**
+ *
+ * @author Norman A. Graf
+ *
+ * @version $Id: SinglePhotonAnalysis.java,v 1.1 2010/06/17 17:12:11 ngraf Exp $
+ */
+public class SinglePhotonAnalysis extends Driver
+{
+
+    private double _expectedResolution;
+    private AIDA aida = AIDA.defaultInstance();
+    private ITree _tree = aida.tree();
+    private boolean _showPlots = true;
+    private String _fileType = "png";
+    private boolean _writeOutAidaFile = false;
+    private String _defaultAidaFileName = "test.aida";
+
+    protected void process(EventHeader event)
+    {
+        // organize the histogram tree by species and energy
+        List<MCParticle> mcparts = event.getMCParticles();
+        MCParticle mcpart = mcparts.get(mcparts.size() - 1);
+        String particleType = mcpart.getType().getName();
+        double mcEnergy = mcpart.getEnergy();
+        long mcIntegerEnergy = Math.round(mcEnergy);
+        boolean meV = false;
+        if (mcEnergy < .99)
+        {
+            mcIntegerEnergy = Math.round(mcEnergy * 1000);
+            meV = true;
+        }
+
+        _tree.mkdirs(particleType);
+        _tree.cd(particleType);
+        _tree.mkdirs(mcIntegerEnergy + (meV ? "_MeV" : "_GeV"));
+        _tree.cd(mcIntegerEnergy + (meV ? "_MeV" : "_GeV"));
+
+        // this analysis is intended for single particle calorimeter response.
+        // let's make sure that the primary particle did not interact in the
+        // tracker...
+        if (mcpart.getSimulatorStatus().isDecayedInCalorimeter())
+        {
+            List<ReconstructedParticle> rpCollection = event.get(ReconstructedParticle.class, "PandoraPFOCollection");
+            // System.out.println("Found "+rpCollection.size()+" ReconstructedParticles");
+            aida.cloud1D("Number of ReconstructedParticles found").fill(rpCollection.size());
+            for (ReconstructedParticle p : rpCollection)
+            {
+                aida.cloud1D("Cluster Energy").fill(p.getEnergy());
+                int id = p.getType();
+                aida.cloud1D("Cluster Energy pid= " + id).fill(p.getEnergy());
+            }
+        }// end of check on whether particle interacted in tracker
+        //reset our histogram tree
+        _tree.cd("/");
+    }
+
+    @Override
+    protected void endOfData()
+    {
+//        String defaultAidaFileName = listOfFilesName + "_" + driver.getClass().getSimpleName() + "_" + date() + ".aida";
+
+        System.out.println("writing aida file to " + _defaultAidaFileName);
+
+
+        try
+        {
+            AIDA.defaultInstance().saveAs(_defaultAidaFileName);
+
+
+        } catch (IOException x)
+        {
+            System.out.println("Experienced an IOException during");
+            x.printStackTrace();
+            return;
+        }
+
+        fitPlots();
+    }
+
+    private void fitPlots()
+    {
+        boolean doit = true;
+        if (doit)
+        {
+
+            String[] pars =
+            {
+                "amplitude", "mean", "sigma"
+            };
+
+            IAnalysisFactory af = IAnalysisFactory.create();
+            String[] dirs = _tree.listObjectNames(".");
+            for (int ii = 0; ii < dirs.length; ++ii)
+            {
+//            System.out.println("dirs["+i+"]= "+dirs[i]);
+                String[] parts = dirs[ii].split("/");
+//            for(int k=0; k<parts.length; ++k)
+//            {
+//                System.out.println("parts["+k+"]= "+parts[k]);
+//            }
+                _tree.cd(dirs[ii]);
+                String[] objects = _tree.listObjectNames(".");
+
+//            for(int j=0; j<objects.length;++j)
+//            {
+//                System.out.println("obj["+j+"]= "+objects[i]);
+//            }
+
+                sortDirectoriesByEnergy(objects);
+
+                int numberOfPoints = objects.length;
+                double[] energies = new double[objects.length];
+                for (int j = 0; j < objects.length; ++j)
+                {
+//                System.out.println(objects[j]);
+
+                    String subDir = parts[1];
+                    String[] st = objects[j].split("/")[1].split("_");
+                    String e = st[0];
+                    String unit = st[1];
+////            System.out.println(e+" "+unit);
+                    energies[j] = Double.parseDouble(e);
+                    if (unit.contains("MeV"))
+                        energies[j] /= 1000.;
+//                System.out.println("energy: "+energies[j]);
+                }
+                IFunctionFactory functionFactory = af.createFunctionFactory(_tree);
+                IFitFactory fitFactory = af.createFitFactory();
+                IFitter jminuit = fitFactory.createFitter("Chi2", "jminuit");
+                IFunction gauss = functionFactory.createFunctionByName("gauss", "G");
+                IFunction line = functionFactory.createFunctionByName("line", "P1");
+                IDataPointSetFactory dpsf = af.createDataPointSetFactory(_tree);
+
+                IPlotter plotter = af.createPlotterFactory().create("sampling fraction plot");
+                plotter.createRegions(3, 4, 0);
+                IPlotterStyle style2 = plotter.region(7).style();
+                style2.legendBoxStyle().setVisible(false);
+                style2.statisticsBoxStyle().setVisible(false);
+
+
+                IPlotterStyle style;
+
+                double[] fitMeans = new double[numberOfPoints];
+                double[] fitSigmas = new double[numberOfPoints];
+                IDataPointSet energyMeans = dpsf.create("energy means vs E", 2);
+                IDataPointSet energySigmas = dpsf.create("sigma \\/ E vs E", 2);
+                IDataPointSet resolutionFit = dpsf.create("sigma \\/  E vs 1 \\/ \u221a E", 2);
+                IDataPointSet energyResiduals = dpsf.create("energy residuals (%) vs E", 2);
+                double eMax = 0;
+                for (int i = 0; i < numberOfPoints; ++i)
+                {
+                    if (energies[i] > .1) // do not analyze 100MeV and below...
+                    {
+                        System.out.println("Energy " + energies[i]);
+                        // +/- 5 sigma
+                        int nSigma = 5;
+                        double lowE = energies[i] - (.18 * sqrt(energies[i]) * nSigma);
+                        double hiE = energies[i] + (.18 * sqrt(energies[i]) * nSigma);
+
+                        ICloud1D e = (ICloud1D) _tree.find(objects[i] + "Cluster Energy");
+                        if (!e.isConverted())
+                        {
+                            int nbins = 50;
+//                            System.out.println(energies[i] + " - " + lowE + " + " + hiE);
+                            e.convert(50, lowE, hiE);
+                        }
+                        IHistogram1D eHist = e.histogram();
+                        gauss.setParameter("amplitude", eHist.maxBinHeight());
+                        gauss.setParameter("mean", eHist.mean());
+                        gauss.setParameter("sigma", eHist.rms());
+                        style = plotter.region(i).style();
+                        style.legendBoxStyle().setVisible(false);
+                        style.statisticsBoxStyle().setVisible(false);
+                        double loElimit = lowE; //energies[i] - .6 * sqrt(energies[i]); // expect ~20% resolution, and go out 3 sigma
+                        double hiElimit = hiE; //energies[i] + .6 * sqrt(energies[i]);
+                        plotter.region(i).setXLimits(loElimit, hiElimit);
+                        plotter.region(i).plot(eHist);
+                        IFitResult jminuitResult = jminuit.fit(eHist, gauss);
+                        double[] fitErrors = jminuitResult.errors();
+                        IFunction fit = jminuitResult.fittedFunction();
+                        for (int j = 0; j < pars.length; ++j)
+                        {
+                            System.out.println("   " + pars[j] + ": " + fit.parameter(pars[j]) + " +/- " + fitErrors[j]);
+                        }
+                        fitMeans[i] = fit.parameter("mean");
+                        fitSigmas[i] = fit.parameter("sigma");
+                        plotter.region(i).plot(fit);
+//            plotter.region(7).plot(eHist);
+
+                        // the means
+                        IDataPoint point = energyMeans.addPoint();
+                        point.coordinate(0).setValue(energies[i]);
+                        point.coordinate(1).setValue(fitMeans[i]);
+                        point.coordinate(1).setErrorPlus(fitErrors[1]);
+                        point.coordinate(1).setErrorMinus(fitErrors[1]);
+
+                        // sigma
+                        IDataPoint point1 = energySigmas.addPoint();
+                        point1.coordinate(0).setValue(energies[i]);
+                        point1.coordinate(1).setValue(fitSigmas[i] / energies[i]);
+                        point1.coordinate(1).setErrorPlus(fitErrors[2] / energies[i]);
+                        point1.coordinate(1).setErrorMinus(fitErrors[2] / energies[i]);
+
+                        // sigma/E vs 1/sqrt(E)
+
+                        IDataPoint point3 = resolutionFit.addPoint();
+                        point3.coordinate(0).setValue(1. / sqrt(energies[i]));
+                        point3.coordinate(1).setValue(fitSigmas[i] / energies[i]);
+                        point3.coordinate(1).setErrorPlus(fitErrors[2] / energies[i]);
+                        point3.coordinate(1).setErrorMinus(fitErrors[2] / energies[i]);
+
+                        // residuals
+                        IDataPoint point2 = energyResiduals.addPoint();
+                        point2.coordinate(0).setValue(energies[i]);
+                        point2.coordinate(1).setValue(100. * (fitMeans[i] - energies[i]) / energies[i]);
+
+                        // axis bookeeping...
+                        if (energies[i] > eMax)
+                            eMax = energies[i];
+                    } // end of 100 MeV cut
+                }
+
+                IPlotter results = af.createPlotterFactory().create("linearity");
+                style = results.region(0).style();
+                style.xAxisStyle().setLabel("MC Energy [GeV]");
+                style.yAxisStyle().setLabel("Cluster Energy [GeV]");
+                style.titleStyle().setVisible(false);
+                style.statisticsBoxStyle().setVisibileStatistics("011");
+                style.legendBoxStyle().setVisible(true);
+                IFitResult fitLine = jminuit.fit(energyMeans, line);
+                System.out.println(" fit status: " + fitLine.fitStatus());
+                double eMaxBin = eMax + 10.;
+                results.region(0).setXLimits(0., eMaxBin);
+//                results.region(0).setYLimits(0., eMaxBin);
+                results.region(0).plot(energyMeans);
+                results.region(0).plot(fitLine.fittedFunction());
+
+
+                IPlotter resolution = af.createPlotterFactory().create("resolution");
+                style = resolution.region(0).style();
+                style.xAxisStyle().setLabel("Energy [GeV]");
+                style.yAxisStyle().setLabel("sigma/E");
+                style.titleStyle().setVisible(false);
+                style.statisticsBoxStyle().setVisible(false);
+                style.legendBoxStyle().setVisible(false);
+                resolution.region(0).setXLimits(0., eMaxBin);
+//                resolution.region(0).setYLimits(0., .2);
+                resolution.region(0).plot(energySigmas);
+
+
+                IPlotter resolution2 = af.createPlotterFactory().create("sigma/E vs 1/E");
+                style = resolution2.region(0).style();
+                style.xAxisStyle().setLabel("1/ \u221a Energy [1/GeV]");
+                style.yAxisStyle().setLabel("sigma/E");
+        style.statisticsBoxStyle().setVisibileStatistics("011");
+                style.legendBoxStyle().setVisible(false);
+                IFitResult resFitLine = jminuit.fit(resolutionFit, line);
+                System.out.println(" fit status: " + resFitLine.fitStatus());
+//        resolution2.region(0).setXLimits(0., 1.05);
+//        resolution2.region(0).setYLimits(0., .2);
+                resolution2.region(0).plot(resolutionFit);
+                resolution2.region(0).plot(resFitLine.fittedFunction());
+
+                IPlotter residuals = af.createPlotterFactory().create("residuals (%)");
+                style = residuals.region(0).style();
+                style.xAxisStyle().setLabel("Energy [GeV]");
+                style.yAxisStyle().setLabel("Residuals [%]");
+                style.statisticsBoxStyle().setVisible(false);
+                style.titleStyle().setVisible(false);
+
+                residuals.region(0).setXLimits(0., eMaxBin);
+
+                residuals.region(0).plot(energyResiduals);
+
+                if (_showPlots)
+                {
+                    plotter.show();
+                    results.show();
+                    resolution.show();
+                    resolution2.show();
+                    residuals.show();
+                } else
+                {
+                    try
+                    {
+                        // hardcopy
+                        plotter.writeToFile("energyPlots." + _fileType, _fileType);
+                        results.writeToFile("linearity." + _fileType, _fileType);
+                        resolution.writeToFile("resolution." + _fileType, _fileType);
+                        resolution2.writeToFile("resolutionLinear." + _fileType, _fileType);
+                        residuals.writeToFile("residuals." + _fileType, _fileType);
+                    } catch (IOException e)
+                    {
+                        System.out.println("problem writing out hardcopy in " + _fileType + " format");
+                        e.printStackTrace();
+                    }
+
+                }
+            }// end of loop over directories
+        }
+    }
+
+    private static void sortDirectoriesByEnergy(String[] s)
+    {
+        Map<Double, String> map = new HashMap<Double, String>();
+        double[] energies = new double[s.length];
+        for (int j = 0; j < s.length; ++j)
+        {
+//           System.out.println(s[j]);
+            String subDir = s[j].split("/")[1]; // first token should be "."
+//            System.out.println(subDir);
+            String[] st = subDir.split("_");
+            String e = st[0];
+            String unit = st[1];
+//            System.out.println(e+" "+unit);
+            energies[j] = Double.parseDouble(e);
+            if (unit.contains("MeV"))
+                energies[j] /= 1000.;
+            map.put(energies[j], s[j]);
+//            System.out.println("energy: "+energies[j]);
+        }
+        Arrays.sort(energies);
+        for (int j = 0; j < s.length; ++j)
+        {
+            s[j] = map.get(energies[j]);
+        }
+//        for(int j=0; j<s.length; ++j)
+//        {
+//            System.out.println(s[j]);
+//        }
+    }
+
+    public void setExpectedResolution(double resolution)
+    {
+        System.out.println("setting expected resolution to "+resolution);
+        _expectedResolution = resolution;
+    }
+
+    public void setShowPlots(boolean showPlots)
+    {
+        _showPlots = showPlots;
+    }
+
+    public void setFileType(String fileType)
+    {
+        _fileType = fileType;
+    }
+
+    public void setWriteAidaFile(boolean writeAidaFile)
+    {
+        _writeOutAidaFile = writeAidaFile;
+    }
+    
+    public void setAidaFileName(String aidaFileName)
+    {
+        _defaultAidaFileName = aidaFileName;
+    }
+}
+
CVSspam 0.2.8