Print

Print


Commit in lcsim/src/org/lcsim/contrib/onoprien/vsegment/geom/segmenter on MAIN
DiskToWedgesSegmenter.java+143added 1.1
DiskTrackerSegmenter.java+103added 1.1
DiskTrackerToRingsSegmenter.java+174added 1.1
DiskTrackerToWedgesSegmenter.java+155added 1.1
SubdetectorBasedSegmenter.java+80added 1.1
+655
5 added files
Updated Segmenters

lcsim/src/org/lcsim/contrib/onoprien/vsegment/geom/segmenter
DiskToWedgesSegmenter.java added at 1.1
diff -N DiskToWedgesSegmenter.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ DiskToWedgesSegmenter.java	3 Sep 2008 16:02:51 -0000	1.1
@@ -0,0 +1,143 @@
+package org.lcsim.contrib.onoprien.vsegment.geom.segmenter;
+
+import hep.physics.vec.BasicHep3Vector;
+import hep.physics.vec.Hep3Vector;
+import org.lcsim.detector.IDetectorElement;
+import org.lcsim.detector.IGeometryInfo;
+import org.lcsim.detector.ILogicalVolume;
+import org.lcsim.detector.IPhysicalVolume;
+import org.lcsim.detector.IRotation3D;
+import org.lcsim.detector.Transform3D;
+import org.lcsim.detector.Translation3D;
+import org.lcsim.detector.Rotation3D;
+import org.lcsim.detector.solids.Tube;
+import org.lcsim.event.SimTrackerHit;
+
+import org.lcsim.contrib.onoprien.vsegment.geom.RegionSegmenter;
+import org.lcsim.contrib.onoprien.vsegment.geom.Sensor;
+import org.lcsim.contrib.onoprien.vsegment.geom.SensorType;
+import org.lcsim.contrib.onoprien.vsegment.geom.sensortype.WedgeSideParallel;
+import org.lcsim.contrib.onoprien.vsegment.transform.ConstHep3Vector;
+import org.lcsim.contrib.onoprien.vsegment.transform.RefFrameCartesian;
+
+/**
+ * Simplistic <tt>Segmenter</tt> that tiles a single disk with wedges.
+ * 
+ * @author D. Onoprienko
+ * @version $Id: DiskToWedgesSegmenter.java,v 1.1 2008/09/03 16:02:51 onoprien Exp $
+ */
+public class DiskToWedgesSegmenter extends RegionSegmenter {
+  
+// -- Constructors :  ----------------------------------------------------------
+  
+  public DiskToWedgesSegmenter(IDetectorElement disk, int nRadialSlices, int nPhiSlices, double pitch, boolean left) {
+    
+    _de = disk;
+    _left = left;
+    _pitch = pitch;
+    _nPhi = nPhiSlices;
+    _nRadial = nRadialSlices;
+    
+    IGeometryInfo gInfo = _de.getGeometry();
+    Tube solid = (Tube) gInfo.getLogicalVolume().getSolid();
+    _rMiddleMin = solid.getInnerRadius();
+    double rMax = solid.getOuterRadius();
+    double halfThickness = solid.getZHalfLength();
+
+    _z = gInfo.getPosition().z();
+    _zMin = _z - halfThickness;
+    _zMax = _z + halfThickness;
+    
+    _deltaPhi = (2.*Math.PI)/nPhiSlices;
+    _rMin = _rMiddleMin/Math.cos(_deltaPhi/2.);
+    _deltaR = (rMax - _rMin) / nRadialSlices;
+    _deltaRMiddle = _deltaR * Math.cos(_deltaPhi/2.);
+    
+    _sType = new SensorType[_nRadial];
+    for (int indexR=0; indexR < _nRadial; indexR++) {
+      _sType[indexR] = new WedgeSideParallel(_rMin+_deltaR*indexR, _deltaR, _deltaPhi, _pitch, _left);
+    }
+
+    _rotation = new Rotation3D[_nPhi];
+    for (int indexPhi=0; indexPhi < _nPhi; indexPhi++ ) {
+      double angle = (left) ? _deltaPhi * (indexPhi + 1) - Math.PI/2. : _deltaPhi * indexPhi - Math.PI/2.;
+      _rotation[indexPhi] = Rotation3D.passiveZRotation(angle);
+      _u[indexPhi] = new ConstHep3Vector(_rotation[indexPhi].rotated(ConstHep3Vector.V100));
+      _v[indexPhi] = new ConstHep3Vector(_rotation[indexPhi].rotated(ConstHep3Vector.V010));
+    }
+  }
+// -- Implementing RegionSegmenter :  ------------------------------------------
+
+  /**
+   * Returns <tt>postfix</tt> corresponding to the position of the given simulated hit. 
+   */
+  protected int makePostfix(SimTrackerHit hit) {
+    
+    double[] pos = hit.getPoint();
+    
+    if (pos[2]<_zMin || pos[2]>_zMax) return -1;
+    
+    double r = Math.hypot(pos[0],pos[1]);
+    double phi = Math.atan2(pos[1], pos[0]);
+    phi = (phi > 0.) ? phi : phi + Math.PI * 2.;
+    
+    int indexPhi = (int) Math.floor(phi/_deltaPhi);
+    if (indexPhi < 0) indexPhi = 0;
+    if (indexPhi >= _nPhi) indexPhi = _nPhi -1;
+    
+    double rMiddle = r * Math.cos(phi - _deltaPhi*(indexPhi+.5));
+    int indexR = (int) Math.floor((rMiddle - _rMiddleMin) / _deltaRMiddle);
+    if ((indexR < 0) || (indexR >= _nRadial)) return -1;
+    
+    return (_nRadial * indexPhi) + indexR;
+  }
+  
+  /**
+   * Returns maximum postfix value that can be returned by
+   * {@link #makePostfix(SimTrackerHit)} method of this <tt>Segmenter</tt> object.
+   */
+  protected int getMaxPostfix() {
+    return (_nRadial * _nPhi) - 1;
+  }
+
+  /**
+   * 
+   * Creates a new {@link Sensor} object given the <tt>postfix</tt>.
+   */
+  protected Sensor makeSensor(int postfix) {
+    int indexR = postfix % _nRadial;
+    int indexPhi = postfix / _nRadial;
+    double r = _rMin + indexR * _deltaR;
+    double phi = (indexPhi + 1) * _deltaPhi;
+    Hep3Vector translation = new BasicHep3Vector(r*Math.cos(phi), r*Math.sin(phi), _z);
+    RefFrameCartesian rf =
+            new RefFrameCartesian(new Transform3D(new Translation3D(translation), _rotation[indexPhi]), null,
+            _u[indexPhi], _v[indexPhi], ConstHep3Vector.V001);
+    return new Sensor(_de, postfixToID(postfix), _sType[indexR], rf);
+  }
+
+// -- Private parts :  ---------------------------------------------------------
+  
+  IDetectorElement _de;
+  
+  boolean _left;
+  double _pitch;
+  
+  int _nPhi;
+  int _nRadial;
+  
+  double _z;
+  double _zMin;
+  double _zMax;
+  
+  double _rMin;
+  double _rMiddleMin;
+  
+  double _deltaPhi;
+  double _deltaR;
+  double _deltaRMiddle;
+  
+  SensorType[] _sType;
+  IRotation3D[] _rotation;
+  ConstHep3Vector[] _u, _v;
+}

