Print

Print


Commit in GeomConverter/src/org/lcsim/geometry on MAIN
segmentation/GridXYZ.java+278-2311.17 -> 1.18
            /NonprojectiveCylinder.java+218-1921.19 -> 1.20
            /ProjectiveCylinder.java+132-1191.21 -> 1.22
util/BaseIDDecoder.java-21.2 -> 1.3
+628-544
4 modified files
JM: source formatting only

GeomConverter/src/org/lcsim/geometry/segmentation
GridXYZ.java 1.17 -> 1.18
diff -u -r1.17 -r1.18
--- GridXYZ.java	7 Dec 2005 10:39:37 -0000	1.17
+++ GridXYZ.java	3 Feb 2006 18:43:59 -0000	1.18
@@ -1,7 +1,5 @@
 /*
- * GridXYZ.java
- *
- * Created on May 27, 2005, 4:41 PM
+ * GridXYZ.java Created on May 27, 2005, 4:41 PM
  */
 package org.lcsim.geometry.segmentation;
 
@@ -20,11 +18,8 @@
 import org.lcsim.geometry.subdetector.CylindricalCalorimeter;
 
 /**
- * @author jeremym
- *
- * Cartesian XYZ grid segmentation, primarily used for readout of planes.
- * This segmentation is based on a local coordinate system.
- *
+ * @author jeremym Cartesian XYZ grid segmentation, primarily used for readout
+ *         of planes. This segmentation is based on a local coordinate system.
  */
 public class GridXYZ extends SegmentationBase
 {
@@ -36,165 +31,189 @@
     private int yIndex = -1;
     private int zIndex = -1;
 
-    private double[] _localPos = { 0, 0, 0};
-    private double[] _globalPos = { 0, 0, 0};
+    private double[] _localPos =
+    { 0, 0, 0 };
+
+    private double[] _globalPos =
+    { 0, 0, 0 };
 
     /** Creates a new instance of GridXYZ */
     public GridXYZ(Element node) throws DataConversionException
     {
         super(node);
 
-        if ( node.getAttribute("gridSizeX") != null )
+        if (node.getAttribute("gridSizeX") != null)
         {
             gridSizeX = node.getAttribute("gridSizeX").getDoubleValue();
         }
 
-        if ( node.getAttribute("gridSizeY") != null )
+        if (node.getAttribute("gridSizeY") != null)
         {
             gridSizeY = node.getAttribute("gridSizeY").getDoubleValue();
         }
 
-        if ( node.getAttribute("gridSizeZ") != null )
+        if (node.getAttribute("gridSizeZ") != null)
         {
             gridSizeZ = node.getAttribute("gridSizeZ").getDoubleValue();
         }
     }
 
-    /** Find neighbouring cells to the current cell.
-     *
-     * Cell neighbors are found based on the direction (theta,phi) of
-     * the reference cell w.r.t the origin.
-     *
+    /**
+     * Find neighbouring cells to the current cell. Cell neighbors are found
+     * based on the direction (theta,phi) of the reference cell w.r.t the
+     * origin.
+     * 
      * @see org.lcsim.geometry.segmentation.SegmentationBase#setID()
      * @return array of cellIDs for the neighbouring cells
      */
     public long[] getNeighbourIDs(int layerRange, int xRange, int yRange)
     {
-//       System.out.println("Nonproj neighbs: "+layerRange+" "+xRange+" "+yRange);
-      IDEncoder encoder = new IDEncoder( descriptor );
-      encoder.setValues(values);
-      long saveID = encoder.getID();
-
-      int klay = values[layerIndex];
-      int kx   = values[xIndex];
-      int ky   = values[yIndex];
-//       System.out.println("Ref.ID: ref="+klay+" "+kx+" "+ky
-// 			 +" (hex "+Long.toHexString(saveID)+")");
-//       long system = (saveID>>7) & 0x1ff;
-//       System.out.println("hit pos: x="+getX()+", y="+getY()+", z="+getZ()+", system="+system);
-
-      int nMax = (2*layerRange + 1)*(2*xRange + 1)*(2*yRange + 1) - 1;
-      long[] result = new long[nMax];
-
-      // theta and phi are used to find central neighbors in other layers
-      double theta = getTheta();
-      double phi = getPhi();
-
-      // this is not general, but specific to endcaps
-      double dx = gridSizeX;
-      double dy = gridSizeY;
-      int zBins = detector.getLayering().getLayerCount();
-      double Rmax = ((CylindricalCalorimeter)detector).getOuterRadius();
-
-      int size = 0;
-      int refLayer = values[layerIndex];
-      boolean isNegativeZ = getZ()<0 ? true : false;
-      for (int i=-layerRange; i<=layerRange; ++i) {
-	int ilay = refLayer + i;
-
-	if (ilay<0 || ilay>=zBins ) continue;
-	encoder.setValue(layerIndex,ilay);
-
-	int xBins = (int)Math.ceil( 2*Rmax / dx );
-	int yBins = xBins;
-
-	// project theta,phi to sensitive middle of current layer
-	double z = getDepthSensitiveMid( ilay );
-	if( isNegativeZ ) z = -z;
-	double rho = z * Math.tan(theta);
-	double x = rho * Math.cos(phi);
-	double y = rho * Math.sin(phi);
-//  	System.out.println("layer "+ilay+", cylR="+rho
-//  			   +", theta="+(theta*180./Math.PI)
-// 			   +", phi="+(phi*180./Math.PI)
-//  			   +", rvec=( "+x+", "+y+", "+z+")");
-
- 	long id = this.findCellContainingXYZ(x,y,z);
- 	if(id==0) continue;
-
-	this.setID(id);
-// 	System.out.println("from findXYZ: x="+getX()+", y="+getY()+", z="+getZ());
- 	for (int j=-xRange; j<=xRange; ++j) {
-	  int ix = values[xIndex] + j;
-
- 	  if (ix<-xBins/2 || ix>=xBins/2) continue;
- 	  encoder.setValue(xIndex,ix);
-
- 	  for (int k=-yRange; k<=yRange; ++k) {
-	    // skip reference cell
-	    if (i==0 && j==0 && k==0) continue;
-
- 	    int iy = values[yIndex] + k;
-	    if (iy<-yBins/2 || iy>=yBins/2) continue;
-
-//    	    System.out.println("Adding neighbor: "+ilay+" "+ix+" "+iy
-//  			       +", total="+ (size+1));
- 	    result[size++] = encoder.setValue(yIndex,iy);
-	  }
- 	}
-      }
-
-      // reset encoder and decoder
-      this.setID(saveID);
-      if(size < result.length) {
-// 	  int kklay = values[layerIndex];
-// 	  int kkx = values[xIndex];
-// 	  int kky = values[yIndex];
-//  	  System.out.println("In a border? Neighbors="+size+"/"+result.length
-//  			     +", ref="+kklay+" "+kkx+" "+kky);
-
-	  long[] temp = new long[size];
-	  System.arraycopy(result,0,temp,0,size);
-	  result = temp;
-      }
-
-//       int kklay = values[layerIndex];
-//       int kkx = values[xIndex];
-//       int kky = values[yIndex];
-//       System.out.println("Neighbors="+size+"/"+result.length
-// 			 +", ref="+kklay+" "+kkx+" "+kky
-// 			 +" (hex "+Long.toHexString(encoder.getID())+")");
-
-//       System.out.println("Leaving getNeighbours: current id="
-// 			 +values[layerIndex]+" "+values[xIndex]
-// 			 +" "+values[yIndex]);
-      return result;
+        // System.out.println("Nonproj neighbs: "+layerRange+" "+xRange+"
+        // "+yRange);
+        IDEncoder encoder = new IDEncoder(descriptor);
+        encoder.setValues(values);
+        long saveID = encoder.getID();
+
+        int klay = values[layerIndex];
+        int kx = values[xIndex];
+        int ky = values[yIndex];
+        // System.out.println("Ref.ID: ref="+klay+" "+kx+" "+ky
+        // +" (hex "+Long.toHexString(saveID)+")");
+        // long system = (saveID>>7) & 0x1ff;
+        // System.out.println("hit pos: x="+getX()+", y="+getY()+",
+        // z="+getZ()+", system="+system);
+
+        int nMax = (2 * layerRange + 1) * (2 * xRange + 1) * (2 * yRange + 1) - 1;
+        long[] result = new long[nMax];
+
+        // theta and phi are used to find central neighbors in other layers
+        double theta = getTheta();
+        double phi = getPhi();
+
+        // this is not general, but specific to endcaps
+        double dx = gridSizeX;
+        double dy = gridSizeY;
+        int zBins = detector.getLayering().getLayerCount();
+        double Rmax = ((CylindricalCalorimeter) detector).getOuterRadius();
+
+        int size = 0;
+        int refLayer = values[layerIndex];
+        boolean isNegativeZ = getZ() < 0 ? true : false;
+        for (int i = -layerRange; i <= layerRange; ++i)
+        {
+            int ilay = refLayer + i;
+
+            if (ilay < 0 || ilay >= zBins)
+                continue;
+            encoder.setValue(layerIndex, ilay);
+
+            int xBins = (int) Math.ceil(2 * Rmax / dx);
+            int yBins = xBins;
+
+            // project theta,phi to sensitive middle of current layer
+            double z = getDepthSensitiveMid(ilay);
+            if (isNegativeZ)
+                z = -z;
+            double rho = z * Math.tan(theta);
+            double x = rho * Math.cos(phi);
+            double y = rho * Math.sin(phi);
+            // System.out.println("layer "+ilay+", cylR="+rho
+            // +", theta="+(theta*180./Math.PI)
+            // +", phi="+(phi*180./Math.PI)
+            // +", rvec=( "+x+", "+y+", "+z+")");
+
+            long id = this.findCellContainingXYZ(x, y, z);
+            if (id == 0)
+                continue;
+
+            this.setID(id);
+            // System.out.println("from findXYZ: x="+getX()+", y="+getY()+",
+            // z="+getZ());
+            for (int j = -xRange; j <= xRange; ++j)
+            {
+                int ix = values[xIndex] + j;
+
+                if (ix < -xBins / 2 || ix >= xBins / 2)
+                    continue;
+                encoder.setValue(xIndex, ix);
+
+                for (int k = -yRange; k <= yRange; ++k)
+                {
+                    // skip reference cell
+                    if (i == 0 && j == 0 && k == 0)
+                        continue;
+
+                    int iy = values[yIndex] + k;
+                    if (iy < -yBins / 2 || iy >= yBins / 2)
+                        continue;
+
+                    // System.out.println("Adding neighbor: "+ilay+" "+ix+" "+iy
+                    // +", total="+ (size+1));
+                    result[size++] = encoder.setValue(yIndex, iy);
+                }
+            }
+        }
+
+        // reset encoder and decoder
+        this.setID(saveID);
+        if (size < result.length)
+        {
+            // int kklay = values[layerIndex];
+            // int kkx = values[xIndex];
+            // int kky = values[yIndex];
+            // System.out.println("In a border?
+            // Neighbors="+size+"/"+result.length
+            // +", ref="+kklay+" "+kkx+" "+kky);
+
+            long[] temp = new long[size];
+            System.arraycopy(result, 0, temp, 0, size);
+            result = temp;
+        }
+
+        // int kklay = values[layerIndex];
+        // int kkx = values[xIndex];
+        // int kky = values[yIndex];
+        // System.out.println("Neighbors="+size+"/"+result.length
+        // +", ref="+kklay+" "+kkx+" "+kky
+        // +" (hex "+Long.toHexString(encoder.getID())+")");
+
+        // System.out.println("Leaving getNeighbours: current id="
+        // +values[layerIndex]+" "+values[xIndex]
+        // +" "+values[yIndex]);
+        return result;
     }
 
     // Not for public use, this is needed to calculate positions
     // and number of cells, etc.
-    public double getZMin() {
-	return ((CylindricalCalorimeter)detector).getZMin();
+    public double getZMin()
+    {
+        return ((CylindricalCalorimeter) detector).getZMin();
     }
 
-    public double getZMax() {
-	return ((CylindricalCalorimeter)detector).getZMax();
+    public double getZMax()
+    {
+        return ((CylindricalCalorimeter) detector).getZMax();
     }
 
-    public double getRMin() {
-	return ((CylindricalCalorimeter)detector).getInnerRadius();
+    public double getRMin()
+    {
+        return ((CylindricalCalorimeter) detector).getInnerRadius();
     }
 
-    public double getRMax() {
-	return ((CylindricalCalorimeter)detector).getOuterRadius();
+    public double getRMax()
+    {
+        return ((CylindricalCalorimeter) detector).getOuterRadius();
     }
 
-    /** FIXME: Doesn't belong here, as it is always generally derivable from x and y. */
+    /**
+     * FIXME: Doesn't belong here, as it is always generally derivable from x
+     * and y.
+     */
     public double getPhi()
     {
-        double phi = atan2(getY(), getX() );
+        double phi = atan2(getY(), getX());
 
-        if ( phi < 0 )
+        if (phi < 0)
         {
             phi += 2 * PI;
         }
@@ -205,9 +224,9 @@
     /** FIXME: Doesn't belong here, as it is always computable given x and y. */
     public double getTheta()
     {
-        double theta = atan(getCylindricalRadiusFromPosition() / getZ() );
+        double theta = atan(getCylindricalRadiusFromPosition() / getZ());
 
-        if ( theta < 0 )
+        if (theta < 0)
         {
             theta += PI;
         }
@@ -255,25 +274,25 @@
 
     private void computeLocalX()
     {
-        if ( xIndex != -1 )
+        if (xIndex != -1)
         {
-            _localPos[0] = (((double)getValue(xIndex)) + 0.5) * gridSizeX;
+            _localPos[0] = (((double) getValue(xIndex)) + 0.5) * gridSizeX;
         }
     }
 
     private void computeLocalY()
     {
-        if ( yIndex != -1 )
+        if (yIndex != -1)
         {
-            _localPos[1] = (((double)getValue(yIndex)) + 0.5) * gridSizeY;
+            _localPos[1] = (((double) getValue(yIndex)) + 0.5) * gridSizeY;
         }
     }
 
     private void computeLocalZ()
     {
-        if ( zIndex != -1 )
+        if (zIndex != -1)
         {
-            _localPos[2] = (((double)getValue(zIndex)) + 0.5) * gridSizeZ;
+            _localPos[2] = (((double) getValue(zIndex)) + 0.5) * gridSizeZ;
         }
     }
 
@@ -286,131 +305,159 @@
 
     public double getCylindricalRadiusFromPosition()
     {
-        return sqrt(getX() * getX() + getY() * getY() );
+        return sqrt(getX() * getX() + getY() * getY());
     }
 
     /**
-     * Check for a valid grid size for each of XYZ.
-     * If the grid is not valid, then leave those
-     * indices flagged with invalid values.  It
-     * is actually okay to have all 0's, because
-     * this will return the center of the volume,
-     * at least in analogous Geant4 impl of this class.
+     * Check for a valid grid size for each of XYZ. If the grid is not valid,
+     * then leave those indices flagged with invalid values. It is actually okay
+     * to have all 0's, because this will return the center of the volume, at
+     * least in analogous Geant4 impl of this class.
      */
     public void setIDDescription(IDDescriptor id)
     {
         super.setIDDescription(id);
 
-        if ( gridSizeX != 0 )
+        if (gridSizeX != 0)
         {
             xIndex = id.indexOf("x");
         }
 
-        if ( gridSizeY != 0 )
+        if (gridSizeY != 0)
         {
             yIndex = id.indexOf("y");
         }
 
-        if ( gridSizeZ != 0 )
+        if (gridSizeZ != 0)
         {
             zIndex = id.indexOf("z");
         }
     }
 
     /**
-     * Returns positive distance from IR to center of sensitive slice
-     * of any layer
-     * @param layer layer index
+     * Returns positive distance from IR to center of sensitive slice of any
+     * layer
+     * 
+     * @param layer
+     *            layer index
      */
-    private double getDepthSensitiveMid(int ilay) {
-	LayerStack stack = detector.getLayering().getLayers();
-	Layer layer = stack.getLayer(ilay);
+    private double getDepthSensitiveMid(int ilay)
+    {
+        LayerStack stack = detector.getLayering().getLayers();
+        Layer layer = stack.getLayer(ilay);
 
-	double preLayers = 0;
-	if(ilay>0) preLayers = stack.getSectionThickness(0,ilay-1);
+        double preLayers = 0;
+        if (ilay > 0)
+            preLayers = stack.getSectionThickness(0, ilay - 1);
 
-	return this.getZMin() + preLayers + layer.getThicknessToSensitiveMid();
+        return this.getZMin() + preLayers + layer.getThicknessToSensitiveMid();
     }
 
     /**
-     * Return the cell which contains a given point (x,y,z).  If point is
-     * not contained in this component, zero is returned.
-     *
-     * @param x,y,z cartesian coordinates of the point
-     * @return ID of cell containing the point (maybe either in
-     * absorber or live material)
+     * Return the cell which contains a given point (x,y,z). If point is not
+     * contained in this component, zero is returned.
+     * 
+     * @param x,y,z
+     *            cartesian coordinates of the point
+     * @return ID of cell containing the point (maybe either in absorber or live
+     *         material)
      */
-    public long findCellContainingXYZ(double x, double y, double z) {
+    public long findCellContainingXYZ(double x, double y, double z)
+    {
 
-	// validate point
-	double absz = Math.abs(z);
-	if(absz<getZMin()) return 0;
-	if(absz>getZMax()) return 0;
-	double rho = Math.sqrt(x*x+y*y);
-	if(rho<getRMin()) return 0;
-	if(rho>getRMax()) return 0;
-
-	// ok, point is valid, so a valid ID should be returned
-	int ix = getXBin(x);
-	int iy = getYBin(y);
-	int ilay = getLayerBin(absz);
-
-	IDEncoder enc = new IDEncoder(descriptor);
-	enc.setValues(values);
-	enc.setValue(layerIndex, ilay);
-	enc.setValue(xIndex, ix);
-	enc.setValue(yIndex, iy);
-	long resultID = enc.getID();
-	return resultID;
-    }
-
-    public int getLayerBin(double z) {
-      // In order to be general, we should not assume that all
-      // layers have the same thickness.  Therefore, one has to
-      // guess the starting layer (based on average thickness), and
-      // then navigate through layers until one finds the right one
-      double depth = z - getZMin();
-      double mean_t = (getZMax()-getZMin()) / getNumberOfLayers();
-
-      int ilay = (int)Math.floor( depth / mean_t );
-      LayerStack stack = getLayering().getLayers();
-      Layer layer = stack.getLayer(ilay);
-      double depHi = stack.getThicknessToLayerBack(ilay);
-      double depLo = depHi - layer.getThickness();
-      for(;;) {
-	if( depth>depLo && depth<=depHi ) return ilay;
-	if( depth<=depLo ) {
-	  --ilay;
-	  depHi = depLo;
-	  layer = stack.getLayer(ilay);
-	  depLo -= layer.getThickness();
-	}
-	if( depth>depHi ) {
-	  ++ilay;
-	  depLo = depHi;
-	  layer = stack.getLayer(ilay);
-	  depHi += layer.getThickness();
-	}
-      }
-    }
-
-    public int getXBin(double x) {
-	return getBin( x, gridSizeX );
-    }
-    public int getYBin(double y) {
-	return getBin( y, gridSizeY );
-    }
-
-    public int getBin(double u, double gridSizeU) {
-      int numBins = (int)Math.floor( 2*getRMax() / gridSizeU );
-      double u0 = gridSizeU / 2;
-      int iu = (int)Math.floor((u-u0)/gridSizeU + 0.5);
-      return iu;
-    }
-
-    public double getGridSizeX() { return gridSizeX; }
-    public double getGridSizeY() { return gridSizeY; }
-    public double getGridSizeZ() { return gridSizeZ; }
+        // validate point
+        double absz = Math.abs(z);
+        if (absz < getZMin())
+            return 0;
+        if (absz > getZMax())
+            return 0;
+        double rho = Math.sqrt(x * x + y * y);
+        if (rho < getRMin())
+            return 0;
+        if (rho > getRMax())
+            return 0;
+
+        // ok, point is valid, so a valid ID should be returned
+        int ix = getXBin(x);
+        int iy = getYBin(y);
+        int ilay = getLayerBin(absz);
+
+        IDEncoder enc = new IDEncoder(descriptor);
+        enc.setValues(values);
+        enc.setValue(layerIndex, ilay);
+        enc.setValue(xIndex, ix);
+        enc.setValue(yIndex, iy);
+        long resultID = enc.getID();
+        return resultID;
+    }
+
+    public int getLayerBin(double z)
+    {
+        // In order to be general, we should not assume that all
+        // layers have the same thickness. Therefore, one has to
+        // guess the starting layer (based on average thickness), and
+        // then navigate through layers until one finds the right one
+        double depth = z - getZMin();
+        double mean_t = (getZMax() - getZMin()) / getNumberOfLayers();
+
+        int ilay = (int) Math.floor(depth / mean_t);
+        LayerStack stack = getLayering().getLayers();
+        Layer layer = stack.getLayer(ilay);
+        double depHi = stack.getThicknessToLayerBack(ilay);
+        double depLo = depHi - layer.getThickness();
+        for (;;)
+        {
+            if (depth > depLo && depth <= depHi)
+                return ilay;
+            if (depth <= depLo)
+            {
+                --ilay;
+                depHi = depLo;
+                layer = stack.getLayer(ilay);
+                depLo -= layer.getThickness();
+            }
+            if (depth > depHi)
+            {
+                ++ilay;
+                depLo = depHi;
+                layer = stack.getLayer(ilay);
+                depHi += layer.getThickness();
+            }
+        }
+    }
+
+    public int getXBin(double x)
+    {
+        return getBin(x, gridSizeX);
+    }
+
+    public int getYBin(double y)
+    {
+        return getBin(y, gridSizeY);
+    }
+
+    public int getBin(double u, double gridSizeU)
+    {
+        int numBins = (int) Math.floor(2 * getRMax() / gridSizeU);
+        double u0 = gridSizeU / 2;
+        int iu = (int) Math.floor((u - u0) / gridSizeU + 0.5);
+        return iu;
+    }
+
+    public double getGridSizeX()
+    {
+        return gridSizeX;
+    }
+
+    public double getGridSizeY()
+    {
+        return gridSizeY;
+    }
+
+    public double getGridSizeZ()
+    {
+        return gridSizeZ;
+    }
 
     private int flag1 = 0;
     private int flag2 = 0;

GeomConverter/src/org/lcsim/geometry/segmentation
NonprojectiveCylinder.java 1.19 -> 1.20
diff -u -r1.19 -r1.20
--- NonprojectiveCylinder.java	4 Jan 2006 18:33:44 -0000	1.19
+++ NonprojectiveCylinder.java	3 Feb 2006 18:43:59 -0000	1.20
@@ -1,7 +1,5 @@
 /*
- * NonprojectiveCylinder.java
- *
- * Created on March 30, 2005, 3:09 PM
+ * NonprojectiveCylinder.java Created on March 30, 2005, 3:09 PM
  */
 package org.lcsim.geometry.segmentation;
 
@@ -20,10 +18,8 @@
 import org.lcsim.geometry.util.IDEncoder;
 
 /**
- * @author jeremym
- *
- * Nonprojective segmentation of a cylinder with delta z and phi as parameters.
- *
+ * @author jeremym Nonprojective segmentation of a cylinder with delta z and phi
+ *         as parameters.
  */
 public class NonprojectiveCylinder extends BarrelCylinderSegmentationBase
 {
@@ -52,27 +48,29 @@
         gridSizeZ = gsz;
     }
 
-    public double getGridSizePhi() {
-	return gridSizePhi;
+    public double getGridSizePhi()
+    {
+        return gridSizePhi;
     }
 
-    public double getGridSizeZ() {
-	return gridSizeZ;
+    public double getGridSizeZ()
+    {
+        return gridSizeZ;
     }
 
     public double getPhi()
     {
-        return (((double)getValue(phiIndex)) + 0.5) * computeDeltaPhiForLayer();
+        return (((double) getValue(phiIndex)) + 0.5) * computeDeltaPhiForLayer();
     }
 
     public double getTheta()
     {
-	double x = this.getX();
-	double y = this.getY();
-        double theta = atan( sqrt(x*x + y*y)  / getZ() );
+        double x = this.getX();
+        double y = this.getY();
+        double theta = atan(sqrt(x * x + y * y) / getZ());
 
         /** Normalize to positive theta. */
-        if ( theta < 0 )
+        if (theta < 0)
         {
             theta += PI;
         }
@@ -82,33 +80,37 @@
 
     public double getX()
     {
-//        return detector.getLayering().getDistanceToLayerSensorMid( getLayer() ) * cos( getPhi() );
-        return getDistanceToSensitive( getLayer() ) * cos( getPhi() );
+        // return detector.getLayering().getDistanceToLayerSensorMid( getLayer()
+        // ) * cos( getPhi() );
+        return getDistanceToSensitive(getLayer()) * cos(getPhi());
     }
 
     public double getY()
     {
-//        return detector.getLayering().getDistanceToLayerSensorMid( getLayer() ) * sin( getPhi() );
-        return getDistanceToSensitive( getLayer() ) * sin( getPhi() );
+        // return detector.getLayering().getDistanceToLayerSensorMid( getLayer()
+        // ) * sin( getPhi() );
+        return getDistanceToSensitive(getLayer()) * sin(getPhi());
     }
 
     public double getZ()
     {
-        return ((double)getValue(zIndex) + 0.5) * gridSizeZ;
+        return ((double) getValue(zIndex) + 0.5) * gridSizeZ;
     }
 
     public double computeDeltaPhiForLayer(int layer)
     {
-//        double circ = detector.getLayering().getDistanceToLayerSensorMid(layer) * ( 2 * PI );
-        double circ = getDistanceToSensitive( layer ) * ( 2 * PI );
-        int nphi = (int)Math.floor( circ / gridSizePhi );
+        // double circ =
+        // detector.getLayering().getDistanceToLayerSensorMid(layer) * ( 2 * PI
+        // );
+        double circ = getDistanceToSensitive(layer) * (2 * PI);
+        int nphi = (int) Math.floor(circ / gridSizePhi);
         double deltaPhi = (2 * PI) / nphi;
         return deltaPhi;
     }
 
     public double computeDeltaPhiForLayer()
     {
-        return computeDeltaPhiForLayer( getLayer() );
+        return computeDeltaPhiForLayer(getLayer());
     }
 
     public void setIDDescription(IDDescriptor id)
@@ -123,188 +125,212 @@
         return true;
     }
 
-    /** Find neighbouring cells to the current cell.
-     *
-     * Cell neighbors are found based on the direction (theta,phi) of
-     * the reference cell w.r.t the origin.
-     *
+    /**
+     * Find neighbouring cells to the current cell. Cell neighbors are found
+     * based on the direction (theta,phi) of the reference cell w.r.t the
+     * origin.
+     * 
      * @see org.lcsim.geometry.segmentation.SegmentationBase#setID()
      * @return array of cellIDs for the neighbouring cells
      */
     public long[] getNeighbourIDs(int layerRange, int zRange, int phiRange)
     {
-//       System.out.println("Entering getNeighbourIDs: dl="+layerRange
-// 			 +", dz="+zRange+", dphi="+phiRange+", id="+printID(decoder,encoder) );
-      IDEncoder gnEncoder = new IDEncoder( descriptor );
-      BaseIDDecoder gnDecoder = new BaseIDDecoder( descriptor );
-      gnEncoder.setValues(values);
-      gnDecoder.setID( gnEncoder.getID() );
-
-      int nMax = (2*layerRange + 1)*(2*zRange + 1)*(2*phiRange + 1) - 1;
-      long[] result = new long[nMax];
-
-      // theta and phi are used to find central neighbors in other layers
-      double theta = getTheta();
-      double phi = getPhi();
-
-      int zBins = (int)Math.floor( (getZMax()-getZMin()) / getGridSizeZ() );
-
-      int size = 0;
-      for (int i=-layerRange; i<=layerRange; ++i) {
-	int ilay = values[layerIndex] + i;
-
-	if (ilay<0 || ilay>= getNumberOfLayers() ) continue;
-	gnEncoder.setValue(layerIndex,ilay);
-
-	double dphi = this.computeDeltaPhiForLayer(ilay);
-	int phiBins =  (int)Math.floor(2*Math.PI / dphi);
-
-	double cylR = getRadiusSensitiveMid( ilay );
-	double x = cylR * Math.cos(phi);
-	double y = cylR * Math.sin(phi);
-	double z = cylR / Math.tan(theta);
-
-	long id = this.findCellContainingXYZ(x,y,z);
-	if(id==0) continue;
-
-	// save indices in a new array, as values[] keeps the original ref
-	gnDecoder.setID(id);
-	for (int j=-zRange; j<=zRange; ++j) {
-          int iz = gnDecoder.getValue(zIndex) + j;
-
-	  if (iz<-zBins/2 || iz>=zBins/2) continue;
-	  gnEncoder.setValue(zIndex,iz);
-
-	  for (int k=-phiRange; k<=phiRange; ++k) {
-	    // skip reference cell (not a neighbor of its own)
-	    if (i==0 && j==0 && k==0) continue;
-
-	    int iphi = gnDecoder.getValue(phiIndex) + k;
-	    // phi is cyclic
-	    if(iphi<0) iphi += phiBins;
-	    if(iphi>=phiBins) iphi -= phiBins;
-
-	    if(iphi<0 || iphi>=phiBins) continue;
-	    gnEncoder.setValue(phiIndex,iphi);
-	    result[size++] = gnEncoder.getID();
-	  }
-	}
-      }
-
-      if(size < result.length) {
-	  long[] temp = new long[size];
-	  System.arraycopy(result,0,temp,0,size);
-	  result = temp;
-      }
+        // System.out.println("Entering getNeighbourIDs: dl="+layerRange
+        // +", dz="+zRange+", dphi="+phiRange+", id="+printID(decoder,encoder)
+        // );
+        IDEncoder gnEncoder = new IDEncoder(descriptor);
+        BaseIDDecoder gnDecoder = new BaseIDDecoder(descriptor);
+        gnEncoder.setValues(values);
+        gnDecoder.setID(gnEncoder.getID());
+
+        int nMax = (2 * layerRange + 1) * (2 * zRange + 1) * (2 * phiRange + 1) - 1;
+        long[] result = new long[nMax];
+
+        // theta and phi are used to find central neighbors in other layers
+        double theta = getTheta();
+        double phi = getPhi();
+
+        int zBins = (int) Math.floor((getZMax() - getZMin()) / getGridSizeZ());
+
+        int size = 0;
+        for (int i = -layerRange; i <= layerRange; ++i)
+        {
+            int ilay = values[layerIndex] + i;
+
+            if (ilay < 0 || ilay >= getNumberOfLayers())
+                continue;
+            gnEncoder.setValue(layerIndex, ilay);
+
+            double dphi = this.computeDeltaPhiForLayer(ilay);
+            int phiBins = (int) Math.floor(2 * Math.PI / dphi);
+
+            double cylR = getRadiusSensitiveMid(ilay);
+            double x = cylR * Math.cos(phi);
+            double y = cylR * Math.sin(phi);
+            double z = cylR / Math.tan(theta);
+
+            long id = this.findCellContainingXYZ(x, y, z);
+            if (id == 0)
+                continue;
+
+            // save indices in a new array, as values[] keeps the original ref
+            gnDecoder.setID(id);
+            for (int j = -zRange; j <= zRange; ++j)
+            {
+                int iz = gnDecoder.getValue(zIndex) + j;
+
+                if (iz < -zBins / 2 || iz >= zBins / 2)
+                    continue;
+                gnEncoder.setValue(zIndex, iz);
+
+                for (int k = -phiRange; k <= phiRange; ++k)
+                {
+                    // skip reference cell (not a neighbor of its own)
+                    if (i == 0 && j == 0 && k == 0)
+                        continue;
+
+                    int iphi = gnDecoder.getValue(phiIndex) + k;
+                    // phi is cyclic
+                    if (iphi < 0)
+                        iphi += phiBins;
+                    if (iphi >= phiBins)
+                        iphi -= phiBins;
+
+                    if (iphi < 0 || iphi >= phiBins)
+                        continue;
+                    gnEncoder.setValue(phiIndex, iphi);
+                    result[size++] = gnEncoder.getID();
+                }
+            }
+        }
+
+        if (size < result.length)
+        {
+            long[] temp = new long[size];
+            System.arraycopy(result, 0, temp, 0, size);
+            result = temp;
+        }
 
-      return result;
+        return result;
     }
 
     /**
      * Return the cell which contains a given point (x,y,z), or zero.
-     *
-     * @param x,y,z cartesian coordinates of the point
-     * @return ID of cell containing the point (maybe either in
-     * absorber or live material)
+     * 
+     * @param x,y,z
+     *            cartesian coordinates of the point
+     * @return ID of cell containing the point (maybe either in absorber or live
+     *         material)
      */
-    public long findCellContainingXYZ(double x, double y, double z) {
+    public long findCellContainingXYZ(double x, double y, double z)
+    {
 
-	// validate point
-	if(z<getZMin()) return 0;
-	if(z>getZMax()) return 0;
-	double rho = Math.sqrt(x*x+y*y);
-	if(rho<getRMin()) return 0;
-	if(rho>getRMax()) return 0;
-
-	// ok, point is valid, so a valid ID should be returned
-	int ilay = getLayerBin(rho);
-	int iz = getZBin(z);
-
-	double phi = Math.atan2( y, x );
-	if(phi<0) phi += 2*Math.PI;
-	int iphi = getPhiBin(ilay,phi);
-
-	IDEncoder enc = new IDEncoder(descriptor);
-	enc.setValues(values);
-	enc.setValue(layerIndex,ilay);
-	enc.setValue(zIndex,iz);
-	enc.setValue(phiIndex,iphi);
-	long resultID = enc.getID();
-
-	return resultID;
-    }
-
-    public int getPhiBin(int ilay, double phi) {
-      // phic is phi at center of cells with iphi=0
-      double deltaPhi = this.computeDeltaPhiForLayer(ilay);
-      double phic = deltaPhi / 2;
-      int iphi = (int)Math.floor((phi-phic)/deltaPhi + 0.5);
-      return iphi;
-    }
-
-    public int getZBin(double z) {
-      // zc is z at center of cells with iz=0
-      int numz = (int)Math.floor((getZMax()-getZMin()) / gridSizeZ);
-//       double zc = 0;  // for odd numz
-//       if( numz%2 == 0 ) zc = gridSizeZ / 2;
-      double zc = gridSizeZ / 2;
-      int iz = (int)Math.floor((z-zc)/gridSizeZ + 0.5);
-      return iz;
+        // validate point
+        if (z < getZMin())
+            return 0;
+        if (z > getZMax())
+            return 0;
+        double rho = Math.sqrt(x * x + y * y);
+        if (rho < getRMin())
+            return 0;
+        if (rho > getRMax())
+            return 0;
+
+        // ok, point is valid, so a valid ID should be returned
+        int ilay = getLayerBin(rho);
+        int iz = getZBin(z);
+
+        double phi = Math.atan2(y, x);
+        if (phi < 0)
+            phi += 2 * Math.PI;
+        int iphi = getPhiBin(ilay, phi);
+
+        IDEncoder enc = new IDEncoder(descriptor);
+        enc.setValues(values);
+        enc.setValue(layerIndex, ilay);
+        enc.setValue(zIndex, iz);
+        enc.setValue(phiIndex, iphi);
+        long resultID = enc.getID();
+
+        return resultID;
+    }
+
+    public int getPhiBin(int ilay, double phi)
+    {
+        // phic is phi at center of cells with iphi=0
+        double deltaPhi = this.computeDeltaPhiForLayer(ilay);
+        double phic = deltaPhi / 2;
+        int iphi = (int) Math.floor((phi - phic) / deltaPhi + 0.5);
+        return iphi;
+    }
+
+    public int getZBin(double z)
+    {
+        // zc is z at center of cells with iz=0
+        int numz = (int) Math.floor((getZMax() - getZMin()) / gridSizeZ);
+        // double zc = 0; // for odd numz
+        // if( numz%2 == 0 ) zc = gridSizeZ / 2;
+        double zc = gridSizeZ / 2;
+        int iz = (int) Math.floor((z - zc) / gridSizeZ + 0.5);
+        return iz;
     }
 
     /**
      * Returns cylindrical radius to center of sensitive slice of any layer
-     * @param layer layer index
+     * 
+     * @param layer
+     *            layer index
      */
-    private double getRadiusSensitiveMid(int ilay) {
-	LayerStack stack = getLayering().getLayers();
-	Layer layer = stack.getLayer(ilay);
-
-	double preLayers = 0;
-	if(ilay>0) preLayers = stack.getSectionThickness(0,ilay-1);
-
-	return this.getRMin() + preLayers + layer.getThicknessToSensitiveMid();
-    }
-
-//    private String printID(IDDecoder dec, IDEncoder enc) {
-//	String ret = "decoder: <"+dec.getValue("layer")
-//	    +" "+dec.getValue("z")
-//	    +" "+dec.getValue("phi")+">";
-//	ret += " --- encoder: "+printID(enc.getID());
-//	return ret;
-//    }
-//
-//    public static String printID(long id) {
-//	return new String("<"+Long.toHexString(id)
-//			  +": "+Integer.toString( getSysBE(id) )
-//			  +" "+Integer.toString( getLayer(id) )
-//			  +" "+Integer.toString( getThetaBin(id))
-//			  +" "+Integer.toString( getPhiBin(id) )
-//			  +">");
-//    }
-
-
-//    public static int getSysBE( long cellid ) {
-//	return (int)((cellid>>16) & 0x3f);
-//    }
-//
-//    public static int getLayer( long cellid ) {
-//	int layer = (int)((cellid>>0) & 0xffff);
-//	return layer;
-//    }
-//
-//    public static int getThetaBin( long cellid ) {
-//	int max = 1<<16;  // for 11 bits
-//	int thetabin = (int)((cellid>>48) & 0xffff);
-//	if( thetabin > max/2-1 ) thetabin = thetabin - max;
-//	return thetabin;
-//    }
-//
-//    public static int getPhiBin( long cellid ) {
-//// 	int max = 1<<11;  // for 11 bits
-//// 	int phibin = (int)((cellid>>43) & 0x7ff);
-//// 	if( phibin > max/2-1 ) phibin = phibin - max;
-//// 	return phibin;
-// 	return (int)((cellid>>32) & 0xffff);
-//    }
+    private double getRadiusSensitiveMid(int ilay)
+    {
+        LayerStack stack = getLayering().getLayers();
+        Layer layer = stack.getLayer(ilay);
+
+        double preLayers = 0;
+        if (ilay > 0)
+            preLayers = stack.getSectionThickness(0, ilay - 1);
+
+        return this.getRMin() + preLayers + layer.getThicknessToSensitiveMid();
+    }
+
+    // private String printID(IDDecoder dec, IDEncoder enc) {
+    // String ret = "decoder: <"+dec.getValue("layer")
+    // +" "+dec.getValue("z")
+    // +" "+dec.getValue("phi")+">";
+    // ret += " --- encoder: "+printID(enc.getID());
+    // return ret;
+    // }
+    //
+    // public static String printID(long id) {
+    // return new String("<"+Long.toHexString(id)
+    // +": "+Integer.toString( getSysBE(id) )
+    // +" "+Integer.toString( getLayer(id) )
+    // +" "+Integer.toString( getThetaBin(id))
+    // +" "+Integer.toString( getPhiBin(id) )
+    // +">");
+    // }
+
+    // public static int getSysBE( long cellid ) {
+    // return (int)((cellid>>16) & 0x3f);
+    // }
+    //
+    // public static int getLayer( long cellid ) {
+    // int layer = (int)((cellid>>0) & 0xffff);
+    // return layer;
+    // }
+    //
+    // public static int getThetaBin( long cellid ) {
+    // int max = 1<<16; // for 11 bits
+    // int thetabin = (int)((cellid>>48) & 0xffff);
+    // if( thetabin > max/2-1 ) thetabin = thetabin - max;
+    // return thetabin;
+    // }
+    //
+    // public static int getPhiBin( long cellid ) {
+    // // int max = 1<<11; // for 11 bits
+    // // int phibin = (int)((cellid>>43) & 0x7ff);
+    // // if( phibin > max/2-1 ) phibin = phibin - max;
+    // // return phibin;
+    // return (int)((cellid>>32) & 0xffff);
+    // }
 }

GeomConverter/src/org/lcsim/geometry/segmentation
ProjectiveCylinder.java 1.21 -> 1.22
diff -u -r1.21 -r1.22
--- ProjectiveCylinder.java	12 Dec 2005 04:44:24 -0000	1.21
+++ ProjectiveCylinder.java	3 Feb 2006 18:43:59 -0000	1.22
@@ -8,145 +8,158 @@
 import org.lcsim.geometry.Layered;
 
 /**
- *
  * @author tonyj
  */
 public class ProjectiveCylinder extends BarrelCylinderSegmentationBase
 {
-   private int thetaBins;
-   private int phiBins;
+    private int thetaBins;
+    private int phiBins;
 
-   private int thetaIndex;
-   private int phiIndex;
+    private int thetaIndex;
+    private int phiIndex;
 
-   ProjectiveCylinder(Element node) throws DataConversionException
-   {
-      super(node);
-      thetaBins = node.getAttribute("thetaBins").getIntValue();
-      phiBins = node.getAttribute("phiBins").getIntValue();
-   }
-
-   public double getPhi()
-   {
-      return Math.PI*2*(getValue(phiIndex)+0.5)/phiBins;
-   }
-
-   public double getTheta()
-   {
-      return Math.PI*(getValue(thetaIndex)+0.5)/thetaBins;
-   }
-
-   public double getX()
-   {
-      return getDistanceToSensitive(getLayer())*Math.cos(getPhi());
-   }
-
-   public double getY()
-   {
-      return getDistanceToSensitive(getLayer())*Math.sin(getPhi());
-   }
-
-   public double getZ()
-   {
-      double cosTheta = Math.cos(getTheta());
-      return getDistanceToSensitive(getLayer())*cosTheta/Math.sqrt(1-cosTheta*cosTheta);
-   }
-
-   public void setIDDescription(IDDescriptor id)
-   {
-      super.setIDDescription(id);
-
-      phiIndex = id.indexOf("phi");
-      thetaIndex = id.indexOf("theta");
-   }
-
-   public boolean supportsNeighbours()
-   {
-      return true;
-   }
-
-   public long[] getNeighbourIDs(int deltaLayer, int deltaTheta, int deltaPhi)
-   {
-      IDEncoder encoder = new IDEncoder( descriptor );
-      encoder.setValues(values);
-
-      int nMax = (2*deltaLayer + 1)*(2*deltaTheta + 1)*(2*deltaPhi + 1) - 1;
-      int size = 0;
-      long[] result = new long[nMax];
-      for (int i=-deltaLayer;i<=deltaLayer;i++)
-      {
-         int l = values[layerIndex] + i;
-
-         if (l<0 || l>= getNumberOfLayers() ) continue;
-         encoder.setValue(layerIndex,l);
-
-         for (int j=-deltaTheta;j<=deltaTheta;j++)
-         {
-            int t = values[thetaIndex] + j;
+    ProjectiveCylinder(Element node) throws DataConversionException
+    {
+        super(node);
+        thetaBins = node.getAttribute("thetaBins").getIntValue();
+        phiBins = node.getAttribute("phiBins").getIntValue();
+    }
+
+    public double getPhi()
+    {
+        return Math.PI * 2 * (getValue(phiIndex) + 0.5) / phiBins;
+    }
+
+    public double getTheta()
+    {
+        return Math.PI * (getValue(thetaIndex) + 0.5) / thetaBins;
+    }
+
+    public double getX()
+    {
+        return getDistanceToSensitive(getLayer()) * Math.cos(getPhi());
+    }
+
+    public double getY()
+    {
+        return getDistanceToSensitive(getLayer()) * Math.sin(getPhi());
+    }
 
-            if (t<0 || t>=thetaBins) continue;
-            encoder.setValue(thetaIndex,t);
+    public double getZ()
+    {
+        double cosTheta = Math.cos(getTheta());
+        return getDistanceToSensitive(getLayer()) * cosTheta / Math.sqrt(1 - cosTheta * cosTheta);
+    }
+
+    public void setIDDescription(IDDescriptor id)
+    {
+        super.setIDDescription(id);
 
-            for (int k=-deltaPhi;k<=deltaPhi;k++)
+        phiIndex = id.indexOf("phi");
+        thetaIndex = id.indexOf("theta");
+    }
+
+    public boolean supportsNeighbours()
+    {
+        return true;
+    }
+
+    public long[] getNeighbourIDs(int deltaLayer, int deltaTheta, int deltaPhi)
+    {
+        IDEncoder encoder = new IDEncoder(descriptor);
+        encoder.setValues(values);
+
+        int nMax = (2 * deltaLayer + 1) * (2 * deltaTheta + 1) * (2 * deltaPhi + 1) - 1;
+        int size = 0;
+        long[] result = new long[nMax];
+        for (int i = -deltaLayer; i <= deltaLayer; i++)
+        {
+            int l = values[layerIndex] + i;
+
+            if (l < 0 || l >= getNumberOfLayers())
+                continue;
+            encoder.setValue(layerIndex, l);
+
+            for (int j = -deltaTheta; j <= deltaTheta; j++)
             {
-               if (i==0 && j==0 && k==0) continue;
+                int t = values[thetaIndex] + j;
 
-               int p = values[phiIndex] + k;
-               if (p<0 || p>=phiBins) continue;
+                if (t < 0 || t >= thetaBins)
+                    continue;
+                encoder.setValue(thetaIndex, t);
+
+                for (int k = -deltaPhi; k <= deltaPhi; k++)
+                {
+                    if (i == 0 && j == 0 && k == 0)
+                        continue;
+
+                    int p = values[phiIndex] + k;
+                    if (p < 0 || p >= phiBins)
+                        continue;
 
-               result[size++] = encoder.setValue(phiIndex,p);
+                    result[size++] = encoder.setValue(phiIndex, p);
+                }
             }
-         }
-      }
-      if (size < result.length)
-      {
-         long[] temp = new long[size];
-         System.arraycopy(result,0,temp,0,size);
-         result = temp;
-      }
-      return result;
-   }
+        }
+        if (size < result.length)
+        {
+            long[] temp = new long[size];
+            System.arraycopy(result, 0, temp, 0, size);
+            result = temp;
+        }
+        return result;
+    }
 
-    public int getThetaBins() {
-	return thetaBins;
+    public int getThetaBins()
+    {
+        return thetaBins;
     }
-    public int getPhiBins() {
-	return phiBins;
+
+    public int getPhiBins()
+    {
+        return phiBins;
     }
 
     /**
      * Return the cell which contains a given point (x,y,z), or zero.
-     *
-     * @param x,y,z cartesian coordinates of the point
-     * @return ID of cell containing the point (maybe either in
-     * absorber or live material)
+     * 
+     * @param x,y,z
+     *            cartesian coordinates of the point
+     * @return ID of cell containing the point (maybe either in absorber or live
+     *         material)
      */
-    public long findCellContainingXYZ(double x, double y, double z) {
+    public long findCellContainingXYZ(double x, double y, double z)
+    {
 
-	// validate point
-	if(z<getZMin()) return 0;
-	if(z>getZMax()) return 0;
-	double rho = Math.sqrt(x*x+y*y);
-	if(rho<getRMin()) return 0;
-	if(rho>getRMax()) return 0;
-
-	// ok, point is valid, so a valid ID should be returned
-	int ilay = getLayerBin(rho);
-
-	double phi = Math.atan2( y, x );
-	if(phi<0) phi += 2*Math.PI;
-	int iphi = (int)( phi * phiBins / (2*Math.PI) );
-
-	double theta = Math.atan2( rho, z );
-	int itheta = (int)(theta*thetaBins/Math.PI);
-
-	IDEncoder enc = new IDEncoder(descriptor);
-	enc.setValues(values);
-	enc.setValue(layerIndex,ilay);
-	enc.setValue(thetaIndex,itheta);
-	enc.setValue(phiIndex,iphi);
-	long resultID = enc.getID();
+        // validate point
+        if (z < getZMin())
+            return 0;
+        if (z > getZMax())
+            return 0;
+        double rho = Math.sqrt(x * x + y * y);
+        if (rho < getRMin())
+            return 0;
+        if (rho > getRMax())
+            return 0;
+
+        // ok, point is valid, so a valid ID should be returned
+        int ilay = getLayerBin(rho);
+
+        double phi = Math.atan2(y, x);
+        if (phi < 0)
+            phi += 2 * Math.PI;
+        int iphi = (int) (phi * phiBins / (2 * Math.PI));
+
+        double theta = Math.atan2(rho, z);
+        int itheta = (int) (theta * thetaBins / Math.PI);
+
+        IDEncoder enc = new IDEncoder(descriptor);
+        enc.setValues(values);
+        enc.setValue(layerIndex, ilay);
+        enc.setValue(thetaIndex, itheta);
+        enc.setValue(phiIndex, iphi);
+        long resultID = enc.getID();
 
-	return resultID;
+        return resultID;
     }
 }

GeomConverter/src/org/lcsim/geometry/util
BaseIDDecoder.java 1.2 -> 1.3
diff -u -r1.2 -r1.3
--- BaseIDDecoder.java	28 Oct 2005 00:34:25 -0000	1.2
+++ BaseIDDecoder.java	3 Feb 2006 18:44:00 -0000	1.3
@@ -7,8 +7,6 @@
 
 package org.lcsim.geometry.util;
 
-import org.lcsim.geometry.IDDecoder;
-
 /**
  *
  * @author jeremym
CVSspam 0.2.8