Print

Print


Commit in lcsim-cal-calib/src/org/lcsim/cal/calib on MAIN
SamplingFractionAnalysisPolyCalDriver.java+339added 1.1
SamplingFractionAnalysisDriver.java+3-31.6 -> 1.7
+342-3
1 added + 1 modified, total 2 files


lcsim-cal-calib/src/org/lcsim/cal/calib
SamplingFractionAnalysisPolyCalDriver.java added at 1.1
diff -N SamplingFractionAnalysisPolyCalDriver.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ SamplingFractionAnalysisPolyCalDriver.java	6 May 2010 20:42:46 -0000	1.1
@@ -0,0 +1,339 @@
+/*
+ * SamplingFractionAnalysisDriver.java
+ *
+ * Created on May 19, 2008, 11:54 AM
+ *
+ * $Id: SamplingFractionAnalysisPolyCalDriver.java,v 1.1 2010/05/06 20:42:46 jeremy Exp $
+ */
+
+package org.lcsim.cal.calib;
+
+import static java.lang.Math.abs;
+import static java.lang.Math.sqrt;
+import hep.aida.ITree;
+import hep.physics.vec.Hep3Vector;
+
+import java.util.List;
+
+import org.lcsim.conditions.ConditionsManager;
+import org.lcsim.conditions.ConditionsSet;
+import org.lcsim.conditions.ConditionsManager.ConditionsSetNotFoundException;
+import org.lcsim.event.CalorimeterHit;
+import org.lcsim.event.Cluster;
+import org.lcsim.event.EventHeader;
+import org.lcsim.event.MCParticle;
+import org.lcsim.geometry.IDDecoder;
+import org.lcsim.geometry.Subdetector;
+import org.lcsim.geometry.subdetector.AbstractPolyhedraCalorimeter;
+import org.lcsim.geometry.subdetector.PolyhedraEndcapCalorimeter2;
+import org.lcsim.recon.cluster.fixedcone.FixedConeClusterer;
+import org.lcsim.recon.cluster.fixedcone.FixedConeClusterer.FixedConeDistanceMetric;
+import org.lcsim.util.Driver;
+import org.lcsim.util.aida.AIDA;
+
+import Jama.Matrix;
+
+/**
+ *
+ * @author Norman Graf
+ */
+public class SamplingFractionAnalysisPolyCalDriver extends Driver
+{
+    private ConditionsSet _cond;
+    private CollectionManager _collectionmanager = CollectionManager.defaultInstance();
+    // we will accumulate the raw energy values in three depths:
+    // 1. Layers (0)1 through (20)21 of the EM calorimeter (note that if layer 0 is massless, SF==1.)
+    // 2. last ten layers of the EM calorimeter
+    // 3. the hadron calorimeter
+    //
+    private double[][] _acc = new double[3][3];
+    private double[] _vec = new double[3];
+    
+    // let's use a clusterer to remove effects of calorimeter cells hit far, far away.
+    // use the only cross-detector clusterer we have:
+    private FixedConeClusterer _fcc;
+    
+    private AIDA aida = AIDA.defaultInstance();
+    private ITree _tree;
+    
+    private boolean _initialized = false;
+    private boolean _debug = false;
+    
+    
+    // TODO fix this dependence on EM calorimeter geometry
+    boolean skipFirstLayer = false;
+    int firstEmStartLayer = 0;
+    int secondEmStartLayer = 20;
+    
+    double emCalInnerRadius = 0.;
+    double emCalInnerZ = 0.;
+    
+    /** Creates a new instance of SamplingFractionAnalysisDriver */
+    public SamplingFractionAnalysisPolyCalDriver()
+    {
+        _tree = aida.tree();
+    }
+    
+    
+    protected void process(EventHeader event)
+    {
+        super.process(event);
+        //System.out.println("processing SamplingFractionAnalysisDriver");
+        // TODO make these values runtime definable        
+        String[] det = {"EcalBarrel","EcalEndcap"};
+//        String[] collNames = {"EcalBarrHits", "EcalEndcapHits", "HcalBarrHits", "HcalEndcapHits"};
+//        double[] mipHistMaxBinVal = {.0005, .0005, .005, .005};
+//        double timeCut = 100.; // cut on energy depositions coming more than 100 ns late
+//        double ECalMipCut = .0001/3.; // determined from silicon using muons at normal incidence
+//        double HCalMipCut = .0008/3.; // determined from scintillator using muons at normal incidence
+//        double[] mipCut = {ECalMipCut, ECalMipCut, HCalMipCut, HCalMipCut};
+        
+        
+        if(!_initialized)
+        {
+            ConditionsManager mgr = ConditionsManager.defaultInstance();
+            try
+            {
+                _cond = mgr.getConditions("CalorimeterCalibration");
+            }
+            catch(ConditionsSetNotFoundException e)
+            {
+                System.out.println("ConditionSet CalorimeterCalibration not found for detector "+mgr.getDetector());
+                System.out.println("Please check that this properties file exists for this detector ");
+            }
+            double radius = .5;
+            double seed = 0.;//.1;
+            double minE = .05; //.25;
+            _fcc = new FixedConeClusterer(radius, seed, minE, FixedConeDistanceMetric.DPHIDTHETA);
+            
+            // detector geometries here...
+            // barrel
+            //CylindricalCalorimeter calsubBarrel = (CylindricalCalorimeter)event.getDetector().getSubdetectors().get(det[0]);
+            System.out.println("looking up subdet: " + det[0]);
+            Subdetector subdet = event.getDetector().getSubdetectors().get(det[0]);            
+            System.out.println("proc subdet: " + subdet.getName());
+            AbstractPolyhedraCalorimeter calsubBarrel = (AbstractPolyhedraCalorimeter)event.getDetector().getSubdetectors().get(det[0]);
+            // TODO remove this hardcoded dependence on the first layer
+            if(calsubBarrel.getLayering().getLayer(0).getSlices().get(0).isSensitive())
+            {
+                skipFirstLayer = true;
+                firstEmStartLayer += 1;
+                secondEmStartLayer += 1;
+            }
+//            Layering layering = calsubBarrel.getLayering();
+//            for(int i=0; i<layering.size(); ++i)
+//            {
+//                Layer l = layering.getLayer(i);
+//                System.out.println("layering "+i);
+//                List<LayerSlice> slices = l.getSlices();
+//                for(int j=0; j<slices.size(); ++j)
+//                {
+//                    LayerSlice slice = slices.get(j);
+//                    System.out.println("Layer "+i+" slice "+j+" is "+ slice.getMaterial().getName() +" and "+(slice.isSensitive() ? " is sensitive" : ""));
+//                }
+//            }
+            emCalInnerRadius = calsubBarrel.getInnerRadius();
+            //endcap
+            AbstractPolyhedraCalorimeter calsubEndcap = (AbstractPolyhedraCalorimeter)event.getDetector().getSubdetectors().get(det[1]);
+            emCalInnerZ = abs(calsubEndcap.getZMin());
+            if(skipFirstLayer) System.out.println("processing "+event.getDetectorName()+" with an em calorimeter with a massless first gap");
+            System.out.println("Calorimeter bounds: r= "+emCalInnerRadius+ " z= "+emCalInnerZ);
+            System.out.println("initialized...");
+            
+            _initialized = true;
+        }
+        
+        // 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...
+        Hep3Vector endpoint = mcpart.getEndPoint();
+        // this is just crap. Why not use SpacePoint?
+        double radius = sqrt(endpoint.x()*endpoint.x()+endpoint.y()*endpoint.y());
+        double z = endpoint.z();
+//        System.out.println("Input MCParticle endpoint: r="+radius+" z= "+z);
+        
+        boolean doit = true;
+        if(radius<emCalInnerRadius && abs(z) < emCalInnerZ) doit = false;
+        if(doit)
+        {
+//            // now let's check the em calorimeters...
+//            // get all of the calorimeter hits...
+//            List<CalorimeterHit> allHits = new ArrayList<CalorimeterHit>();
+//            // and the list after cuts.
+//            List<CalorimeterHit> hitsToCluster = new ArrayList<CalorimeterHit>();
+//            int i = 0;
+//            for(String name : collNames)
+//            {
+////                System.out.println("fetching "+name+" from the event");
+//                List<CalorimeterHit> hits = event.get(CalorimeterHit.class, name);
+////                System.out.println(name+ " has "+hits.size()+" hits");
+//                // let's look at the hits and see if we need to cut on energy or time...
+//                for(CalorimeterHit hit: hits)
+//                {
+//                    aida.histogram1D(name+" raw calorimeter cell energy",100, 0., mipHistMaxBinVal[i]).fill(hit.getRawEnergy());
+//                    aida.histogram1D(name+" raw calorimeter cell energy full range",100, 0., 0.2).fill(hit.getRawEnergy());
+////                    aida.cloud1D(name+" raw calorimeter cell energies").fill(hit.getRawEnergy());
+//                    aida.histogram1D(name+" calorimeter cell time",100,0., 200.).fill(hit.getTime());
+//                    if(hit.getTime()<timeCut)
+//                    {
+//                        if(hit.getRawEnergy()>mipCut[i])
+//                        {
+//                            hitsToCluster.add(hit);
+//                        }
+//                    }
+//                }
+//                allHits.addAll(hits);
+//                ++i;
+//            }
+//            System.out.println("ready to cluster "+hitsToCluster.size()+ " hits");
+            String processedHitsName = _cond.getString("ProcessedHitsCollectionName");
+            List<CalorimeterHit> hitsToCluster = _collectionmanager.getList(processedHitsName);//event.get(CalorimeterHit.class, processedHitsName);
+
+            if(_debug) System.out.println("clustering "+hitsToCluster.size()+" hits");
+            // quick check
+//            for(CalorimeterHit hit : hitsToCluster)
+//            {
+//                System.out.println("hit ");
+//                System.out.println(hit.getLCMetaData().getName());
+//            }
+            // cluster the hits
+            List<Cluster> clusters = _fcc.createClusters(hitsToCluster);
+            if(_debug) System.out.println("found "+clusters.size()+" clusters");
+            aida.histogram1D("number of found clusters", 10, -0.5, 9.5).fill(clusters.size());
+            for(Cluster c : clusters)
+            {
+//                System.out.println(c);
+                aida.cloud1D("cluster energy for all clusters").fill(c.getEnergy());
+            }
+            
+            // proceed only if we found a single cluster above threshold
+            // too restrictive! simply take the highest energy cluster
+            if(clusters.size()>0)
+            {
+                Cluster c = clusters.get(0);
+                
+                aida.cloud1D("Highest energy cluster energy").fill(c.getEnergy());
+                aida.cloud1D("Highest energy cluster number of cells").fill(c.getCalorimeterHits().size());
+                
+                double clusterEnergy = c.getEnergy();
+                double mcMass = mcpart.getType().getMass();
+                // subtract the mass to get kinetic energy...
+                double expectedEnergy = sqrt(mcEnergy*mcEnergy - mcMass*mcMass);
+//                System.out.println(mcpart.getType().getName()+" "+expectedEnergy);
+                aida.cloud1D("measured - predicted energy").fill(clusterEnergy - expectedEnergy);
+                
+                // let's now break down the cluster by component.
+                // this analysis uses:
+                // 1.) first 20 EM layers
+                // 2.) next 10 EM layers
+                // 3.) Had layers
+                List<CalorimeterHit> hits = c.getCalorimeterHits();
+                double[] vals = new double[3];
+                double clusterRawEnergy = 0.;
+                for(CalorimeterHit hit : hits)
+                {
+                    long id = hit.getCellID();
+                    IDDecoder decoder = hit.getIDDecoder();
+                    decoder.setID(id);
+                    int layer = decoder.getLayer();
+                    String detectorName = decoder.getSubdetector().getName();
+                    int type = 0;
+                    // FIXME Hard-coded name.
+                    if(detectorName.startsWith("Ecal"))
+                    {
+                        if(layer>=firstEmStartLayer && layer<secondEmStartLayer)
+                        {
+                            type = 0;
+                        }
+                        else
+                        {
+                            type = 1;
+                        }
+                    }
+                    // FIXME Hard-coded name.
+                    if(detectorName.startsWith("Hcal"))
+                    {
+                        type = 2;
+                    }
+                    clusterRawEnergy += hit.getRawEnergy();
+                    vals[type] += hit.getRawEnergy();
+                } // end of loop over hits in cluster
+                // set up linear least squares:
+                // expectedEnergy = a*E1 + b*E2 +c*E3
+                for(int j=0; j<3; ++j)
+                {
+                    _vec[j] += expectedEnergy*vals[j];
+                    for(int k=0; k<3; ++k)
+                    {
+                        _acc[j][k] += vals[j]*vals[k];
+                    }
+                }
+            } // end of single cluster cut
+            
+//            event.put("All Calorimeter Hits",allHits);
+//            event.put("Hits To Cluster",hitsToCluster);
+            event.put("Found Clusters",clusters);
+        }// end of check on decays outside tracker volume
+        _tree.cd("/");
+    }
+    
+    protected void endOfData()
+    {
+        System.out.println("done! endOfData.");
+        // calculate the sampling fractions...
+        Matrix A = new Matrix(_acc, 3, 3);
+        A.print(6,4);
+        Matrix b = new Matrix(3,1);
+        for(int i=0; i<3; ++i)
+        {
+            b.set(i,0,_vec[i]);
+        }
+        b.print(6,4);
+        try
+        {
+            Matrix x = A.solve(b);
+            x.print(6, 4);
+            System.out.println("SamplingFractions: "+ 1./x.get(0,0)+ " " + 1./x.get(1,0)+" "+1./x.get(2,0));
+        }
+        catch(Exception e)
+        {
+            e.printStackTrace();
+            System.out.println("try reducing dimensionality...");
+            Matrix Ap = new Matrix(_acc, 2, 2);
+            Ap.print(6,4);
+            Matrix bp = new Matrix(2,1);
+            for(int i=0; i<2; ++i)
+            {
+                bp.set(i,0,_vec[i]);
+            }
+            bp.print(6,4);
+            try
+            {
+                Matrix x = Ap.solve(bp);
+                x.print(6, 4);
+            }
+            catch(Exception e2)
+            {
+                e2.printStackTrace();
+            }
+        }
+    }
+}
\ No newline at end of file

