Print

Print


Commit in lcsim on MAIN
src/org/lcsim/recon/emid/hmatrix/InterpolatedHMatrixBuilder.java+135added 1.1
                                /InterpolatedHMatrix.java+99added 1.1
test/org/lcsim/recon/emid/hmatrix/InterpolatedHMatrixTest.java+163added 1.1
+397
3 added files
Classes to create and represent HMatrices which interpolate between discrete values of theta and energies.
Requires appropriate properties file for detectors.

lcsim/src/org/lcsim/recon/emid/hmatrix
InterpolatedHMatrixBuilder.java added at 1.1
diff -N InterpolatedHMatrixBuilder.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ InterpolatedHMatrixBuilder.java	6 Jun 2008 07:27:32 -0000	1.1
@@ -0,0 +1,135 @@
+/*
+ * InterpolatedHMatrixBuilder.java
+ *
+ * Created on June 5, 2008, 11:54 PM
+ *
+ * $Id: InterpolatedHMatrixBuilder.java,v 1.1 2008/06/06 07:27:32 ngraf Exp $
+ */
+
+package org.lcsim.recon.emid.hmatrix;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.TreeMap;
+import org.lcsim.conditions.ConditionsManager;
+import org.lcsim.conditions.ConditionsManager.ConditionsNotFoundException;
+import org.lcsim.conditions.ConditionsManager.ConditionsSetNotFoundException;
+import org.lcsim.conditions.ConditionsSet;
+import org.lcsim.math.interpolation.BilinearInterpolator;
+
+/**
+ * This class uses data stored in a properties file to create an InterpolatedHMatrix
+ * which is able to calculate a cluster "chi-squared" for arbitrary values of theta and 
+ * energy
+ *
+ * @author Norman Graf
+ */
+public class InterpolatedHMatrixBuilder
+{
+    static final boolean debug = false;
+    
+    /**
+     * Given a detectorname, this method will locate the appropriate
+     * properties file and create an HMatrix which interpolates between 
+     * the discrete points in theta and energy.
+     *
+     * @param detectorName the name of a supported detector
+     * @return an InterpolatedHMatrix
+     */
+    public static InterpolatedHMatrix build(String detectorName)
+    {
+        String conditionsSetName = detectorName+"_HMatrices";
+        ConditionsManager mgr = ConditionsManager.defaultInstance();
+        try
+        {
+            mgr.setDetector(detectorName, 0);
+        }
+        catch( ConditionsNotFoundException e)
+        {
+            System.out.println("Conditions not found for detector "+mgr.getDetector());
+            System.out.println("Please check that this properties file exists for this detector ");
+            throw new RuntimeException("Conditions not found for detector "+mgr.getDetector());
+        }
+        ConditionsSet cs = null;
+        try
+        {
+            cs = mgr.getConditions(conditionsSetName);
+        }
+        catch(ConditionsSetNotFoundException e)
+        {
+            System.out.println("ConditionSet "+conditionsSetName+" not found for detector "+mgr.getDetector());
+            System.out.println("Please check that this properties file exists for this detector ");
+            throw new RuntimeException("ConditionSet "+conditionsSetName+" not found for detector "+mgr.getDetector());
+            
+        }
+        
+        int dim = cs.getInt("Dimensionality");
+        double[] energies = cs.getDoubleArray("EnergyVals");
+        int numEnergies = energies.length;
+        if(debug) System.out.println("energies: "+Arrays.toString(energies));
+        double[] angles = cs.getDoubleArray("ThetaVals");
+        int numAngles = angles.length;
+        if(debug) System.out.println("angles: "+Arrays.toString(angles));
+        
+        // Maps to hold all the arrays of numbers keyed on theta and energy
+        Map<String, double[]> avMap = new TreeMap<String, double[]>();
+        Map<String, double[]> covMap = new HashMap<String, double[]>();
+        
+        for(double theta : angles)
+        {
+            for( double energy : energies)
+            {
+                String key = "Theta_"+theta+"_Energy_"+energy;
+                avMap.put(key, cs.getDoubleArray(key+"_vals"));
+                covMap.put(key, cs.getDoubleArray(key+"_covs"));
+                if(debug) System.out.println(key);
+            }
+        }
+        
+        // for each theta and energy point, we have:
+        // n           average values
+        // n*(n+1)/2   covariance values (packed)
+        //
+        // will need to create a bilinearInterpolator for each of these (n^2+3n)/2 parameters
+        
+        // order is theta, energy
+        double[][] tmp = new double[numAngles][numEnergies];
+        BilinearInterpolator[] valInterpolators = new BilinearInterpolator[dim];
+        
+        // mean vector [dim]
+        for (int iVal=0; iVal<dim; ++iVal)
+        {
+            for(int i=0; i<numAngles; ++i)
+            {
+                for(int j=0; j<numEnergies; ++j)
+                {
+                    String key = "Theta_"+angles[i]+"_Energy_"+energies[j];
+                    tmp[i][j] = avMap.get(key)[iVal];
+                    if(debug) System.out.println(key +"_"+iVal+" "+  tmp[i][j]);
+                }
+            }
+            valInterpolators[iVal] = new BilinearInterpolator(angles, energies, tmp);
+        }
+        
+        // cov matrix elements [(dim*(dim+1))/2]
+        int covDim = (dim*(dim+1))/2;
+        BilinearInterpolator[] covInterpolators = new BilinearInterpolator[(dim*(dim+1))/2];
+        
+        for (int iVal=0; iVal<covDim; ++iVal)
+        {
+            for(int i=0; i<numAngles; ++i)
+            {
+                for(int j=0; j<numEnergies; ++j)
+                {
+                    String key = "Theta_"+angles[i]+"_Energy_"+energies[j];
+                    tmp[i][j] = covMap.get(key)[iVal];
+                    if(debug) System.out.println(key +"_"+iVal+" "+  tmp[i][j]);
+                }
+            }
+            covInterpolators[iVal] = new BilinearInterpolator(angles, energies, tmp);
+        }
+        
+        return new InterpolatedHMatrix(dim, valInterpolators, covInterpolators);
+    }
+}
\ No newline at end of file