lcsim/src/org/lcsim/contrib/onoprien/vsegment/geom/segmenter
DiskTrackerSegmenter.java added at 1.1
diff -N DiskTrackerSegmenter.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ DiskTrackerSegmenter.java	3 Sep 2008 16:02:51 -0000	1.1
@@ -0,0 +1,103 @@
+package org.lcsim.contrib.onoprien.vsegment.geom.segmenter;
+
+import java.util.*;
+
+import org.lcsim.detector.IDetectorElement;
+import org.lcsim.event.SimTrackerHit;
+import org.lcsim.geometry.Detector;
+import org.lcsim.geometry.Subdetector;
+
+import org.lcsim.contrib.onoprien.vsegment.geom.AbstractSegmenter;
+import org.lcsim.contrib.onoprien.vsegment.geom.ForwardingSegmenter;
+
+/**
+ * Forwarding segmenter that chooses daughter segmenter based on the {@link IDetectorElement}
+ * associated with the hit. Daughter segmenters are prefixed in the order of increasing Z
+ * of the disks they handle. Subclasses should implement {@link #assignSegmenter(IDetectorElement)}
+ * method that assigns segmenters to disks.
+ *
+ * @author D. Onoprienko
+ * @version $Id: DiskTrackerSegmenter.java,v 1.1 2008/09/03 16:02:51 onoprien Exp $
+ */
+abstract public class DiskTrackerSegmenter extends ForwardingSegmenter {
+  
+// -- Constructors :  ----------------------------------------------------------
+  
+  public DiskTrackerSegmenter(String subdetectorName) {
+    _subdName = subdetectorName;
+  }
+  
+// -- Choosing daughter Segmenter :  -------------------------------------------
+
+  /**
+   * Returns daughter <tt>Segmenter</tt> that can handle the given hit.
+   */
+  public AbstractSegmenter chooseSegmenter(SimTrackerHit hit) {
+    return _deToSegmenter.get(hit.getDetectorElement());
+  }
+  
+// -- Initialization :  --------------------------------------------------------
+  
+  public void detectorChanged(Detector detector) {
+    Subdetector sub = detector.getSubdetector(_subdName);
+    if (sub == null) return;
+    _dElements = AbstractSegmenter.getLeaves(sub.getDetectorElement());
+    Collections.sort(_dElements, new Comparator<IDetectorElement>() {
+      public int compare(IDetectorElement s1, IDetectorElement s2) {
+        return (int)Math.signum(s1.getGeometry().getPosition().z()-s2.getGeometry().getPosition().z());
+      }
+    });
+    _deToSegmenter = new HashMap<IDetectorElement,AbstractSegmenter>();
+    removeAllDaughterSegmenters();
+    for (IDetectorElement de : _dElements) {
+      AbstractSegmenter segmenter = assignSegmenter(de);
+      addDaughterSegmenter(segmenter);
+      _deToSegmenter.put(de, segmenter);
+    }
+    updateDaughterSegmenters(detector);
+  }
+  
+  /**
+   * Subclasses should implement this method to return <tt>Segmenter</tt> that 
+   * handles hits in the given <tt>DetectorElement</tt>.
+   */
+  abstract public AbstractSegmenter assignSegmenter(IDetectorElement de);
+  
+// -- Utility methods :  -------------------------------------------------------
+  
+  /**
+   * Returns layer number for the disk.
+   */
+  public int getLayer(IDetectorElement de) {
+    int index = _dElements.indexOf(de);
+    int nLayers = _dElements.size()/2;
+    return (index < nLayers) ? nLayers-index-1 : index - nLayers;
+  }
+  
+  /**
+   * Returns superlayer number for the disk.
+   * Superlayer is a pair of sensor disks on opposite sides of the same support disk.
+   */
+  public int getSuperlayer(IDetectorElement de) {
+    return getLayer(de)/2;
+  }
+  
+  /**
+   * Returns <tt>true</tt> if the disk is on the side of a superlayer that faces 
+   * the center of the detector.
+   */
+  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 :  ---------------------------------------------------------
+  
+  protected String _subdName;
+  protected List<IDetectorElement> _dElements;
+  
+  protected HashMap<IDetectorElement,AbstractSegmenter> _deToSegmenter;
+}

