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 }