lcsim/src/org/lcsim/recon/emid/hmatrix
InterpolatedHMatrix.java added at 1.1
diff -N InterpolatedHMatrix.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ InterpolatedHMatrix.java	6 Jun 2008 07:27:32 -0000	1.1
@@ -0,0 +1,99 @@
+/*
+ * InterpolatedHMatrix.java
+ *
+ * Created on June 5, 2008, 10:34 AM
+ *
+ * $Id: InterpolatedHMatrix.java,v 1.1 2008/06/06 07:27:32 ngraf Exp $
+ */
+
+package org.lcsim.recon.emid.hmatrix;
+
+import hep.physics.matrix.SymmetricMatrix;
+import org.lcsim.math.interpolation.BilinearInterpolator;
+
+/**
+ * This class interpolates the average values and inverse covariance matrix elements
+ * for photon showers based on derivations at fixed energy and angle.
+ * @author Norman Graf
+ */
+public class InterpolatedHMatrix
+{
+    //Interpolation for the vector of measurement averages
+    private BilinearInterpolator[] _valInterpolators;
+    //Interpolation for the inverse covariance matrix elements represented as a
+    //packed lower-diagonal matrix
+    private BilinearInterpolator[] _covInterpolators;
+    
+    private int _dim;
+    private int _covDim;
+    
+    /** Creates a new instance of InterpolatedHMatrix */
+    // TODO check robustness, use deep copy if necessary.
+    public InterpolatedHMatrix(int dim, BilinearInterpolator[] valInterpolators, BilinearInterpolator[] covInterpolators)
+    {
+        _dim = dim;
+        _covDim = (_dim*(_dim+1))/2;
+        _valInterpolators = valInterpolators;
+        _covInterpolators = covInterpolators; 
+    }
+       
+    /**
+     * Returns the closeness of the vector dat to the expectations based on an 
+     * interpolation between discrete values of angle and energy at which showers
+     * were simulated.
+     *
+     * @param theta  the polar angle
+     * @param energy the energy of the electromagnetic shower
+     * @param dat the vector of fractional energies by layer
+     * @return the distance of this shower to that expected, chi-squared for normal distributions of layer energies.
+     */
+    public double zeta(double theta, double energy, double[] dat)
+    {
+        double[] means = new double[_dim];
+        double[] cov = new double[_covDim];
+        double[] tmp = new double[_dim];
+        double[] tmp2 = new double[_dim];
+
+        for(int i=0; i<_dim; ++i)
+        {
+            means[i] = _valInterpolators[i].interpolateValueAt(theta, energy);
+        }
+
+        for(int i=0; i<_covDim; ++i)
+        {
+            cov[i] = _covInterpolators[i].interpolateValueAt(theta, energy);
+        }
+
+        // vector of measured-predicted values
+        for(int i=0; i<_dim; ++i)
+        {
+            tmp[i] = dat[i] - means[i];
+        }
+
+        double zeta = 0.;
+        // reexpand lower-diagonal into full double array
+        // could this be optimized?
+        double[][] invcov = new double[_dim][_dim];
+        int count = 0;
+        for(int i=0; i<_dim; ++i)
+        {
+            for(int j=0; j<i+1; ++j)
+            {
+                invcov[i][j] = cov[count];
+                invcov[j][i] = cov[count];
+                count++;
+            }
+        }
+        // covariance matrix times difference vector
+        for(int i=0; i<_dim; ++i)
+        {
+            tmp2[i] = 0.;
+            for(int j=0; j<_dim; ++j)
+            {
+                tmp2[i]+=invcov[j][i]*tmp[j];
+            }
+            zeta += tmp[i]*tmp2[i];
+        }
+        return zeta;
+    }   
+}
\ No newline at end of file

