View Javadoc

1   package org.lcsim.recon.tracking.vsegment.geom.segmenters;
2   
3   import java.util.*;
4   
5   import hep.physics.vec.BasicHep3Vector;
6   import hep.physics.vec.Hep3Vector;
7   import org.lcsim.event.SimTrackerHit;
8   import org.lcsim.geometry.Detector;
9   import org.lcsim.geometry.Subdetector;
10  import org.lcsim.detector.IDetectorElement;
11  import org.lcsim.detector.IGeometryInfo;
12  import org.lcsim.detector.ILogicalVolume;
13  import org.lcsim.detector.IPhysicalVolume;
14  import org.lcsim.detector.solids.Tube;
15  import org.lcsim.recon.cat.util.Const;
16  
17  import org.lcsim.recon.tracking.vsegment.geom.AbstractSegmenter;
18  import org.lcsim.recon.tracking.vsegment.geom.RegionSegmenter;
19  import org.lcsim.recon.tracking.vsegment.geom.Sensor;
20  import org.lcsim.recon.tracking.vsegment.geom.SensorType;
21  import org.lcsim.recon.tracking.vsegment.geom.sensortypes.Ring;
22  import org.lcsim.recon.tracking.vsegment.transform.Rotation3D;
23  import org.lcsim.recon.tracking.vsegment.transform.Axis;
24  
25  /**
26   * 
27   * Simplistic <tt>Segmenter</tt> that tiles endcap disks with strips or pixels.
28   * <p>
29   * Each disk will correspond to a {@link Sensor} object. Postfixes are assigned in
30   * the increasing Z order. Sensors corresponding to layers facing away from the center
31   * of the detector are rotated by an angle set through a call to 
32   * {@link #setStereoAngle(double angle)}.
33   * 
34   * @author D.Onoprienko
35   * @version $Id: DiskTrackerToRingsSegmenter.java,v 1.1 2008/12/06 21:53:43 onoprien Exp $
36   */
37  public class DiskTrackerToRingsSegmenter extends RegionSegmenter {
38    
39  // -- Constructors and initialization :  ---------------------------------------
40    
41    /**
42     * 
43     * Creates a new instance of DiskTrackerToRingsSegmenter.
44     * Subdetector name supplied to the constructor is used to provide reasonable 
45     * defaults for strip width, length, and stereo angle.
46     */
47    public DiskTrackerToRingsSegmenter(String subdetectorName) {
48      _sdName = subdetectorName;
49      if (_sdName == "TrackerEndcap") {
50        setStripWidth(25.*Const.micrometer);
51        setStripLength(10.*Const.cm);
52        setStereoAngle(Math.PI / 2.);
53      } else if (_sdName == "VertexEndcap" || _sdName == "TrackerForward") {
54        setStripWidth(25.*Const.micrometer);
55        setStripLength(25.*Const.micrometer);
56        setStereoAngle(0.);
57      }
58    }
59  
60    /** 
61     * Detector-dependent initialization.
62     */
63    public void detectorChanged(Detector detector) {
64      super.detectorChanged(detector);
65      Subdetector sub = detector.getSubdetector(_sdName);
66      if (sub == null) return;
67      _detElts = AbstractSegmenter.getLeaves(sub.getDetectorElement());
68      Collections.sort(_detElts, new Comparator<IDetectorElement>() {
69        public int compare(IDetectorElement s1, IDetectorElement s2) {
70          return (int)Math.signum(s1.getGeometry().getPosition().z()-s2.getGeometry().getPosition().z());
71        }
72      });
73      _nDisks = _detElts.size();
74      _nLayers = _nDisks/2;
75      _radiusInner = new double[_nDisks];
76      _radiusOuter = new double[_nDisks];
77      _thickness = new double[_nDisks];
78      _z = new double[_nDisks];
79      int postfix = 0;
80      for (IDetectorElement del : _detElts) {
81        IGeometryInfo gInfo = del.getGeometry();
82        Tube solid = (Tube) gInfo.getLogicalVolume().getSolid();
83        _radiusInner[postfix] = solid.getInnerRadius();
84        _radiusOuter[postfix] = solid.getOuterRadius();
85        _thickness[postfix] = solid.getZHalfLength()*2.;
86        _z[postfix] = gInfo.getPosition().z();
87        postfix++;
88      }
89    }
90    
91  // -- Setters :  ---------------------------------------------------------------
92  
93    /**
94     * Set strip width.
95     * Default is 25 micron.
96     */
97    public void setStripWidth(double pitch) {
98      _stripWidth = pitch;
99    }
100 
101   /**
102    * Set strip length. 
103    * Default is 10 cm for "TrackerEndcap", 25 micron for "VertexEndcap" and "TrackerForward".
104    */
105   public void setStripLength(double length) {
106     _stripLength = length;
107   }
108 
109   /**
110    * Set stereo angle.
111    * Default is 90 degrees for "TrackerEndcap", 0 for "VertexEndcap" and "TrackerForward".
112    */
113   public void setStereoAngle(double angle) {
114     _rot1 = new Rotation3D(Axis.Z, angle);
115   }
116 
117 // -- Implementing RegionSegmenter :  ------------------------------------------
118 
119   /**
120    * Returns sensor ID postfix corresponding to the given position.
121    */
122   public int makePostfix(SimTrackerHit hit) {
123     int layer = hit.getLayer();
124     return hit.getPoint()[2] < 0. ? _nLayers - layer - 1  : _nLayers + layer ;
125   }
126   
127   /**
128    * Returns maximum postfix value that can be returned by
129    * {@link #makePostfix(SimTrackerHit)} method of this <tt>Segmenter</tt>.
130    */
131   public int getMaxPostfix() {
132     return _nDisks - 1;
133   }
134 
135   /** Creates a {@link Sensor} object given the ID. */
136   public Sensor makeSensor(int postfix) {
137     SensorType type = new Ring(_radiusInner[postfix], _radiusOuter[postfix], _stripWidth, _stripLength, _thickness[postfix]);
138     Hep3Vector trans = new BasicHep3Vector(0.,0.,_z[postfix]);
139     int layer = (postfix < _nDisks) ? _nDisks - postfix - 1 : postfix - _nDisks ;
140     Rotation3D rot = (layer % 2 == 0) ? _rot0 : _rot1 ;
141     return new Sensor(_detElts.get(postfix), postfixToID(postfix), type, trans, rot);
142   }
143   
144 // -- Private parts :  ---------------------------------------------------------
145   
146   String _sdName;
147   private List<IDetectorElement> _detElts;
148   
149   private int _nDisks;
150   private int _nLayers;
151   private double[] _radiusInner;
152   private double[] _radiusOuter;
153   private double[] _thickness;
154   private double[] _z;
155   private double _stripLength;
156   private double _stripWidth;
157   
158   private Rotation3D _rot0 = new Rotation3D();
159   private Rotation3D _rot1;
160 
161 }