3 added files
lcsim/src/org/lcsim/recon/emid/hmatrix
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
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
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