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 rectangular sensor with strips parallel to its side. 13 * The reference frame origin is at the center of the sensor. 14 * 15 * @author D.Onoprienko 16 * @version $Id: Rectangle.java,v 1.1 2008/12/06 21:53:44 onoprien Exp $ 17 */ 18 public class Rectangle implements SensorType { 19 20 // -- Constructors : ---------------------------------------------------------- 21 22 /** Default constructor for use by subclusses. No initialization. */ 23 public Rectangle() {} 24 25 /** 26 * Create an instance of <tt>Rectangle</tt>. 27 * The <tt>center</tt> parameter controls how the local reference frame origin 28 * is positioned with respect to the cuboid defining the sensor volume. 29 * 30 * @param width Width of the sensor. 31 * @param length Length of the sensor (along strip direction). 32 * @param thickness Thickness of the sensor. 33 * @param nWidth Number of divisions across the sensor width. 34 * @param nLength Number of divisions along the sensor length. 35 * @param center Position of the cuboid center in the local reference frame 36 */ 37 public Rectangle(double width, double length, double thickness, 38 int nWidth, int nLength, Hep3Vector center) { 39 if (nLength == 0) nLength = 1; 40 _uLow = center.x() - width/2.; 41 _vLow = center.y() - length/2.; 42 _wCenter = center.z(); 43 _pitch = width/nWidth; 44 _length = length/nLength; 45 _thick = thickness; 46 _hitDim = (_length/_pitch < 4.) ? 2 : 1; 47 _nDivV = nLength; 48 _nDivU = nWidth; 49 // System.out.println("Rect w "+width+" len "+length+" thick "+thickness+" nW "+nWidth+" nL "+nLength+" center "+center); 50 // System.out.println(" pitch "+_pitch+" length "+_length+" thick "+_thick+" hitDim "+_hitDim); 51 } 52 53 /** 54 * Create <tt>Rectangle</tt> instance. 55 * Reference frame origin will be in the center of the cuboid defining the sensor volume. 56 * 57 * @param width Width of the sensor. 58 * @param length Length of the sensor (along strip direction). 59 * @param thickness Thickness of the sensor. 60 * @param nWidth Number of divisions across the sensor width. 61 * @param nLength Number of divisions along the sensor length. 62 */ 63 public Rectangle(double width, double length, double thickness, int nWidth, int nLength) { 64 this(width, length, thickness, nWidth, nLength, new BasicHep3Vector()); 65 } 66 67 /** 68 * Create <tt>Rectangle</tt> instance. 69 * The <tt>center</tt> parameter controls how the local reference frame origin 70 * is positioned with respect to the cuboid defining the sensor volume. 71 * Strip width will be rounded to place integral number of strips on the rectangle. 72 * 73 * @param width Width of the sensor. 74 * @param length Length of the sensor (along strip direction). 75 * @param thickness Thickness of the sensor. 76 * @param stripPitch Strip width. 77 * @param nLength Number of divisions along the sensor length. 78 * @param center Position of the cuboid center in the local reference frame 79 */ 80 public Rectangle(double width, double length, double thickness, 81 double stripPitch, int nLength, Hep3Vector center) { 82 this(width, length, thickness, (int)Math.round(width/stripPitch), nLength, center); 83 } 84 85 /** 86 * Create <tt>Rectangle</tt> instance. 87 * Reference frame origin will be in the center of the cuboid defining the sensor volume. 88 * Strip width will be rounded to place integral number of strips on the rectangle. 89 * 90 * @param width Width of the sensor. 91 * @param length Length of the sensor (along strip direction). 92 * @param thickness Thickness of the sensor. 93 * @param stripPitch Strip width. 94 * @param nLength Number of divisions along the sensor length. 95 */ 96 public Rectangle(double width, double length, double thickness, 97 double stripPitch, int nLength) { 98 this(width, length, thickness, (int)Math.round(width/stripPitch), nLength, new BasicHep3Vector()); 99 } 100 101 /** 102 * Create <tt>Rectangle</tt> instance. 103 * The <tt>center</tt> parameter controls how the local reference frame origin 104 * is positioned with respect to the cuboid defining the sensor volume. 105 * Strip length will be rounded to place integral number of strips on the rectangle. 106 * 107 * @param width Width of the sensor. 108 * @param length Length of the sensor (along strip direction). 109 * @param thickness Thickness of the sensor. 110 * @param nWidth Number of divisions across the sensor width. 111 * @param stripLength Strip length. 112 * @param center Position of the cuboid center in the local reference frame 113 */ 114 public Rectangle(double width, double length, double thickness, 115 int nWidth, double stripLength, Hep3Vector center) { 116 this(width, length, thickness, nWidth, (int)Math.round(length/stripLength), center); 117 } 118 119 /** 120 * Create <tt>Rectangle</tt> instance. 121 * Reference frame origin will be in the center of the cuboid defining the sensor volume. 122 * Strip length will be rounded to place integral number of strips on the rectangle. 123 * 124 * @param width Width of the sensor. 125 * @param length Length of the sensor (along strip direction). 126 * @param thickness Thickness of the sensor. 127 * @param nWidth Number of divisions across the sensor width. 128 * @param stripLength Strip length. 129 */ 130 public Rectangle(double width, double length, double thickness, 131 int nWidth, double stripLength) { 132 this(width, length, thickness, nWidth, (int)Math.round(length/stripLength), new BasicHep3Vector()); 133 } 134 135 /** 136 * Create <tt>Rectangle</tt> instance. 137 * The <tt>center</tt> parameter controls how the local reference frame origin 138 * is positioned with respect to the cuboid defining the sensor volume. 139 * Strip width and length will be rounded to place integral number of strips on the rectangle. 140 * 141 * @param width Width of the sensor. 142 * @param length Length of the sensor (along strip direction). 143 * @param thickness Thickness of the sensor. 144 * @param stripPitch Strip width. 145 * @param stripLength Strip length. 146 * @param center Position of the cuboid center in the local reference frame 147 */ 148 public Rectangle(double width, double length, double thickness, 149 double stripPitch, double stripLength, Hep3Vector center) { 150 this(width, length, thickness, (int)Math.round(width/stripPitch), (int)Math.round(length/stripLength), center); 151 } 152 153 /** 154 * Create <tt>Rectangle</tt> instance. 155 * Reference frame origin will be in the center of the cuboid defining the sensor volume. 156 * Strip width and length will be rounded to place integral number of strips on the rectangle. 157 * 158 * @param width Width of the sensor. 159 * @param length Length of the sensor (along strip direction). 160 * @param thickness Thickness of the sensor. 161 * @param stripPitch Strip width. 162 * @param stripLength Strip length. 163 */ 164 public Rectangle(double width, double length, double thickness, 165 double stripPitch, double stripLength) { 166 this(width, length, thickness, (int)Math.round(width/stripPitch), (int)Math.round(length/stripLength), new BasicHep3Vector()); 167 } 168 169 // -- Setters : --------------------------------------------------------------- 170 171 /** 172 * Set the dimension of a measurement by this type of sensor (1 for strips, 2 for pixels, etc). 173 */ 174 public void setHitDimension(int dim) { 175 _hitDim = dim; 176 } 177 178 // ----------------------------------------------------------------------------- 179 180 /** 181 * Converts a point in local sensor coordinates to channel ID. 182 * Returns -1 if the point is outside of sensor sensitive area. 183 */ 184 public int getChannelID(Hep3Vector point) { 185 186 if (Math.abs(point.z()-_wCenter) > _thick/2.) return -1; 187 188 double u = point.x(); 189 double v = point.y(); 190 191 int nU = (int) Math.floor((u-_uLow)/_pitch); 192 if ((nU < 0) || (nU >= _nDivU)) return -1; 193 int nV = (int) Math.floor((v-_vLow)/_length); 194 if ((nV < 0) || (nV >= _nDivV)) return -1; 195 return nV*_nDivU + nU; 196 } 197 198 /** 199 * Returns position of the center of the given channel, in local sensor coordinates. 200 */ 201 public Hep3Vector getChannelPosition(int channelID) { 202 int nU = channelID % _nDivU; 203 int nV = channelID / _nDivU; 204 double u = (nU + .5) * _pitch + _uLow; 205 double v = (nV + .5) * _length + _vLow; 206 return new BasicHep3Vector(u,v,_wCenter); 207 } 208 209 /** Returns maximum possible channel ID on this sensor. */ 210 public int getMaxChannelID() { 211 return _nDivU * _nDivV - 1; 212 } 213 214 /** Returns <tt>true</tt> if channel with this ID exists on this sensor. */ 215 public boolean isValidChannelID(int channelID) { 216 return channelID > -1 && channelID < (_nDivU * _nDivV); 217 } 218 219 /** 220 * Returns dimensions of the given channel along U, V, W. 221 */ 222 public Hep3Vector getChannelDimensions(int channelID) { 223 return new BasicHep3Vector(_pitch, _length, _thick); 224 } 225 226 /** 227 * Returns the dimension of a measurement by this type of sensor 228 * (1 for strips, 2 for pixels, etc). 229 * By default, this method returns <tt>1</tt> if strip length is at least 4 times 230 * bigger than strip pitch. Alternatively, the return value can be set explicitly 231 * through a call to {@link #setHitDimension(int)}. 232 */ 233 public int getHitDimension() { 234 return _hitDim; 235 } 236 237 /** 238 * Returns channel ID of a neighbor channel. 239 * Returns -1 if the channel defined by shifts does not exist on this sensor. 240 * 241 * @param channelID ID of the original channel 242 * @param shiftV move in <tt>V</tt> direction by <tt>shiftV</tt> channels 243 * @param shiftU move in <tt>U</tt> direction by <tt>shiftU</tt> channels 244 */ 245 public int getNeighbor(int channelID, int shiftU, int shiftV) { 246 int nU = (channelID % _nDivU) + shiftU; 247 if ((nU < 0) || (nU >= _nDivU)) return -1; 248 int nV = (channelID / _nDivU) + shiftV; 249 if ((nV < 0) || (nV >= _nDivV)) return -1; 250 return nV*_nDivU + nU; 251 } 252 253 /** Returns array of IDs of all immediate neighbor channels. */ 254 public List<Integer> getNeighbors(int channelID) { 255 int nU = channelID % _nDivU; 256 int nV = channelID / _nDivU; 257 ArrayList<Integer> out = new ArrayList<Integer>(8); 258 int vDown = ((_hitDim == 2) && (nV > 0)) ? nV-1 : nV; 259 int vUp = ((_hitDim == 2) && (nV < _nDivV-1)) ? nV+1 : nV; 260 int uDown = (nU > 0) ? nU-1 : nU; 261 int uUp = (nU < _nDivU-1) ? nU+1 : nU; 262 for (int iV = vDown; iV < vUp; iV++) { 263 for (int iU = uDown; iU < uUp; iU++) { 264 out.add(nV*_nDivU + nU); 265 } 266 } 267 return out; 268 } 269 270 // -- Private parts : --------------------------------------------------------- 271 272 protected double _uLow; 273 protected double _vLow; 274 protected double _wCenter; 275 276 protected double _pitch; 277 protected double _length; 278 protected double _thick; 279 280 protected int _hitDim; 281 282 protected int _nDivU; 283 protected int _nDivV; 284 }