View Javadoc

1   package org.lcsim.recon.tracking.vsegment.geom.sensortypes;
2   
3   import java.util.ArrayList;
4   import java.util.List;
5   
6   import hep.physics.vec.BasicHep3Vector;
7   import hep.physics.vec.Hep3Vector;
8   
9   import org.lcsim.recon.tracking.vsegment.geom.SensorType;
10  
11  /**
12   * This class represents a cylindrical sensor with strips parallel to its axis.
13   * The reference frame is cylindrical (U,V,W = Phi,Z,R), with the position of origin 
14   * controled by <tt>Hep3Vector center</tt> parameter given to a constructor.
15   * If <tt>center = (Phi0,Z0,R0)</tt>, then the sensor volume of the cylinder will be defined by 
16   * <tt><nobr>Phi0-PI < u < Phi0+PI ,</nobr> 
17   * <nobr>Z0-length < v < Z0+length ,</nobr> 
18   * <nobr>R0-thickness/2 < w < R0+thickness/2</nobr></tt>. 
19   * Constructors that do not require <tt>center</tt> parameter assume
20   * <nobr><tt>center = (0.,0.,radius)</tt></nobr>,
21   * placing the local reference frame origin in the center of the detector with 
22   * <tt>phi</tt> ranging from <tt>-PI</tt> to <tt>PI</tt>.
23   *
24   * @author D.Onoprienko
25   * @version $Id: Cylinder.java,v 1.1 2008/12/06 21:53:44 onoprien Exp $
26   */
27  public class Cylinder extends Rectangle {
28    
29  // -- Constructors :  ----------------------------------------------------------
30    
31    /**
32     * Create <tt>Cylinder</tt> instance.
33     * The <tt>center</tt> parameter controls offsets in the local reference frame.
34     *
35     * @param length      Length of the cylinder (along strip direction).
36     * @param radius      Radius of the cylinder.
37     * @param thickness   Thickness of the sensor.
38     * @param nLength     Number of divisions along the cylinder length.
39     * @param nPhi        Number of divisions in phi.
40     * @param center      Controls definition of the local reference frame
41     */
42    public Cylinder(double radius, double length, double thickness, int nPhi, int nLength, Hep3Vector center) {
43      super(TWOPI, length, thickness, nPhi, nLength, center);
44      _hitDim = ((length/nLength)/(TWOPI*radius/nPhi) < 4.) ? 2 : 1;
45    }
46    
47    /**
48     * Create <tt>Cylinder</tt> instance.
49     *
50     * @param length      Length of the cylinder (along strip direction).
51     * @param radius      Radius of the cylinder.
52     * @param thickness   Thickness of the sensor.
53     * @param nLength     Number of divisions along the cylinder length.
54     * @param nPhi        Number of divisions in phi.
55     */
56    public Cylinder(double radius, double length, double thickness, int nPhi, int nLength) {
57      this(radius, length, thickness, nPhi, nLength, new BasicHep3Vector(0.,0.,radius));
58    }
59    
60    /**
61     * Create <tt>Cylinder</tt> instance.
62     * Strip width will be adjusted to make sure integral number of strips fits the 
63     * circumference of the cylinder.
64     *
65     * @param length       Length of the cylinder (along strip direction).
66     * @param radius       Radius of the cylinder.
67     * @param thickness    Thickness of the sensor.
68     * @param stripPitch   Strip width.
69     * @param stripLength  Strip length.
70     * @param center       Controls definition of the local reference frame
71     */
72    public Cylinder(double radius, double length, double thickness, double stripPitch, double stripLength, Hep3Vector center) {
73      this(radius, length, thickness, (int) Math.round((TWOPI*radius)/stripPitch), (int) Math.round(length/stripLength), center);
74    }
75    
76    /**
77     * Create <tt>Cylinder</tt> instance.
78     * Strip width will be adjusted to make sure integral number of strips fits the 
79     * circumference of the cylinder.
80     *
81     * @param length       Length of the cylinder (along strip direction).
82     * @param radius       Radius of the cylinder.
83     * @param thickness    Thickness of the sensor.
84     * @param stripPitch   Strip width.
85     * @param stripLength  Strip length.
86     */
87    public Cylinder(double radius, double length, double thickness, double stripPitch, double stripLength) {
88      this(radius, length, thickness, stripPitch, stripLength, new BasicHep3Vector(0.,0.,radius));
89    }
90  
91  // -----------------------------------------------------------------------------
92  
93    /**
94     * Converts a point in local sensor coordinates to channel ID.
95     * Returns -1 if the point is outside of sensor sensitive area.
96     */
97    public int getChannelID(Hep3Vector point) {
98      
99      if (Math.abs(point.z()-_wCenter) > _thick/2.) return -1;
100 
101     double u = point.x();
102     double v = point.y();
103 
104     int nV = (int) Math.floor((v-_vLow)/_length);
105     if ((nV < 0) || (nV >= _nDivV)) return -1;
106 
107     int nU = (int) Math.floor((u-_uLow)/_pitch); 
108     while (nU < 0) nU += _nDivU;
109     while (nU >= _nDivU) nU -= _nDivU;
110 
111     return nV*_nDivU + nU;
112   }
113   
114   /**
115    * Returns channel ID of a neighbor channel.
116    * Returns -1 if the channel defined by shifts does not exist on this sensor.
117    *
118    * @param channelID  ID of the original channel
119    * @param shiftV     move in <tt>V</tt> direction by <tt>shiftV</tt> channels
120    * @param shiftU     move in <tt>U</tt> direction by <tt>shiftU</tt> channels
121    */
122   public int getNeighbor(int channelID, int shiftU, int shiftV) {
123     int nV = (channelID / _nDivU) + shiftV;
124     if (nV < 0 || nV >= _nDivV) return -1;
125     int nU = (channelID % _nDivU) + shiftU;
126     while (nU < 0) nU += _nDivU;
127     while (nU >= _nDivU) nU -= _nDivU;
128     return nV*_nDivU + nU;
129   }
130   
131   /** 
132    * Returns array of IDs of all immediate neighbor channels. 
133    * For strips ({@link #getHitDimension()} returns 1), this method looks for neighbors
134    * in U direction only. Therefore, each strip has 1 or 2 neighbors. For pixels
135    * ({@link #getHitDimension()} returns 2), up to 8 neighbors can be found.
136    */
137   public List<Integer> getNeighbors(int channelID) {
138     int nU = channelID % _nDivU;
139     int nV = channelID / _nDivU;
140     ArrayList<Integer> out = new ArrayList<Integer>(8);
141     int vDown = ((_hitDim == 2) && (nV > 0)) ? nV-1 : nV;
142     int vUp = ((_hitDim == 2) && (nV < _nDivV-1)) ? nV+1 : nV;
143     for (int iV = vDown; iV < vUp; iV++) {
144       for (int iU = nU-1; iU < nU+1; iU++) {
145         while (nU < 0) nU += _nDivU;
146         while (nU >= _nDivU) nU -= _nDivU;
147         out.add(nV*_nDivU + nU);
148       }
149     }
150     return out;
151   }
152 
153 // -- Private parts :  ---------------------------------------------------------
154   
155   static final double TWOPI = 2.*Math.PI;
156 }