lcsim-cal-calib/src/org/lcsim/cal/calib
SamplingFractionAnalysisDriver.java 1.6 -> 1.7
diff -u -r1.6 -r1.7
--- SamplingFractionAnalysisDriver.java	6 Jun 2008 15:17:22 -0000	1.6
+++ SamplingFractionAnalysisDriver.java	6 May 2010 20:42:46 -0000	1.7
@@ -3,7 +3,7 @@
  *
  * Created on May 19, 2008, 11:54 AM
  *
- * $Id: SamplingFractionAnalysisDriver.java,v 1.6 2008/06/06 15:17:22 ngraf Exp $
+ * $Id: SamplingFractionAnalysisDriver.java,v 1.7 2010/05/06 20:42:46 jeremy Exp $
  */
 
 package org.lcsim.cal.calib;
@@ -53,7 +53,7 @@
     private AIDA aida = AIDA.defaultInstance();
     private ITree _tree;
     
-    private boolean _initialized;
+    private boolean _initialized = false;
     private boolean _debug = false;
     
     
@@ -75,7 +75,7 @@
     protected void process(EventHeader event)
     {
         super.process(event);
-        System.out.println("processing SamplingFractionAnalysisDriver");
+        //System.out.println("processing SamplingFractionAnalysisDriver");
         // TODO make these values runtime definable
         String[] det = {"EMBarrel","EMEndcap"};
 //        String[] collNames = {"EcalBarrHits", "EcalEndcapHits", "HcalBarrHits", "HcalEndcapHits"};
CVSspam 0.2.8