Commit in lcsim/src/org/lcsim/contrib/onoprien/tracking/geom on MAIN
segmenters/CylindricalBarrelSegmenter.java+14-21.1 -> 1.2
          /DiskToWedgesSegmenter.java+3-21.1 -> 1.2
          /DiskTrackerSegmenter.java+8-51.3 -> 1.4
          /DiskTrackerToRingsSegmenter.java+2-21.1 -> 1.2
          /DiskTrackerToWedgesSegmenter.java+31-11.5 -> 1.6
sensortypes/Cylinder.java+69-1311.1 -> 1.2
           /Rectangle.java+147-261.1 -> 1.2
           /Ring.java+2-171.1 -> 1.2
+276-186
8 modified files
stereo related changes

lcsim/src/org/lcsim/contrib/onoprien/tracking/geom/segmenters
CylindricalBarrelSegmenter.java 1.1 -> 1.2
diff -u -r1.1 -r1.2
--- CylindricalBarrelSegmenter.java	25 Sep 2007 03:16:33 -0000	1.1
+++ CylindricalBarrelSegmenter.java	9 Oct 2007 18:08:52 -0000	1.2
@@ -28,7 +28,7 @@
  * 
  * 
  * @author D.Onoprienko
- * @version $Id: CylindricalBarrelSegmenter.java,v 1.1 2007/09/25 03:16:33 onoprien Exp $
+ * @version $Id: CylindricalBarrelSegmenter.java,v 1.2 2007/10/09 18:08:52 onoprien Exp $
  */
 public class CylindricalBarrelSegmenter extends RegionSegmenter {
   
@@ -58,6 +58,11 @@
     Subdetector sub = detector.getSubdetector(_sdName);
     if (sub == null) return;
     _detElts = AbstractSegmenter.getLeaves(sub.getDetectorElement());
+    for (IDetectorElement de : _detElts) {
+      if (!(de.getGeometry().getLogicalVolume().getSolid() instanceof Tube)) {
+        throw new RuntimeException("You are trying to apply CylindricalBarrelSegmenter to detector whose barrel is not made of Tubes");
+      }
+    }
     Collections.sort(_detElts, new Comparator<IDetectorElement>() {
       public int compare(IDetectorElement s1, IDetectorElement s2) {
         return (int)Math.signum(((Tube)(s1.getGeometry().getLogicalVolume().getSolid())).getInnerRadius()
@@ -114,10 +119,17 @@
 
   /** Creates a {@link Sensor} object given the ID. */
   public Sensor makeSensor(int postfix) {
-    SensorType type = new Cylinder(_length[postfix], _radius[postfix], _thickness[postfix], _stripLength, _stripWidth);
+    SensorType type = new Cylinder(_radius[postfix], _length[postfix], _thickness[postfix], _stripWidth, _stripLength);
     return new Sensor(_detElts.get(postfix), postfixToID(postfix), type, _trans, _rot);
   }
   
+  /**
+   * Returnes <tt>null</tt> since there is no stereo in cylindrical barel.
+   */
+  public List<Integer> getStereoPartners(int sensorID) {
+    return null;
+  }
+  
 // -- Private parts :  ---------------------------------------------------------
   
   String _sdName;

lcsim/src/org/lcsim/contrib/onoprien/tracking/geom/segmenters
DiskToWedgesSegmenter.java 1.1 -> 1.2
diff -u -r1.1 -r1.2
--- DiskToWedgesSegmenter.java	25 Sep 2007 03:16:33 -0000	1.1
+++ DiskToWedgesSegmenter.java	9 Oct 2007 18:08:52 -0000	1.2
@@ -21,7 +21,7 @@
  * Simplistic <tt>Segmenter</tt> that tiles a single disk with wedges.
  * 
  * @author D. Onoprienko
- * @version $Id: DiskToWedgesSegmenter.java,v 1.1 2007/09/25 03:16:33 onoprien Exp $
+ * @version $Id: DiskToWedgesSegmenter.java,v 1.2 2007/10/09 18:08:52 onoprien Exp $
  */
 public class DiskToWedgesSegmenter extends RegionSegmenter {
   
@@ -57,7 +57,8 @@
 
     _rotation = new Transformation3D[_nPhi];
     for (int indexPhi=0; indexPhi < _nPhi; indexPhi++ ) {
-      _rotation[indexPhi] = new Rotation3D(Axis.Z, _deltaPhi * indexPhi);
+      double angle = (left) ? _deltaPhi * (indexPhi + 1) - Math.PI/2. : _deltaPhi * indexPhi - Math.PI/2.;
+      _rotation[indexPhi] = new Rotation3D(Axis.Z, angle);
     }
   }
 // -- Implementing RegionSegmenter :  ------------------------------------------

lcsim/src/org/lcsim/contrib/onoprien/tracking/geom/segmenters
DiskTrackerSegmenter.java 1.3 -> 1.4
diff -u -r1.3 -r1.4
--- DiskTrackerSegmenter.java	1 Oct 2007 20:48:07 -0000	1.3
+++ DiskTrackerSegmenter.java	9 Oct 2007 18:08:52 -0000	1.4
@@ -17,7 +17,7 @@
  * method that assigns segmenters to disks.
  *
  * @author D. Onoprienko
- * @version $Id: DiskTrackerSegmenter.java,v 1.3 2007/10/01 20:48:07 onoprien Exp $
+ * @version $Id: DiskTrackerSegmenter.java,v 1.4 2007/10/09 18:08:52 onoprien Exp $
  */
 abstract public class DiskTrackerSegmenter extends ForwardingSegmenter {
   
@@ -89,12 +89,15 @@
   public boolean isInner(IDetectorElement de) {
     return (getLayer(de) % 2) == 0;
   }
+  
+  protected int getOtherSideIndex(int daughterIndex) {
+    return (daughterIndex % 2 == 0) ? daughterIndex + 1 : daughterIndex - 1 ;
+  }
 
 // -- Private parts :  ---------------------------------------------------------
   
-  String _subdName;
-  List<IDetectorElement> _dElements;
-  
-  HashMap<IDetectorElement,AbstractSegmenter> _deToSegmenter;
+  protected String _subdName;
+  protected List<IDetectorElement> _dElements;
   
+  protected HashMap<IDetectorElement,AbstractSegmenter> _deToSegmenter;
 }

lcsim/src/org/lcsim/contrib/onoprien/tracking/geom/segmenters
DiskTrackerToRingsSegmenter.java 1.1 -> 1.2
diff -u -r1.1 -r1.2
--- DiskTrackerToRingsSegmenter.java	25 Sep 2007 03:16:33 -0000	1.1
+++ DiskTrackerToRingsSegmenter.java	9 Oct 2007 18:08:52 -0000	1.2
@@ -32,7 +32,7 @@
  * {@link #setStereoAngle(double angle)}.
  * 
  * @author D.Onoprienko
- * @version $Id: DiskTrackerToRingsSegmenter.java,v 1.1 2007/09/25 03:16:33 onoprien Exp $
+ * @version $Id: DiskTrackerToRingsSegmenter.java,v 1.2 2007/10/09 18:08:52 onoprien Exp $
  */
 public class DiskTrackerToRingsSegmenter extends RegionSegmenter {
   
@@ -134,7 +134,7 @@
 
   /** Creates a {@link Sensor} object given the ID. */
   public Sensor makeSensor(int postfix) {
-    SensorType type = new Ring(_radiusInner[postfix], _radiusOuter[postfix], _thickness[postfix], _stripLength, _stripWidth);
+    SensorType type = new Ring(_radiusInner[postfix], _radiusOuter[postfix], _stripWidth, _stripLength, _thickness[postfix]);
     Hep3Vector trans = new BasicHep3Vector(0.,0.,_z[postfix]);
     int layer = (postfix < _nDisks) ? _nDisks - postfix - 1 : postfix - _nDisks ;
     Rotation3D rot = (layer % 2 == 0) ? _rot0 : _rot1 ;

lcsim/src/org/lcsim/contrib/onoprien/tracking/geom/segmenters
DiskTrackerToWedgesSegmenter.java 1.5 -> 1.6
diff -u -r1.5 -r1.6
--- DiskTrackerToWedgesSegmenter.java	1 Oct 2007 20:48:07 -0000	1.5
+++ DiskTrackerToWedgesSegmenter.java	9 Oct 2007 18:08:52 -0000	1.6
@@ -13,7 +13,7 @@
  *
  *
  * @author D. Onoprienko
- * @version $Id: DiskTrackerToWedgesSegmenter.java,v 1.5 2007/10/01 20:48:07 onoprien Exp $
+ * @version $Id: DiskTrackerToWedgesSegmenter.java,v 1.6 2007/10/09 18:08:52 onoprien Exp $
  */
 public class DiskTrackerToWedgesSegmenter extends DiskTrackerSegmenter {
   
@@ -30,6 +30,8 @@
    */
   public AbstractSegmenter assignSegmenter(IDetectorElement de) {
     
+    checkGeometry();
+    
     int nRadialSlices;
     if (_radialSlicesBySuperlayer == null) {
       IGeometryInfo gInfo = de.getGeometry();
@@ -59,7 +61,21 @@
     
     return new DiskToWedgesSegmenter(de, nRadialSlices, nPhiSlices, pitch, left);
   }
+
+// -- Stereo partners :  -------------------------------------------------------
   
+  /**
+   * Returns a list of <tt>Sensors</tt> that might contain hits that should be combined
+   * with hits in the <tt>Sensor</tt> whose <tt>sensorID</tt> is supplied as an argument
+   * to form stereo pairs. 
+   */
+  public List<Integer> getStereoPartners(int sensorID) {
+    int partnerDisk = getOtherSideIndex(idToDaughterIndex(sensorID));
+    List<Integer> out = new ArrayList<Integer>(1);
+    out.add((partnerDisk << _daughterPostfixLength) | (sensorID & ~_daughterIdMask));
+    return out;
+  }
+
 // -- Setters :  ---------------------------------------------------------------
   
   /**
@@ -111,6 +127,20 @@
     //_pitchBySuperlayer = Arrays.copyOf(pitch, pitch.length); // Need JDK 1.6
     _pitchBySuperlayer = pitch;
   }
+  
+// -- Helpers :  ---------------------------------------------------------------
+  
+  protected void checkGeometry() {
+    int nDisks = _dElements.size()/4;
+    String m1 = "Disk tracker "+_subdName +" contains "+nDisks +" disks in each endcap, but you only supplied ";
+    if (_radialSlicesBySuperlayer != null && _radialSlicesBySuperlayer.length < nDisks ) {
+      throw new RuntimeException(m1 + "number of radial slices for " + _radialSlicesBySuperlayer.length + " superlayers");
+    } else if (_phiSlicesBySuperlayer != null && _phiSlicesBySuperlayer.length < nDisks ) {
+      throw new RuntimeException(m1 + "number of phi slices for " + _radialSlicesBySuperlayer.length + " superlayers");
+    } else if (_pitchBySuperlayer != null && _pitchBySuperlayer.length < nDisks ) {
+      throw new RuntimeException(m1 + "strip widths for " + _radialSlicesBySuperlayer.length + " superlayers");
+    }
+  }
     
 // -- Private parts :  ---------------------------------------------------------
   

lcsim/src/org/lcsim/contrib/onoprien/tracking/geom/sensortypes
Cylinder.java 1.1 -> 1.2
diff -u -r1.1 -r1.2
--- Cylinder.java	25 Sep 2007 03:16:33 -0000	1.1
+++ Cylinder.java	9 Oct 2007 18:08:52 -0000	1.2
@@ -10,95 +10,84 @@
 
 /**
  * This class represents a cylindrical sensor with strips parallel to its axis.
- * The reference frame is cylindrical (U,V,W = Phi,Z,R) with the origin at the 
- * center of the cylinder.
+ * The reference frame is cylindrical (U,V,W = Phi,Z,R), with the position of origin 
+ * controled by <tt>Hep3Vector center</tt> parameter given to a constructor.
+ * If <tt>center = (Phi0,Z0,R0)</tt>, then the sensor volume of the cylinder will be defined by 
+ * <tt><nobr>Phi0-PI < u < Phi0+PI ,</nobr> 
+ * <nobr>Z0-length < v < Z0+length ,</nobr> 
+ * <nobr>R0-thickness/2 < w < R0+thickness/2</nobr></tt>. 
+ * Constructors that do not require <tt>center</tt> parameter assume
+ * <nobr><tt>center = (0.,0.,radius)</tt></nobr>,
+ * placing the local reference frame origin in the center of the detector with 
+ * <tt>phi</tt> ranging from <tt>-PI</tt> to <tt>PI</tt>.
  *
  * @author D.Onoprienko
- * @version $Id: Cylinder.java,v 1.1 2007/09/25 03:16:33 onoprien Exp $
+ * @version $Id: Cylinder.java,v 1.2 2007/10/09 18:08:52 onoprien Exp $
  */
-public class Cylinder implements SensorType {
+public class Cylinder extends Rectangle {
   
 // -- Constructors :  ----------------------------------------------------------
   
-  /** Default constructor for use by subclusses. No initialization. */
-  public Cylinder() {}
-  
   /**
    * Create <tt>Cylinder</tt> instance.
+   * The <tt>center</tt> parameter controls offsets in the local reference frame.
    *
    * @param length      Length of the cylinder (along strip direction).
    * @param radius      Radius of the cylinder.
    * @param thickness   Thickness of the sensor.
    * @param nLength     Number of divisions along the cylinder length.
    * @param nPhi        Number of divisions in phi.
+   * @param center      Controls definition of the local reference frame
    */
-  public Cylinder(double length, double radius, double thickness, 
-                   int nLength, int nPhi) {
-    _halfLength = length/2.;
-    _halfThick = thickness/2.;
-    _radius = radius;
-    _nDivV = nLength;
-    _nDivU = nPhi;
-    _stripWidth = TWOPI/_nDivU;
-    _stripLength = length/_nDivV;
-    _hitDim = (_stripLength/_stripWidth < 4.) ? 2 : 1;
+  public Cylinder(double radius, double length, double thickness, int nPhi, int nLength, Hep3Vector center) {
+    super(TWOPI, length, thickness, nPhi, nLength, center);
+    _hitDim = ((length/nLength)/(TWOPI*radius/nPhi) < 4.) ? 2 : 1;
   }
   
   /**
    * Create <tt>Cylinder</tt> instance.
-   * Strip width will be adjusted to make sure integral number of strips fits the 
-   * circumference of the cylinder.
    *
    * @param length      Length of the cylinder (along strip direction).
    * @param radius      Radius of the cylinder.
    * @param thickness   Thickness of the sensor.
    * @param nLength     Number of divisions along the cylinder length.
-   * @param stripPitch  Strip width.
+   * @param nPhi        Number of divisions in phi.
    */
-  public Cylinder(double length, double radius, double thickness, 
-                   int nLength, double stripPitch) {
-    _halfLength = length/2.;
-    _halfThick = thickness/2.;
-    _radius = radius;
-    _nDivV = nLength;
-    _nDivU = (int) Math.round((TWOPI*radius)/stripPitch);
-    _stripWidth = TWOPI/_nDivU;
-    _stripLength = length/_nDivV;
-    _hitDim = (_stripLength/_stripWidth < 4.) ? 2 : 1;
+  public Cylinder(double radius, double length, double thickness, int nPhi, int nLength) {
+    this(radius, length, thickness, nPhi, nLength, new BasicHep3Vector(0.,0.,radius));
   }
   
   /**
    * Create <tt>Cylinder</tt> instance.
-   * Strip width and length will be adjusted to make sure integral number of 
-   * strips fits the circumference and the length of the cylinder.
+   * Strip width will be adjusted to make sure integral number of strips fits the 
+   * circumference of the cylinder.
    *
-   * @param length        Length of the cylinder (along strip direction).
-   * @param radius        Radius of the cylinder.
-   * @param thickness     Thickness of the sensor.
-   * @param stripLength   Strip length.
-   * @param stripPitch    Strip width.
-   */
-  public Cylinder(double length, double radius, double thickness, 
-                   double stripLength, double stripPitch) {
-    _halfLength = length/2.;
-    _halfThick = thickness/2.;
-    _radius = radius;
-    _nDivV = (int) Math.round(length/stripLength);
-    _nDivU = (int) Math.round((TWOPI*radius)/stripPitch);
-    _stripWidth = TWOPI/_nDivU;
-    _stripLength = length/_nDivV;
-    _hitDim = (stripLength/stripPitch < 4.) ? 2 : 1;
+   * @param length       Length of the cylinder (along strip direction).
+   * @param radius       Radius of the cylinder.
+   * @param thickness    Thickness of the sensor.
+   * @param stripPitch   Strip width.
+   * @param stripLength  Strip length.
+   * @param center       Controls definition of the local reference frame
+   */
+  public Cylinder(double radius, double length, double thickness, double stripPitch, double stripLength, Hep3Vector center) {
+    this(radius, length, thickness, (int) Math.round((TWOPI*radius)/stripPitch), (int) Math.round(length/stripLength), center);
   }
-
-// -- Setters :  ---------------------------------------------------------------
   
   /**
-   * Set the dimension of a measurement by this type of sensor (1 for strips, 2 for pixels, etc).
+   * Create <tt>Cylinder</tt> instance.
+   * Strip width will be adjusted to make sure integral number of strips fits the 
+   * circumference of the cylinder.
+   *
+   * @param length       Length of the cylinder (along strip direction).
+   * @param radius       Radius of the cylinder.
+   * @param thickness    Thickness of the sensor.
+   * @param stripPitch   Strip width.
+   * @param stripLength  Strip length.
    */
-  public void setHitDimension(int dim) {
-    _hitDim = dim;
+  public Cylinder(double radius, double length, double thickness, double stripPitch, double stripLength) {
+    this(radius, length, thickness, stripPitch, stripLength, new BasicHep3Vector(0.,0.,radius));
   }
-  
+
 // -----------------------------------------------------------------------------
 
   /**
@@ -107,49 +96,19 @@
    */
   public int getChannelID(Hep3Vector point) {
     
-    if (Math.abs(point.z()-_radius) > _halfThick) return -1;
+    if (Math.abs(point.z()-_wCenter) > _thick/2.) return -1;
 
     double u = point.x();
     double v = point.y();
-    if (u < 0. || u > TWOPI || Math.abs(v) > _halfLength) return -1;
-    
-    int nU = (int) Math.floor(u/_stripWidth); if (nU == _nDivU) nU--;
-    int nV = (int) Math.floor((v+_halfLength)/_stripLength); if (nV == _nDivV) nV--;
-    return nV*_nDivU + nU + 1;
-  }
-  
-  /**
-   * Returns position of the center of the given channel, in local sensor coordinates.
-   */
-  public Hep3Vector getChannelPosition(int channelID) {
-    int nU = --channelID % _nDivU;
-    int nV = channelID / _nDivU;
-    double u = (nU + .5) * _stripWidth;
-    double v = (nV + .5) * _stripLength - _halfLength;
-    return new BasicHep3Vector(u,v,_radius);
-  }
-  
-  /** Returns maximum possible channel ID on this sensor. */
-  public int getMaxChannelID() {
-    return  _nDivU * _nDivV;
-  }
-  
-  /**
-   * Returns dimensions of the given channel along U, V, W.
-   */
-  public Hep3Vector getChannelDimensions(int channelID) {
-    return new BasicHep3Vector(_stripWidth, _stripLength, 2.*_halfThick);
-  }
-  
-  /**
-   * Returns the dimension of a measurement by this type of sensor
-   * (1 for strips, 2 for pixels, etc). 
-   * By default, this method returns <tt>1</tt> if strip length is at least 4 times
-   * bigger than strip pitch. The return value can also be set explicitly through a call
-   * to {@link #setHitDimension(int)}.
-   */
-  public int getHitDimension() {
-    return _hitDim;
+
+    int nV = (int) Math.floor((v-_vLow)/_length);
+    if ((nV < 0) || (nV >= _nDivV)) return -1;
+
+    int nU = (int) Math.floor((u-_uLow)/_pitch); 
+    while (nU < 0) nU += _nDivU;
+    while (nU >= _nDivU) nU -= _nDivU;
+
+    return nV*_nDivU + nU;
   }
   
   /**
@@ -161,18 +120,12 @@
    * @param shiftU     move in <tt>U</tt> direction by <tt>shiftU</tt> channels
    */
   public int getNeighbor(int channelID, int shiftU, int shiftV) {
-    int nU = (--channelID % _nDivU) + shiftU;
-    if (nU < 0) {
-      nU += _nDivU;
-    } else if (nU >= _nDivU) {
-      nU -= _nDivU;
-    }
     int nV = (channelID / _nDivU) + shiftV;
-    if (nV < 0 || nV >= _nDivV) {
-      return -1;
-    } else {
-      return nV*_nDivU + nU + 1;
-    }
+    if (nV < 0 || nV >= _nDivV) return -1;
+    int nU = (channelID % _nDivU) + shiftU;
+    while (nU < 0) nU += _nDivU;
+    while (nU >= _nDivU) nU -= _nDivU;
+    return nV*_nDivU + nU;
   }
   
   /** 
@@ -182,37 +135,22 @@
    * ({@link #getHitDimension()} returns 2), up to 8 neighbors can be found.
    */
   public List<Integer> getNeighbors(int channelID) {
-    int nU = ((channelID -1) % _nDivU);
-    int nV = ((channelID -1) / _nDivU);
+    int nU = channelID % _nDivU;
+    int nV = channelID / _nDivU;
     ArrayList<Integer> out = new ArrayList<Integer>(8);
-    if ((_hitDim == 2) && (nV > 0)) {
-      out.add((nU > 0) ? (channelID - _nDivU - 1) : (channelID - 1) );
-      out.add( channelID - _nDivU );
-      out.add( (nU < _nDivU - 1) ? (channelID - _nDivU + 1) : (channelID - 2*_nDivU + 1) );
-    }
-    out.add( (nU > 0) ? (channelID - 1) : (channelID - 1 + _nDivU) );
-    out.add( (nU < _nDivU - 1) ? (channelID +1) : (channelID - _nDivU + 1) );
-    if ((_hitDim == 2) && (nV < _nDivV-1)) {
-      out.add( (nU > 0) ? (channelID + _nDivU -1) : (channelID - 1 + 2*_nDivU) );
-      out.add(channelID + _nDivU);
-      out.add( (nU < _nDivU - 1) ? (channelID + _nDivU + 1) : (channelID + 1) );
+    int vDown = ((_hitDim == 2) && (nV > 0)) ? nV-1 : nV;
+    int vUp = ((_hitDim == 2) && (nV < _nDivV-1)) ? nV+1 : nV;
+    for (int iV = vDown; iV < vUp; iV++) {
+      for (int iU = nU-1; iU < nU+1; iU++) {
+        while (nU < 0) nU += _nDivU;
+        while (nU >= _nDivU) nU -= _nDivU;
+        out.add(nV*_nDivU + nU);
+      }
     }
     return out;
   }
-  
+
 // -- Private parts :  ---------------------------------------------------------
   
-  protected double _halfLength;
-  protected double _halfThick;
-  protected double _radius;
-  
-  protected double _stripWidth;
-  protected double _stripLength;
-  
-  protected int _hitDim;
-  
-  protected int _nDivU;
-  protected int _nDivV;
-  
   static final double TWOPI = 2.*Math.PI;
 }

lcsim/src/org/lcsim/contrib/onoprien/tracking/geom/sensortypes
Rectangle.java 1.1 -> 1.2
diff -u -r1.1 -r1.2
--- Rectangle.java	25 Sep 2007 03:16:33 -0000	1.1
+++ Rectangle.java	9 Oct 2007 18:08:52 -0000	1.2
@@ -13,7 +13,7 @@
  * The reference frame origin is at the center of the sensor.
  *
  * @author D.Onoprienko
- * @version $Id: Rectangle.java,v 1.1 2007/09/25 03:16:33 onoprien Exp $
+ * @version $Id: Rectangle.java,v 1.2 2007/10/09 18:08:52 onoprien Exp $
  */
 public class Rectangle implements SensorType {
   
@@ -23,24 +23,147 @@
   public Rectangle() {}
   
   /**
-   * Create <tt>Rectangle</tt> instance.
+   * Create an instance of <tt>Rectangle</tt>.
+   * The <tt>center</tt> parameter controls how the local reference frame origin
+   * is positioned with respect to the cuboid defining the sensor volume.
    *
    * @param width       Width of the sensor.
    * @param length      Length of the sensor (along strip direction).
    * @param thickness   Thickness of the sensor.
    * @param nWidth      Number of divisions across the sensor width.
    * @param nLength     Number of divisions along the sensor length.
+   * @param center      Position of the cuboid center in the local reference frame
    */
   public Rectangle(double width, double length, double thickness, 
-                   int nWidth, int nLength) {
-    _halfLength = length/2.;
-    _halfWidth = width/2.;
-    _halfThick = thickness/2.;
-    _nDivV = nLength;
-    _nDivU = nWidth;
+                   int nWidth, int nLength, Hep3Vector center) {
+    if (nLength == 0) nLength = 1;
+    _uLow = center.x() - width/2.;
+    _vLow = center.y() - length/2.;
+    _wCenter = center.z();
     _pitch = width/nWidth;
     _length = length/nLength;
+    _thick = thickness;
     _hitDim = (_length/_pitch < 4.) ? 2 : 1;
+    _nDivV = nLength;
+    _nDivU = nWidth;
+//    System.out.println("Rect w "+width+" len "+length+" thick "+thickness+" nW "+nWidth+" nL "+nLength+" center "+center);
+//    System.out.println(" pitch "+_pitch+" length "+_length+" thick "+_thick+" hitDim "+_hitDim);
+  }
+  
+  /**
+   * Create <tt>Rectangle</tt> instance.
+   * Reference frame origin will be in the center of the cuboid defining the sensor volume.
+   *
+   * @param width       Width of the sensor.
+   * @param length      Length of the sensor (along strip direction).
+   * @param thickness   Thickness of the sensor.
+   * @param nWidth      Number of divisions across the sensor width.
+   * @param nLength     Number of divisions along the sensor length.
+   */
+  public Rectangle(double width, double length, double thickness, int nWidth, int nLength) {
+    this(width, length, thickness, nWidth, nLength, new BasicHep3Vector());
+  }
+  
+  /**
+   * Create <tt>Rectangle</tt> instance.
+   * The <tt>center</tt> parameter controls how the local reference frame origin
+   * is positioned with respect to the cuboid defining the sensor volume.
+   * Strip width will be rounded to place integral number of strips on the rectangle.
+   *
+   * @param width       Width of the sensor.
+   * @param length      Length of the sensor (along strip direction).
+   * @param thickness   Thickness of the sensor.
+   * @param stripPitch  Strip width.
+   * @param nLength     Number of divisions along the sensor length.
+   * @param center      Position of the cuboid center in the local reference frame
+   */
+  public Rectangle(double width, double length, double thickness, 
+                   double stripPitch, int nLength, Hep3Vector center) {
+    this(width, length, thickness, (int)Math.round(width/stripPitch), nLength, center);
+  }
+  
+  /**
+   * Create <tt>Rectangle</tt> instance.
+   * Reference frame origin will be in the center of the cuboid defining the sensor volume.
+   * Strip width will be rounded to place integral number of strips on the rectangle.
+   *
+   * @param width       Width of the sensor.
+   * @param length      Length of the sensor (along strip direction).
+   * @param thickness   Thickness of the sensor.
+   * @param stripPitch  Strip width.
+   * @param nLength     Number of divisions along the sensor length.
+   */
+  public Rectangle(double width, double length, double thickness, 
+                   double stripPitch, int nLength) {
+    this(width, length, thickness, (int)Math.round(width/stripPitch), nLength, new BasicHep3Vector());
+  }
+  
+  /**
+   * Create <tt>Rectangle</tt> instance.
+   * The <tt>center</tt> parameter controls how the local reference frame origin
+   * is positioned with respect to the cuboid defining the sensor volume.
+   * Strip length will be rounded to place integral number of strips on the rectangle.
+   *
+   * @param width         Width of the sensor.
+   * @param length        Length of the sensor (along strip direction).
+   * @param thickness     Thickness of the sensor.
+   * @param nWidth        Number of divisions across the sensor width.
+   * @param stripLength   Strip length.
+   * @param center        Position of the cuboid center in the local reference frame
+   */
+  public Rectangle(double width, double length, double thickness, 
+                   int nWidth, double stripLength, Hep3Vector center) {
+    this(width, length, thickness, nWidth, (int)Math.round(length/stripLength), center);
+  }
+  
+  /**
+   * Create <tt>Rectangle</tt> instance.
+   * Reference frame origin will be in the center of the cuboid defining the sensor volume.
+   * Strip length will be rounded to place integral number of strips on the rectangle.
+   *
+   * @param width         Width of the sensor.
+   * @param length        Length of the sensor (along strip direction).
+   * @param thickness     Thickness of the sensor.
+   * @param nWidth        Number of divisions across the sensor width.
+   * @param stripLength   Strip length.
+   */
+  public Rectangle(double width, double length, double thickness, 
+                   int nWidth, double stripLength) {
+    this(width, length, thickness, nWidth, (int)Math.round(length/stripLength), new BasicHep3Vector());
+  }
+  
+  /**
+   * Create <tt>Rectangle</tt> instance.
+   * The <tt>center</tt> parameter controls how the local reference frame origin
+   * is positioned with respect to the cuboid defining the sensor volume.
+   * Strip width and length will be rounded to place integral number of strips on the rectangle.
+   *
+   * @param width         Width of the sensor.
+   * @param length        Length of the sensor (along strip direction).
+   * @param thickness     Thickness of the sensor.
+   * @param stripPitch    Strip width.
+   * @param stripLength   Strip length.
+   * @param center        Position of the cuboid center in the local reference frame
+   */
+  public Rectangle(double width, double length, double thickness, 
+                   double stripPitch, double stripLength, Hep3Vector center) {
+    this(width, length, thickness, (int)Math.round(width/stripPitch), (int)Math.round(length/stripLength), center);
+  }
+  
+  /**
+   * Create <tt>Rectangle</tt> instance.
+   * Reference frame origin will be in the center of the cuboid defining the sensor volume.
+   * Strip width and length will be rounded to place integral number of strips on the rectangle.
+   *
+   * @param width         Width of the sensor.
+   * @param length        Length of the sensor (along strip direction).
+   * @param thickness     Thickness of the sensor.
+   * @param stripPitch    Strip width.
+   * @param stripLength   Strip length.
+   */
+  public Rectangle(double width, double length, double thickness, 
+                   double stripPitch, double stripLength) {
+    this(width, length, thickness, (int)Math.round(width/stripPitch), (int)Math.round(length/stripLength), new BasicHep3Vector());
   }
 
 // -- Setters :  ---------------------------------------------------------------
@@ -60,16 +183,15 @@
    */
   public int getChannelID(Hep3Vector point) {
     
-    if (Math.abs(point.z()) > _halfThick) return -1;
+    if (Math.abs(point.z()-_wCenter) > _thick/2.) return -1;
 
     double u = point.x();
     double v = point.y();
-    if (Math.abs(u) > _halfWidth || Math.abs(v) > _halfLength) return -1;
     
-    int nU = (int) Math.floor((u+_halfWidth)/_pitch); 
-    if ((nU == _nDivU) || (nU < 0)) return -1;
-    int nV = (int) Math.floor((v+_halfLength)/_length);
-    if ((nV == _nDivV) || (nV < 0)) return -1;
+    int nU = (int) Math.floor((u-_uLow)/_pitch); 
+    if ((nU < 0) || (nU >= _nDivU)) return -1;
+    int nV = (int) Math.floor((v-_vLow)/_length);
+    if ((nV < 0) || (nV >= _nDivV)) return -1;
     return nV*_nDivU + nU;
   }
   
@@ -79,9 +201,9 @@
   public Hep3Vector getChannelPosition(int channelID) {
     int nU = channelID % _nDivU;
     int nV = channelID / _nDivU;
-    double u = (nU + .5) * _pitch - _halfWidth;
-    double v = (nV + .5) * _length - _halfLength;
-    return new BasicHep3Vector(u,v,0.);
+    double u = (nU + .5) * _pitch + _uLow;
+    double v = (nV + .5) * _length + _vLow;
+    return new BasicHep3Vector(u,v,_wCenter);
   }
 
   /** Returns maximum possible channel ID on this sensor. */
@@ -93,7 +215,7 @@
    * Returns dimensions of the given channel along U, V, W.
    */
   public Hep3Vector getChannelDimensions(int channelID) {
-    return new BasicHep3Vector(_pitch, _length, 2.*_halfThick);
+    return new BasicHep3Vector(_pitch, _length, _thick);
   }
   
   /**
@@ -117,12 +239,10 @@
    */
   public int getNeighbor(int channelID, int shiftU, int shiftV) {
     int nU = (channelID % _nDivU) + shiftU;
+    if ((nU < 0) || (nU >= _nDivU)) return -1;
     int nV = (channelID / _nDivU) + shiftV;
-    if (nU < 0 || nV < 0 || nU >= _nDivU || nV >= _nDivV) {
-      return -1;
-    } else {
-      return nV*_nDivU + nU;
-    }
+    if ((nV < 0) || (nV >= _nDivV)) return -1;
+    return nV*_nDivU + nU;
   }
   
   /** Returns array of IDs of all immediate neighbor channels. */
@@ -144,12 +264,13 @@
   
 // -- Private parts :  ---------------------------------------------------------
   
-  protected double _halfLength;
-  protected double _halfWidth;
-  protected double _halfThick;
+  protected double _uLow;
+  protected double _vLow;
+  protected double _wCenter;
   
   protected double _pitch;
   protected double _length;
+  protected double _thick;
   
   protected int _hitDim;
   

lcsim/src/org/lcsim/contrib/onoprien/tracking/geom/sensortypes
Ring.java 1.1 -> 1.2
diff -u -r1.1 -r1.2
--- Ring.java	25 Sep 2007 03:16:33 -0000	1.1
+++ Ring.java	9 Oct 2007 18:08:52 -0000	1.2
@@ -9,14 +9,11 @@
  * Class to represent a disk sensor divided into rectangular strips or pixels.
  * Reference frame origin is at the center of the disk. 
  *
- * Note that {@link #getNeighbors(int)} method of an instance of this class can
- * return non-existing channel IDs - for the sake of speed, no ckecking is done 
- * to verify that returned IDs belong to channels inside the ring. 
  * {@link #getChannelID(Hep3Vector)} method returns <tt>-1</tt> if and only if the 
  * center of the rectangle (strip) to which the point belongs is ouside the ring.
  *
  * @author D.Onoprienko
- * @version $Id: Ring.java,v 1.1 2007/09/25 03:16:33 onoprien Exp $
+ * @version $Id: Ring.java,v 1.2 2007/10/09 18:08:52 onoprien Exp $
  */
 public class Ring extends Rectangle {
   
@@ -32,21 +29,9 @@
    * @param thickness   Thickness of the sensor.
    */
   public Ring(double radiusMin, double radiusMax, double pitch, double length, double thickness) {
-    
+    super(pitch*Math.ceil(2.*radiusMax/pitch), length*Math.ceil(2.*radiusMax/length), thickness, pitch, length);
     _rMin = radiusMin;
     _rMax = radiusMax;
-    
-    _nDivU = (int) Math.ceil(2.*radiusMax/pitch);
-    _nDivV = (int) Math.ceil(2.*radiusMax/length);
-    
-    _halfWidth = (_nDivU * pitch)/2.;
-    _halfLength = (_nDivV * length)/2.;
-    _halfThick = thickness/2.;
-    
-    _pitch = pitch;
-    _length = length;
-    
-    _hitDim = (_length/_pitch < 4.) ? 2 : 1;
   }
   
 // -----------------------------------------------------------------------------
CVSspam 0.2.8