5 added files
lcsim/sandbox/readout/segmentation
diff -N CylinderGeometer.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ CylinderGeometer.java 30 Nov 2010 22:46:04 -0000 1.1
@@ -0,0 +1,103 @@
+package org.lcsim.readout.segmentation;
+
+import org.lcsim.spacegeom.SpacePoint;
+import org.lcsim.spacegeom.CylindricalPoint;
+/**
+ * A class to provide projective segmentation of barrels and disks
+ * @author Norman Graf
+ * @version 1.0
+ */
+public class CylinderGeometer implements ReadoutChannelSegmenter
+{
+ private double _rMin;
+ private double _rMax;
+ private double _zMin;
+ private double _zMax;
+
+ private double _dRZ;
+ private double _dPhi;
+ private double _dLayer;
+
+ private boolean _layerRadial;
+
+ /** Creates a new instance of CylinderGeometer
+ * Creates a new instance of ProjectiveCylinderSegmenter
+ * @param rInner Cylinder inner radius
+ * @param rOuter Cylinder outer radius
+ * @param zMin Cylinder minimum z
+ * @param zMax Cylinder maximum z
+ * @param nLayers Number of layers (radial or z)
+ * @param nRZBins Number of readout bins for full extent of cylinder in either r or z
+ * @param nPhi Number of phi bins for full 0 - 2pi
+ * @param layerRadial if true layer radially, else layer in z
+ */
+ public CylinderGeometer(double rInner, double rOuter, double zMin, double zMax, int nLayers, int nRZBins, int nPhi, boolean layerRadial)
+ {
+ _rMin = rInner;
+ _rMax = rOuter;
+ _zMin = zMin;
+ _zMax = zMax;
+ _layerRadial = layerRadial;
+ _dRZ = nRZBins;
+ _dPhi = 2.*Math.PI/nPhi;
+ if(_layerRadial)
+ {
+ _dLayer = (rOuter-rInner)/nLayers;
+ }
+ else
+ {
+ _dLayer = (zMax-zMin)/nLayers;
+ }
+ }
+ /**
+ * Calculate the readout indices corresponding to the input spacepoint.
+ * This method does not check that the spacepoint is inside the volume.
+ * @param sp The spacepoint for which the readout indices are to be calculated.
+ * @param indices indices[0] is theta, indices[1] is phi, indices[2] is layer.
+ *
+ */
+ public void segment(SpacePoint sp, int[] indices)
+ {
+ indices[1] = (int) Math.rint((sp.phi())/_dPhi);
+ int layer;
+ if(_layerRadial)
+ {
+ indices[0] = (int) Math.rint((sp.z())/_dRZ);
+ layer = (int) Math.rint((sp.rxy()-_rMin)/_dLayer);
+ }
+ else
+ {
+ indices[0] = (int) Math.rint((sp.rxy())/_dRZ);
+ layer=0;
+ }
+ indices[2] = layer;
+ }
+
+ /**
+ * Calculate the readout indices corresponding to the input spacepoint,
+ * checking that the point is within the readout boundaries.
+ * @param sp The spacepoint for which the readout indices are to be calculated.
+ * @param indices indices[0] is theta, indices[1] is phi, indices[2] is layer.
+ * @return true if spacepoint is within readout boundaries.
+ */
+ public boolean segmentCheckBounds(SpacePoint sp, int[] indices)
+ {
+ // limits in z are easy, do first
+ double z = sp.z();
+ if(z<_zMin || z>_zMax) return false;
+ // check layer next
+ double r = sp.rxy();
+ if(r<_rMin || r>_rMax) return false;
+ segment(sp,indices);
+ return true;
+ }
+
+ public SpacePoint position(int[] indices)
+ {
+ double r = _rMin;
+ double phi = 0.;
+ double z = 0.;
+ return new CylindricalPoint(r, phi, z);
+ }
+
+}
lcsim/sandbox/readout/segmentation
diff -N ProjectiveCylinderGeometer.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ ProjectiveCylinderGeometer.java 30 Nov 2010 22:46:04 -0000 1.1
@@ -0,0 +1,113 @@
+package org.lcsim.readout.segmentation;
+
+import org.lcsim.spacegeom.SpacePoint;
+import org.lcsim.spacegeom.CylindricalPoint;
+/**
+ * A class to provide projective segmentation of barrels and disks
+ * @author Norman Graf
+ * @version 1.0
+ */
+public class ProjectiveCylinderGeometer implements ReadoutChannelSegmenter
+{
+ private double _rMin;
+ private double _rMax;
+ private double _zMin;
+ private double _zMax;
+
+ private double _dTheta;
+ private double _dPhi;
+ private double _dLayer;
+
+ private boolean _layerRadial;
+
+ /**
+ * Creates a new instance of ProjectiveCylinderSegmenter
+ * @param rInner Cylinder inner radius
+ * @param rOuter Cylinder outer radius
+ * @param zMin Cylinder minimum z
+ * @param zMax Cylinder maximum z
+ * @param nLayers Number of layers (radial or z)
+ * @param nTheta Number of theta bins for full 0 - pi
+ * @param nPhi Number of phi bins for full 0 - 2pi
+ * @param layerRadial if true layer radially, else layer in z
+ */
+ public ProjectiveCylinderGeometer(double rInner, double rOuter, double zMin, double zMax, int nLayers, int nTheta, int nPhi, boolean layerRadial)
+ {
+ _rMin = rInner;
+ _rMax = rOuter;
+ _zMin = zMin;
+ _zMax = zMax;
+ _layerRadial = layerRadial;
+ _dTheta = Math.PI/nTheta;
+ _dPhi = 2.*Math.PI/nPhi;
+ if(_layerRadial)
+ {
+ _dLayer = (rOuter-rInner)/nLayers;
+ }
+ else
+ {
+ _dLayer = (zMax-zMin)/nLayers;
+ }
+ }
+
+ /**
+ * Calculate the readout indices corresponding to the input spacepoint.
+ * This method does not check that the spacepoint is inside the volume.
+ * @param sp The spacepoint for which the readout indices are to be calculated.
+ * @param indices indices[0] is theta, indices[1] is phi, indices[2] is layer.
+ *
+ */
+ public void segment(SpacePoint sp, int[] indices)
+ {
+ indices[0] = (int) Math.rint((sp.theta())/_dTheta);
+ indices[1] = (int) Math.rint((sp.phi())/_dPhi);
+ int layer;
+ if(_layerRadial)
+ {
+ layer = (int) Math.rint((sp.rxy()-_rMin)/_dLayer);
+ }
+ else
+ {
+ layer=0;
+ }
+ indices[2] = layer;
+ }
+
+ /**
+ * Calculate the readout indices corresponding to the input spacepoint,
+ * checking that the point is within the readout boundaries.
+ * @param sp The spacepoint for which the readout indices are to be calculated.
+ * @param indices indices[0] is theta, indices[1] is phi, indices[2] is layer.
+ * @return true if spacepoint is within readout boundaries.
+ */
+ public boolean segmentCheckBounds(SpacePoint sp, int[] indices)
+ {
+ // limits in z are easy, do first
+ double z = sp.z();
+ if(z<_zMin || z>_zMax) return false;
+ // check layer next
+ double r = sp.rxy();
+ if(r<_rMin || r>_rMax) return false;
+ segment(sp,indices);
+ return true;
+ }
+
+ public SpacePoint position(int[] indices)
+ {
+ double r = _rMin;
+ double phi = 0.;
+ double z = 0.;
+ return new CylindricalPoint(r, phi, z);
+ }
+
+
+ /**
+ * Object printout.
+ * @return a String representation of this object
+ */
+ public String toString()
+ {
+ StringBuffer sb = new StringBuffer("ProjectiveCylinderSegmenter");
+ return sb.toString();
+ }
+}
lcsim/sandbox/readout/segmentation
diff -N ReadoutChannelSegmenter.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ ReadoutChannelSegmenter.java 30 Nov 2010 22:46:04 -0000 1.1
@@ -0,0 +1,39 @@
+package org.lcsim.readout.segmentation;
+
+import org.lcsim.spacegeom.SpacePoint;
+/**
+ * An interface for classes which quantize readout
+ * and thereby segment a sensitive volume.
+ * @author Norman Graf
+ * @version 1.0
+ */
+public interface ReadoutChannelSegmenter
+{
+ /**
+ * Calculate the readout indices corresponding to the input spacepoint.
+ * @param sp The spacepoint for which the readout indices are to be calculated.
+ * @param indices The array of indices appropriate for this segmenter.
+ */
+ public void segment(SpacePoint sp, int[] indices);
+
+ /**
+ * Calculate the readout indices corresponding to the input spacepoint,
+ * checking that the point is within the readout boundaries.
+ * @param sp The spacepoint for which the readout indices are to be calculated.
+ * @param indices The array of indices appropriate for this segmenter.
+ * @return true if spacepoint is within readout boundaries.
+ */
+ public boolean segmentCheckBounds(SpacePoint sp, int[] indices);
+
+
+ /**
+ * Calculate the position of the readout segment corresponding to the indices.
+ * Note that subclasses will interpret meaning of indices polymorphically. User
+ * is obligated to ensure a commensurate pairing of concrete ReadoutChannelSegmenter
+ * and indices.
+ * @param indices The array of indices appropriate for this segmenter.
+ * @return The position of the readout segment corresponding to the input indices.
+ */
+ public SpacePoint position(int[] indices);
+
+}
lcsim/sandbox/readout/segmentation
diff -N XYPlaneGeometer.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ XYPlaneGeometer.java 30 Nov 2010 22:46:04 -0000 1.1
@@ -0,0 +1,142 @@
+package org.lcsim.readout.segmentation;
+
+import org.lcsim.spacegeom.SpacePoint;
+import org.lcsim.spacegeom.CartesianPoint;
+/**
+ * A class describing segmentation and geometry of a plane in xy.
+ * @author Norman Graf
+ * @version 1.0
+ *
+ */
+public class XYPlaneGeometer implements ReadoutChannelSegmenter
+{
+ private double _phi0;
+ private double _vMin;
+ private double _vMax;
+ private double _zMin;
+ private double _zMax;
+ private double _rMin;
+ private double _rMax;
+ private int _nVSegments;
+ private int _nZSegments;
+ private int _nLayers;
+
+ private double _dV;
+ private double _dZ;
+ private double _dR;
+
+ /**
+ * Creates a new instance of XYPlaneSegmenter
+ * @param rInner Inner distance normal to the xyplane.
+ * @param rOuter Outer distance normal to the xyplane.
+ * @param phi Phi of the normal to the plane.
+ * @param vmin Minimum dimension in the plane normal to the radius.
+ * @param vmax Maximum dimension in the plane normal to the radius.
+ * @param zmin Minimum dimension in z.
+ * @param zmax Maximum dimension in z.
+ * @param nLayers Number of layers in radial dimension.
+ * @param nVSegments Number of segments in the v plane.
+ * @param nZSegments Number of segmentations in z.
+ */
+ public XYPlaneGeometer(double rInner, double rOuter, double phi, double vmin, double vmax, double zmin, double zmax, int nLayers, int nVSegments, int nZSegments)
+ {
+ _rMin = rInner;
+ _rMax = rOuter;
+ _phi0 = phi;
+ _vMin = vmin;
+ _vMax = vmax;
+ _zMin = zmin;
+ _zMax = zmax;
+ _nLayers = nLayers;
+ _nVSegments = nVSegments;
+ _nZSegments = nZSegments;
+
+ _dR = (_rMax-_rMin)/nLayers;
+ _dZ = (_zMax - _zMin)/nZSegments;
+ _dV = (_vMax - _vMin)/nVSegments;
+ }
+
+ /**
+ * Calculate the readout indices corresponding to the input spacepoint.
+ * This method does not check that the spacepoint is inside the volume.
+ * @param sp The spacepoint for which the readout indices are to be calculated.
+ * @param indices indices[0] is z, indices[1] is v, indices[2] is layer.
+ *
+ */
+ public void segment(SpacePoint sp, int[] indices)
+ {
+ double z = sp.z();
+ // check layer next
+ double r = sp.rxy();
+ double phi = sp.phi();
+ double rad = r*Math.cos(_phi0-phi);
+ // now check extent in v
+ double v = r*Math.sin(_phi0-phi);
+ // ok, point is inside volume
+ segment(rad, v, z, indices);
+ }
+
+ /**
+ * Calculate the readout indices corresponding to the input spacepoint.
+ * @param r The reduced radius for the spacepoint.
+ * @param v The dimension normal to the radius vector.
+ * @param z The z position.
+ * @param indices indices[0] is z, indices[1] is v, indices[2] is layer.
+ */
+ public void segment(double r, double v, double z, int[] indices)
+ {
+ indices[0] = (int) Math.rint( (z - _zMin)/_dZ);
+ indices[1] = (int) Math.rint( (v - _vMin)/_dV);
+ indices[2] = (int) Math.rint( (r-_rMin)/_dR);
+ }
+
+ /**
+ * Calculate the readout indices corresponding to the input spacepoint,
+ * checking that the point is within the readout boundaries.
+ * @param sp The spacepoint for which the readout indices are to be calculated.
+ * @param indices indices[0] is theta, indices[1] is phi, indices[2] is layer.
+ * @return true if spacepoint is within readout boundaries.
+ */
+ public boolean segmentCheckBounds(SpacePoint sp, int[] indices)
+ {
+ // limits in z are easy, do first
+ double z = sp.z();
+ if(z<_zMin || z>_zMax) return false;
+ // check layer next
+ double r = sp.rxy();
+ double phi = sp.phi();
+ double rad = r*Math.cos(_phi0-phi);
+ if(rad<_rMin || rad>_rMax) return false;
+ // now check extent in v
+ double v = r*Math.sin(_phi0-phi);
+ if(v < _vMin || v>_vMax) return false;
+ // ok, point is inside volume
+ segment(rad, v, z, indices);
+ return true;
+
+ }
+
+ public SpacePoint position(int[] indices)
+ {
+ double x = 0.;
+ double y = 0.;
+ double z = 0.;
+ return new CartesianPoint(x, y, z);
+ }
+
+
+ /**
+ * A String representation of this object.
+ * @return A String representation of this object.
+ */
+ public String toString()
+ {
+ StringBuffer sb = new StringBuffer(this.getClass().getName()+":\n");
+ sb.append("rMin, rMax, nLayers: "+_rMin+" "+_rMax+" "+_nLayers+"\n");
+ sb.append("vMin, vMax, nVSegments: "+_vMin+" "+_vMax+" "+_nVSegments+"\n");
+ sb.append("zMin, zMax, nZSegments: "+_zMin+" "+_zMax+" "+_nZSegments+"\n");
+ sb.append("phi0: "+_phi0+"\n");
+ return sb.toString();
+ }
+
+}
lcsim/sandbox/readout/segmentation
diff -N ZPlaneGeometer.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ ZPlaneGeometer.java 30 Nov 2010 22:46:04 -0000 1.1
@@ -0,0 +1,195 @@
+package org.lcsim.readout.segmentation;
+
+import org.lcsim.spacegeom.SpacePoint;
+import org.lcsim.spacegeom.TwoSpacePoint;
+import org.lcsim.spacegeom.CartesianPoint;
+/**
+ * Encapsulates the behavior of a polygonal plane perpendicular
+ * to the z axis. Segmentation is in cartesian x,y coordinates.
+ * @author Norman Graf
+ * @version 1.0
+ *
+ */
+public class ZPlaneGeometer implements ReadoutChannelSegmenter
+{
+ private double _zMin;
+ private double _zMax;
+ private int _nLayers;
+ private double _dZ;
+
+ private double _dX;
+ private double _dY;
+
+ // the vertices of the plane
+ private TwoSpacePoint[] _vertices;
+
+ // plane orientation
+ private boolean _clockwise;
+
+ /**
+ * Creates a new instance of ZPlaneGeometer
+ * @param zmin The minimum extent in z
+ * @param zmax The maximum extent in z
+ * @param nLayers The number of layers in z
+ * @param vertices The array of TwoSpacePoints representing the vertices of the polygon
+ * in the x-y plane. The polygon should be convex.
+ * @param dx The size of the x bins.
+ * @param dy The size of the y bins.
+ */
+ public ZPlaneGeometer(double zmin, double zmax, int nLayers, TwoSpacePoint[] vertices, double dx, double dy)
+ {
+ // is the polygon convex?
+ if(convex(vertices)!=1) throw new IllegalArgumentException("Polygon must be convex!");
+ _zMin = zmin;
+ _zMax = zmax;
+ _nLayers = nLayers;
+ _dZ = (_zMax-_zMin)/nLayers;
+
+ _vertices = new TwoSpacePoint[vertices.length];
+
+ System.arraycopy(vertices,0,_vertices,0,vertices.length);
+ _dX = dx;
+ _dY = dy;
+ }
+
+ /**
+ * Calculate the readout indices corresponding to the input spacepoint.
+ * This method does not check that the spacepoint is inside the volume.
+ * @param sp The spacepoint for which the readout indices are to be calculated.
+ * @param indices indices[0] is x, indices[1] is y, indices[2] is layer.
+ */
+ public void segment(SpacePoint sp, int[] indices)
+ {
+ indices[0] = (int) ( sp.x()/_dX);
+ indices[1] = (int) ( sp.y()/_dY);
+ indices[2] = (int) ( (sp.z() - _zMin)/_dZ);
+ }
+
+ /**
+ * Calculate the readout indices corresponding to the input spacepoint,
+ * checking that the point is within the readout boundaries.
+ * @param sp The spacepoint for which the readout indices are to be calculated.
+ * @param indices The array of indices appropriate for this segmenter.
+ * @return true if spacepoint is within readout boundaries.
+ */
+ public boolean segmentCheckBounds(SpacePoint sp, int[] indices)
+ {
+ // limits in z are easy, do first
+ double z = sp.z();
+ if(z<_zMin || z>_zMax) return false;
+ if(inPolygon(sp))
+ {
+ segment(sp, indices);
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+
+ /**
+ * Given a point p, determine whether it lies within this polygon. This method
+ *only checks in the x-y plane.
+ * @param p The Spacepoint to check.
+ * @return true if the (x,y) coordinates of sp lie within this polygon.
+ */
+ public boolean inPolygon(SpacePoint p)
+ {
+ double y = p.y();
+ double x = p.x();
+ int counter = 0;
+ int n = _vertices.length;
+ double xinters;
+ TwoSpacePoint p1 = _vertices[0];
+ TwoSpacePoint p2;
+ for(int i=0; i<n; ++i)
+ {
+ p2 = _vertices[i%n];
+ if(y > Math.min(p1.y(), p2.y()))
+ {
+ if (y <= Math.max(p1.y(),p2.y()))
+ {
+ if (x <= Math.max(p1.x(),p2.x()))
+ {
+ if (p1.y() != p2.y())
+ {
+ xinters = (y-p1.y())*(p2.x()-p1.x())/(p2.y()-p1.y())+p1.x();
+ if (p1.x() == p2.x() || x <= xinters)
+ counter++;
+ }
+ }
+ }
+ }
+ p1 = p2;
+ }
+ if (counter % 2 == 0)
+ return false;
+ else
+ return true;
+ }
+
+ // given an ordered list of spacepoints, return whether polygon is convex or not.
+ // we don't return a boolean since we also want to signal an error condition
+ // could also handle this with an exception!
+ private int convex(TwoSpacePoint[] p)
+ {
+ /*
+ Return whether a polygon in 2D is concave or convex
+ return 0 for incomputables eg: collinear points
+ CONVEX == 1
+ CONCAVE == -1
+ It is assumed that the polygon is simple
+ (does not intersect itself or have holes)
+ */
+
+ int i,j,k;
+ int flag = 0;
+ double z=0.;
+ int n = p.length;
+
+ if (n < 3) return 0;
+
+ for (i=0;i<n;i++)
+ {
+ j = (i + 1) % n;
+ k = (i + 2) % n;
+ z = (p[j].x() - p[i].x()) * (p[k].y() - p[j].y());
+ z -= (p[j].y() - p[i].y()) * (p[k].x() - p[j].x());
+ if (z < 0)
+ flag |= 1;
+ else if (z > 0)
+ flag |= 2;
+ if (flag == 3)
+ return -1;
+ }
+ _clockwise = (z<0);
+ if (flag != 0)
+ return 1;
+ else
+ return 0;
+ }
+
+ /**
+ * A String representation of this object
+ * @return String representing this object
+ */
+ public String toString()
+ {
+ StringBuffer sb = new StringBuffer(this.getClass().getName()+":\n");
+ sb.append("zMin, zMax, nLayers: "+_zMin+" "+_zMax+" "+_nLayers+"\n");
+ sb.append("dX, dY, dZ: "+_dX+" "+_dY+" "+_dZ+"\n");
+ return sb.toString();
+ }
+
+
+ public SpacePoint position(int[] indices)
+ {
+ double x = 0.;
+ double y = 0.;
+ double z = 0.;
+ return new CartesianPoint(x, y, z);
+ }
+
+}
CVSspam 0.2.8