View Javadoc

1   package org.lcsim.recon.tracking.vsegment.geom.segmenters;
2   
3   import hep.physics.vec.BasicHep3Vector;
4   import hep.physics.vec.Hep3Vector;
5   import org.lcsim.detector.IDetectorElement;
6   import org.lcsim.detector.IGeometryInfo;
7   import org.lcsim.detector.ILogicalVolume;
8   import org.lcsim.detector.IPhysicalVolume;
9   import org.lcsim.detector.solids.Tube;
10  import org.lcsim.event.SimTrackerHit;
11  
12  import org.lcsim.recon.tracking.vsegment.geom.RegionSegmenter;
13  import org.lcsim.recon.tracking.vsegment.geom.Sensor;
14  import org.lcsim.recon.tracking.vsegment.geom.SensorType;
15  import org.lcsim.recon.tracking.vsegment.geom.sensortypes.WedgeSideParallel;
16  import org.lcsim.recon.tracking.vsegment.transform.Axis;
17  import org.lcsim.recon.tracking.vsegment.transform.Rotation3D;
18  import org.lcsim.recon.tracking.vsegment.transform.Transformation3D;
19  
20  /**
21   * Simplistic <tt>Segmenter</tt> that tiles a single disk with wedges.
22   * 
23   * @author D. Onoprienko
24   * @version $Id: DiskToWedgesSegmenter.java,v 1.1 2008/12/06 21:53:43 onoprien Exp $
25   */
26  public class DiskToWedgesSegmenter extends RegionSegmenter {
27    
28  // -- Constructors :  ----------------------------------------------------------
29    
30    public DiskToWedgesSegmenter(IDetectorElement disk, int nRadialSlices, int nPhiSlices, double pitch, boolean left) {
31      
32      _de = disk;
33      _left = left;
34      _pitch = pitch;
35      _nPhi = nPhiSlices;
36      _nRadial = nRadialSlices;
37      
38      IGeometryInfo gInfo = _de.getGeometry();
39      Tube solid = (Tube) gInfo.getLogicalVolume().getSolid();
40      _rMiddleMin = solid.getInnerRadius();
41      double rMax = solid.getOuterRadius();
42      double halfThickness = solid.getZHalfLength();
43  
44      _z = gInfo.getPosition().z();
45      _zMin = _z - halfThickness;
46      _zMax = _z + halfThickness;
47      
48      _deltaPhi = (2.*Math.PI)/nPhiSlices;
49      _rMin = _rMiddleMin/Math.cos(_deltaPhi/2.);
50      _deltaR = (rMax - _rMin) / nRadialSlices;
51      _deltaRMiddle = _deltaR * Math.cos(_deltaPhi/2.);
52      
53      _sType = new SensorType[_nRadial];
54      for (int indexR=0; indexR < _nRadial; indexR++) {
55        _sType[indexR] = new WedgeSideParallel(_rMin+_deltaR*indexR, _deltaR, _deltaPhi, _pitch, _left, 2.*halfThickness);
56      }
57  
58      _rotation = new Transformation3D[_nPhi];
59      for (int indexPhi=0; indexPhi < _nPhi; indexPhi++ ) {
60        double angle = (left) ? _deltaPhi * (indexPhi + 1) - Math.PI/2. : _deltaPhi * indexPhi - Math.PI/2.;
61        _rotation[indexPhi] = new Rotation3D(Axis.Z, angle);
62      }
63    }
64  // -- Implementing RegionSegmenter :  ------------------------------------------
65  
66    /**
67     * Returns <tt>postfix</tt> corresponding to the position of the given simulated hit. 
68     */
69    protected int makePostfix(SimTrackerHit hit) {
70      
71      double[] pos = hit.getPoint();
72      
73      if (pos[2]<_zMin || pos[2]>_zMax) return -1;
74      
75      double r = Math.hypot(pos[0],pos[1]);
76      double phi = Math.atan2(pos[1], pos[0]);
77      phi = (phi > 0.) ? phi : phi + Math.PI * 2.;
78      
79      int indexPhi = (int) Math.floor(phi/_deltaPhi);
80      if (indexPhi < 0) indexPhi = 0;
81      if (indexPhi >= _nPhi) indexPhi = _nPhi -1;
82      
83      double rMiddle = r * Math.cos(phi - _deltaPhi*(indexPhi+.5));
84      int indexR = (int) Math.floor((rMiddle - _rMiddleMin) / _deltaRMiddle);
85      if ((indexR < 0) || (indexR >= _nRadial)) return -1;
86      
87      return (_nRadial * indexPhi) + indexR;
88    }
89    
90    /**
91     * Returns maximum postfix value that can be returned by
92     * {@link #makePostfix(SimTrackerHit)} method of this <tt>Segmenter</tt> object.
93     */
94    protected int getMaxPostfix() {
95      return (_nRadial * _nPhi) - 1;
96    }
97  
98    /**
99     * 
100    * Creates a new {@link Sensor} object given the <tt>postfix</tt>.
101    */
102   protected Sensor makeSensor(int postfix) {
103     int indexR = postfix % _nRadial;
104     int indexPhi = postfix / _nRadial;
105     double r = _rMin + indexR * _deltaR;
106     double phi = (indexPhi + 1) * _deltaPhi;
107     Hep3Vector translation = new BasicHep3Vector(r*Math.cos(phi), r*Math.sin(phi), _z);
108     return new Sensor(_de, postfixToID(postfix), _sType[indexR], translation, _rotation[indexPhi]);
109   }
110 
111 // -- Private parts :  ---------------------------------------------------------
112   
113   IDetectorElement _de;
114   
115   boolean _left;
116   double _pitch;
117   
118   int _nPhi;
119   int _nRadial;
120   
121   double _z;
122   double _zMin;
123   double _zMax;
124   
125   double _rMin;
126   double _rMiddleMin;
127   
128   double _deltaPhi;
129   double _deltaR;
130   double _deltaRMiddle;
131   
132   SensorType[] _sType;
133   Transformation3D[] _rotation;
134 }