lcsim/src/org/lcsim/contrib/onoprien/vsegment/geom/segmenter
DiskTrackerToRingsSegmenter.java added at 1.1
diff -N DiskTrackerToRingsSegmenter.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ DiskTrackerToRingsSegmenter.java	3 Sep 2008 16:02:51 -0000	1.1
@@ -0,0 +1,174 @@
+package org.lcsim.contrib.onoprien.vsegment.geom.segmenter;
+
+import java.util.*;
+
+import hep.physics.vec.BasicHep3Vector;
+import hep.physics.vec.Hep3Vector;
+import org.lcsim.event.SimTrackerHit;
+import org.lcsim.geometry.Detector;
+import org.lcsim.geometry.Subdetector;
+import org.lcsim.detector.IDetectorElement;
+import org.lcsim.detector.IGeometryInfo;
+import org.lcsim.detector.ILogicalVolume;
+import org.lcsim.detector.IPhysicalVolume;
+import org.lcsim.detector.IRotation3D;
+import org.lcsim.detector.Transform3D;
+import org.lcsim.detector.Translation3D;
+import org.lcsim.detector.Rotation3D;
+import org.lcsim.detector.solids.Tube;
+import org.lcsim.units.clhep.SystemOfUnits;
+
+import org.lcsim.contrib.onoprien.vsegment.geom.AbstractSegmenter;
+import org.lcsim.contrib.onoprien.vsegment.geom.RegionSegmenter;
+import org.lcsim.contrib.onoprien.vsegment.geom.Sensor;
+import org.lcsim.contrib.onoprien.vsegment.geom.SensorType;
+import org.lcsim.contrib.onoprien.vsegment.geom.sensortype.Ring;
+import org.lcsim.contrib.onoprien.vsegment.transform.ConstHep3Vector;
+import org.lcsim.contrib.onoprien.vsegment.transform.IRefFrame;
+import org.lcsim.contrib.onoprien.vsegment.transform.RefFrameCartesian;
+
+/**
+ * 
+ * Simplistic <tt>Segmenter</tt> that tiles endcap disks with strips or pixels.
+ * <p>
+ * Each disk will correspond to a {@link Sensor} object. Postfixes are assigned in
+ * the increasing Z order. Sensors corresponding to layers facing away from the center
+ * of the detector are rotated by an angle set through a call to 
+ * {@link #setStereoAngle(double angle)}.
+ * 
+ * @author D.Onoprienko
+ * @version $Id: DiskTrackerToRingsSegmenter.java,v 1.1 2008/09/03 16:02:51 onoprien Exp $
+ */
+public class DiskTrackerToRingsSegmenter extends RegionSegmenter {
+  
+// -- Constructors and initialization :  ---------------------------------------
+  
+  /**
+   * 
+   * Creates a new instance of DiskTrackerToRingsSegmenter.
+   * Subdetector name supplied to the constructor is used to provide reasonable 
+   * defaults for strip width, length, and stereo angle.
+   */
+  public DiskTrackerToRingsSegmenter(String subdetectorName) {
+    _sdName = subdetectorName;
+    if (_sdName == "TrackerEndcap") {
+      setStripWidth(25.*SystemOfUnits.micrometer);
+      setStripLength(10.*SystemOfUnits.cm);
+      setStereoAngle(Math.PI / 2.);
+    } else if (_sdName == "VertexEndcap" || _sdName == "TrackerForward") {
+      setStripWidth(25.*SystemOfUnits.micrometer);
+      setStripLength(25.*SystemOfUnits.micrometer);
+      setStereoAngle(0.);
+    }
+  }
+
+  /** 
+   * Detector-dependent initialization.
+   */
+  public void detectorChanged(Detector detector) {
+    super.detectorChanged(detector);
+    Subdetector sub = detector.getSubdetector(_sdName);
+    if (sub == null) return;
+    _detElts = AbstractSegmenter.getLeaves(sub.getDetectorElement());
+    Collections.sort(_detElts, new Comparator<IDetectorElement>() {
+      public int compare(IDetectorElement s1, IDetectorElement s2) {
+        return (int)Math.signum(s1.getGeometry().getPosition().z()-s2.getGeometry().getPosition().z());
+      }
+    });
+    _nDisks = _detElts.size();
+    _nLayers = _nDisks/2;
+    _radiusInner = new double[_nDisks];
+    _radiusOuter = new double[_nDisks];
+    _thickness = new double[_nDisks];
+    _z = new double[_nDisks];
+    int postfix = 0;
+    for (IDetectorElement del : _detElts) {
+      IGeometryInfo gInfo = del.getGeometry();
+      Tube solid = (Tube) gInfo.getLogicalVolume().getSolid();
+      _radiusInner[postfix] = solid.getInnerRadius();
+      _radiusOuter[postfix] = solid.getOuterRadius();
+      _thickness[postfix] = solid.getZHalfLength()*2.;
+      _z[postfix] = gInfo.getPosition().z();
+      postfix++;
+    }
+  }
+  
+// -- Setters :  ---------------------------------------------------------------
+
+  /**
+   * Set strip width.
+   * Default is 25 micron.
+   */
+  public void setStripWidth(double pitch) {
+    _stripWidth = pitch;
+  }
+
+  /**
+   * Set strip length. 
+   * Default is 10 cm for "TrackerEndcap", 25 micron for "VertexEndcap" and "TrackerForward".
+   */
+  public void setStripLength(double length) {
+    _stripLength = length;
+  }
+
+  /**
+   * Set stereo angle.
+   * Default is 90 degrees for "TrackerEndcap", 0 for "VertexEndcap" and "TrackerForward".
+   */
+  public void setStereoAngle(double angle) {
+    _rot1 = Rotation3D.passiveZRotation(angle);
+    _u1 = new ConstHep3Vector(_rot1.rotated(ConstHep3Vector.V100));
+    _v1 = new ConstHep3Vector(_rot1.rotated(ConstHep3Vector.V010));
+  }
+
+// -- Implementing RegionSegmenter :  ------------------------------------------
+
+  /**
+   * Returns sensor ID postfix corresponding to the given position.
+   */
+  public int makePostfix(SimTrackerHit hit) {
+    int layer = hit.getLayer();
+    return hit.getPoint()[2] < 0. ? _nLayers - layer - 1  : _nLayers + layer ;
+  }
+  
+  /**
+   * Returns maximum postfix value that can be returned by
+   * {@link #makePostfix(SimTrackerHit)} method of this <tt>Segmenter</tt>.
+   */
+  public int getMaxPostfix() {
+    return _nDisks - 1;
+  }
+
+  /** Creates a {@link Sensor} object given the ID. */
+  public Sensor makeSensor(int postfix) {
+    SensorType type = new Ring(_radiusInner[postfix], _radiusOuter[postfix], _stripWidth, _stripLength, _thickness[postfix], 0.);
+    Hep3Vector trans = new BasicHep3Vector();
+    int layer = (postfix < _nDisks) ? _nDisks - postfix - 1 : postfix - _nDisks ;
+    Translation3D translation = new Translation3D(0.,0.,_z[postfix]);
+    IRefFrame rf;
+    if (layer % 2 == 0) {
+      rf = new RefFrameCartesian(new Transform3D(translation), null,
+              ConstHep3Vector.V100, ConstHep3Vector.V010, ConstHep3Vector.V001);
+    } else {
+      rf = new RefFrameCartesian(new Transform3D(translation, _rot1), null, _u1, _v1, ConstHep3Vector.V001);
+      }
+    return new Sensor(_detElts.get(postfix), postfixToID(postfix), type, rf);
+  }
+  
+// -- Private parts :  ---------------------------------------------------------
+  
+  String _sdName;
+  private List<IDetectorElement> _detElts;
+  
+  private int _nDisks;
+  private int _nLayers;
+  private double[] _radiusInner;
+  private double[] _radiusOuter;
+  private double[] _thickness;
+  private double[] _z;
+  private double _stripLength;
+  private double _stripWidth;
+  
+  private IRotation3D _rot1;
+  private ConstHep3Vector _u1, _v1;
+}