lcsim/test/org/lcsim/recon/emid/hmatrix
InterpolatedHMatrixTest.java added at 1.1
diff -N InterpolatedHMatrixTest.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ InterpolatedHMatrixTest.java	6 Jun 2008 07:27:33 -0000	1.1
@@ -0,0 +1,163 @@
+/*
+ * InterpolatedHMatrixTest.java
+ * JUnit based test
+ *
+ * Created on June 5, 2008, 5:41 PM
+ */
+
+package org.lcsim.recon.emid.hmatrix;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.TreeMap;
+import junit.framework.*;
+import org.lcsim.conditions.ConditionsManager;
+import org.lcsim.conditions.ConditionsManager.ConditionsSetNotFoundException;
+import org.lcsim.conditions.ConditionsSet;
+import org.lcsim.math.interpolation.BilinearInterpolator;
+
+/**
+ *
+ * @author ngraf
+ */
+public class InterpolatedHMatrixTest extends TestCase
+{
+    /**
+     * Test of org.lcsim.recon.emid.hmatrix.InterpolatedHMatrix.
+     */
+    public void testInterpolatedHMatrix() throws Exception
+    {
+        boolean debug = false;
+        if(debug) System.out.println("testing InterpolatedHMatrix");
+        String detectorName = "sid01_scint";
+        String conditionsSetName = detectorName+"_HMatrices";
+        ConditionsManager mgr = ConditionsManager.defaultInstance();
+        mgr.setDetector(detectorName, 0);
+        ConditionsSet cs = null;
+        try
+        {
+            cs = mgr.getConditions(conditionsSetName);
+        }
+        catch(ConditionsSetNotFoundException e)
+        {
+            System.out.println("ConditionSet "+conditionsSetName+" not found for detector "+mgr.getDetector());
+            System.out.println("Please check that this properties file exists for this detector ");
+        }
+        
+        int dim = cs.getInt("Dimensionality");
+        if(debug) System.out.println(dim);
+        
+        double[] energies = cs.getDoubleArray("EnergyVals");
+        int numEnergies = energies.length;
+        if(debug) System.out.println("energies: "+Arrays.toString(energies));
+        double[] angles = cs.getDoubleArray("ThetaVals");
+        int numAngles = angles.length;
+        if(debug) System.out.println("angles: "+Arrays.toString(angles));
+        
+        // Maps to hold all the arrays of numbers keyed on theta and energy
+        Map<String, double[]> avMap = new TreeMap<String, double[]>();
+        Map<String, double[]> covMap = new HashMap<String, double[]>();
+        
+        for(double theta : angles)
+        {
+            for( double energy : energies)
+            {
+                String key = "Theta_"+theta+"_Energy_"+energy;
+                avMap.put(key, cs.getDoubleArray(key+"_vals"));
+                covMap.put(key, cs.getDoubleArray(key+"_covs"));
+                if(debug) System.out.println(key);
+            }
+        }
+        
+        // for each theta and energy point, we have:
+        // n           average values
+        // n*(n+1)/2   covariance values (packed)
+        //
+        // will need to create a bilinearInterpolator for each of these (n^2+3n)/2 parameters
+        
+        // OK, let's try to get one interpolator going here...
+        // test val[3]
+        
+        // order is theta, energy
+        double[][] tmp = new double[numAngles][numEnergies];
+        int itest = 3;
+        for(int i=0; i<numAngles; ++i)
+        {
+            for(int j=0; j<numEnergies; ++j)
+            {
+                String key = "Theta_"+angles[i]+"_Energy_"+energies[j];
+                tmp[i][j] = avMap.get(key)[itest];
+                if(debug) System.out.println(key + " "+  tmp[i][j]);
+            }
+        }
+        // OK, create the BilinearInterpolator
+        BilinearInterpolator bi = new BilinearInterpolator(angles, energies, tmp);
+        
+        // now check what we got
+        for(int i=0; i<numAngles; ++i)
+        {
+            for(int j=0; j<numEnergies; ++j)
+            {
+                String key = "Theta_"+angles[i]+"_Energy_"+energies[j];
+                double meas = avMap.get(key)[itest];
+                double pred = bi.interpolateValueAt(angles[i],energies[j]);
+                if(debug) System.out.println(key+" meas: "+meas+" interp: "+pred);
+                assertEquals(meas, pred ,1e-5);
+            }
+        }
+        if(debug) System.out.println(bi.interpolateValueAt(169., 99.));
+        
+        //TODO there seems to be some problem with the bilinear interpolator with
+        // values near the high end of the range of validity, i.e near theta=170
+        // and energy = 100.
+        BilinearInterpolator[] valInterpolators = new BilinearInterpolator[dim];
+        
+        // mean vector [dim]
+        for (int iVal=0; iVal<dim; ++iVal)
+        {
+            for(int i=0; i<numAngles; ++i)
+            {
+                for(int j=0; j<numEnergies; ++j)
+                {
+                    String key = "Theta_"+angles[i]+"_Energy_"+energies[j];
+                    tmp[i][j] = avMap.get(key)[iVal];
+                    if(debug) System.out.println(key +"_"+iVal+" "+  tmp[i][j]);
+                }
+            }
+            valInterpolators[iVal] = new BilinearInterpolator(angles, energies, tmp);
+        }
+        
+        // cov matrix elements [(dim*(dim+1))/2]
+        int covDim = (dim*(dim+1))/2;
+        BilinearInterpolator[] covInterpolators = new BilinearInterpolator[(dim*(dim+1))/2];
+        
+        for (int iVal=0; iVal<covDim; ++iVal)
+        {
+            for(int i=0; i<numAngles; ++i)
+            {
+                for(int j=0; j<numEnergies; ++j)
+                {
+                    String key = "Theta_"+angles[i]+"_Energy_"+energies[j];
+                    tmp[i][j] = covMap.get(key)[iVal];
+                    if(debug) System.out.println(key +"_"+iVal+" "+  tmp[i][j]);
+                }
+            }
+            covInterpolators[iVal] = new BilinearInterpolator(angles, energies, tmp);
+        }
+        
+        // sanity check 
+        double theta = 90.0;
+        double energy = 10.0;
+        String key = "Theta_"+theta+"_Energy_"+energy;                
+        double[] dat = avMap.get(key);
+        InterpolatedHMatrix instance = new InterpolatedHMatrix(dat.length, valInterpolators, covInterpolators);
+        
+        // passing the exact same vector as the average should give us a zeta of zero
+        double result = instance.zeta(theta, energy, dat);
+        System.out.println("result: "+result);
+        assertEquals(result, 0.);
+        
+    }
+    
+}
CVSspam 0.2.8