lcsim/src/org/lcsim/contrib/onoprien/vsegment/geom/segmenter
DiskTrackerToWedgesSegmenter.java added at 1.1
diff -N DiskTrackerToWedgesSegmenter.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ DiskTrackerToWedgesSegmenter.java	3 Sep 2008 16:02:51 -0000	1.1
@@ -0,0 +1,155 @@
+package org.lcsim.contrib.onoprien.vsegment.geom.segmenter;
+
+import java.util.*;
+
+import org.lcsim.detector.IDetectorElement;
+import org.lcsim.detector.IGeometryInfo;
+import org.lcsim.detector.IPhysicalVolume;
+import org.lcsim.detector.solids.Tube;
+
+import org.lcsim.contrib.onoprien.vsegment.geom.AbstractSegmenter;
+
+/**
+ *
+ *
+ * @author D. Onoprienko
+ * @version $Id: DiskTrackerToWedgesSegmenter.java,v 1.1 2008/09/03 16:02:51 onoprien Exp $
+ */
+public class DiskTrackerToWedgesSegmenter extends DiskTrackerSegmenter {
+  
+// -- Constructors :  ----------------------------------------------------------
+  
+  public DiskTrackerToWedgesSegmenter(String subdetectorName) {
+    super(subdetectorName);
+  }
+  
+// -- Implementing DiskTrackerSegmenter :  -------------------------------------
+  
+  /**
+   * Return <tt>Segmenter</tt> that handles hits in the given <tt>DetectorElement</tt>.
+   */
+  public AbstractSegmenter assignSegmenter(IDetectorElement de) {
+    
+    checkGeometry();
+    
+    int nRadialSlices;
+    if (_radialSlicesBySuperlayer == null) {
+      IGeometryInfo gInfo = de.getGeometry();
+      Tube solid = (Tube) gInfo.getLogicalVolume().getSolid();
+      double radiusInner = solid.getInnerRadius();
+      double radiusOuter = solid.getOuterRadius();
+      nRadialSlices = (int)Math.round((radiusOuter - radiusInner)/_stripLength);
+    } else {
+      nRadialSlices = _radialSlicesBySuperlayer[getSuperlayer(de)];
+    }
+    
+    int nPhiSlices;
+    if (_phiSlicesBySuperlayer == null) {
+      nPhiSlices = _phiSlices;
+    } else {
+      nPhiSlices = _phiSlicesBySuperlayer[getSuperlayer(de)];
+    }
+   
+    double pitch;
+    if (_pitchBySuperlayer == null) {
+      pitch = _pitch;
+    } else {
+      pitch = _pitchBySuperlayer[getSuperlayer(de)];
+    }
+    
+    boolean left = isInner(de);
+    
+    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 :  ---------------------------------------------------------------
+  
+  /**
+   * Set strip length.
+   * The actual strip length in each disk will be adjusted to create an integral
+   * number of radial slices.
+   */
+  public void setStripLength(double length) {
+    _radialSlicesBySuperlayer = null;
+    _stripLength = length;
+  }
+  
+  /**
+   * Set the number of radial slices in each superlayer.
+   */
+  public void setNumberOfRadialSlices(int[] nRadialSlices) {
+    //_radialSlicesBySuperlayer = Arrays.copyOf(nRadialSlices, nRadialSlices.length); // Need JDK 1.6
+    _radialSlicesBySuperlayer = nRadialSlices;
+  }
+  
+  /**
+   * Set the number of axial slices in all superlayers.
+   */
+  public void setNumberOfPhiSlices(int nPhiSlices) {
+    _phiSlicesBySuperlayer = null;
+    _phiSlices = nPhiSlices;
+  }
+  
+  /**
+   * Set the number of axial slices in each superlayer.
+   */
+  public void setNumberOfPhiSlices(int[] nPhiSlices) {
+    //_phiSlicesBySuperlayer = Arrays.copyOf(nPhiSlices, nPhiSlices.length); // Need JDK 1.6
+    _phiSlicesBySuperlayer = nPhiSlices;
+  }
+  
+  /**
+   * Set the strip width in all superlayers.
+   */
+  public void setStripWidth(double pitch) {
+    _pitchBySuperlayer = null;
+    _pitch = pitch;
+  }
+  
+  /**
+   * Set the strip width in each superlayer.
+   */
+  public void setStripWidth(double[] pitch) {
+    //_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 :  ---------------------------------------------------------
+  
+  double _stripLength;
+  int[] _radialSlicesBySuperlayer;
+
+  int _phiSlices;
+  int[] _phiSlicesBySuperlayer;
+  
+  double _pitch;
+  double[] _pitchBySuperlayer;
+}

lcsim/src/org/lcsim/contrib/onoprien/vsegment/geom/segmenter
SubdetectorBasedSegmenter.java added at 1.1
diff -N SubdetectorBasedSegmenter.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ SubdetectorBasedSegmenter.java	3 Sep 2008 16:02:51 -0000	1.1
@@ -0,0 +1,80 @@
+package org.lcsim.contrib.onoprien.vsegment.geom.segmenter;
+
+import java.util.*;
+
+import org.lcsim.geometry.Detector;
+import org.lcsim.geometry.Subdetector;
+import org.lcsim.event.SimTrackerHit;
+
+import org.lcsim.contrib.onoprien.vsegment.geom.AbstractSegmenter;
+import org.lcsim.contrib.onoprien.vsegment.geom.ForwardingSegmenter;
+import org.lcsim.contrib.onoprien.vsegment.geom.SegmentationManager;
+import org.lcsim.contrib.onoprien.vsegment.geom.Sensor;
+
+/**
+ * <tt>Segmenter</tt> that forwards <tt>postfix</tt> and {@link Sensor} creation calls 
+ * to daughter Segmenters based on subdetector where the hit occured.
+ * 
+ * 
+ * @author D.Onoprienko
+ * @version $Id: SubdetectorBasedSegmenter.java,v 1.1 2008/09/03 16:02:51 onoprien Exp $
+ */
+public class SubdetectorBasedSegmenter extends ForwardingSegmenter {
+  
+// -- Constructors and initialization :  ---------------------------------------
+  
+  /** Create an instance of <tt>SubdetectorBasedSegmenter</tt>. */
+  public SubdetectorBasedSegmenter() {
+    _subdetectorNames = new ArrayList<String>();
+    _segmenters = new ArrayList<AbstractSegmenter>();
+  }
+  
+  /** 
+   * Detector dependent initialization.
+   */
+  public void detectorChanged(Detector detector) {
+    _subdetectorNames.trimToSize();
+    _segmenters.trimToSize();
+    _sdToSegmenter = new HashMap<Subdetector, AbstractSegmenter>();
+    removeAllDaughterSegmenters();
+    for (int i=0; i<_segmenters.size(); i++) {
+      String name = _subdetectorNames.get(i);
+      Subdetector subDet = detector.getSubdetector(name);
+      if (subDet != null) {
+        AbstractSegmenter segmenter = _segmenters.get(i);
+        _sdToSegmenter.put(subDet, segmenter);
+        addDaughterSegmenter(segmenter);
+      }
+    }
+    super.detectorChanged(detector);
+    //updateDaughterSegmenters(detector);
+  }
+  
+// -- Setters :  ---------------------------------------------------------------
+
+  /** 
+   * Set segmenter that will handle a particular subdetector.
+   *
+   * @param subdetectorName  Name of the subdetector to be handled by the supplied <tt>Segmenter</tt>
+   * @param segmenter        <tt>Segmenter</tt> to be used
+   */
+  public void setSegmenter(String subdetectorName, AbstractSegmenter segmenter) {
+    _subdetectorNames.add(subdetectorName);
+    _segmenters.add(segmenter);
+  }
+  
+// -- Choosing Segmenter :  ----------------------------------------------------
+  
+  /**
+   * Returns daughter <tt>Segmenter</tt> that can handle the given hit.
+   */
+  public AbstractSegmenter chooseSegmenter(SimTrackerHit hit) {
+    return _sdToSegmenter.get(hit.getSubdetector());
+  }
+  
+// -- Private parts :  ---------------------------------------------------------
+  
+  private ArrayList<String> _subdetectorNames;
+  private ArrayList<AbstractSegmenter> _segmenters;
+  private HashMap<Subdetector, AbstractSegmenter> _sdToSegmenter;
+}
CVSspam 0.2.8