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 org.lcsim.event.SimTrackerHit;
7   import org.lcsim.geometry.Detector;
8   import org.lcsim.geometry.Subdetector;
9   import org.lcsim.detector.IDetectorElement;
10  import org.lcsim.detector.IGeometryInfo;
11  import org.lcsim.detector.ILogicalVolume;
12  import org.lcsim.detector.IPhysicalVolume;
13  import org.lcsim.detector.solids.Tube;
14  import org.lcsim.units.clhep.SystemOfUnits;
15  
16  import org.lcsim.recon.tracking.vsegment.geom.AbstractSegmenter;
17  import org.lcsim.recon.tracking.vsegment.geom.RegionSegmenter;
18  import org.lcsim.recon.tracking.vsegment.geom.Sensor;
19  import org.lcsim.recon.tracking.vsegment.geom.SensorType;
20  import org.lcsim.recon.tracking.vsegment.geom.sensortypes.Cylinder;
21  import org.lcsim.recon.tracking.vsegment.transform.CartesianToCylindrical;
22  
23  /**
24   * Simplistic <tt>Segmenter</tt> that tiles barrel cylinders with Z-parallel strips or pixels.
25   * <p>
26   * Each barrel layer will correspond to a single {@link Sensor} object, with the
27   * <tt>postfix</tt> equal to layer number.
28   * 
29   * 
30   * @author D.Onoprienko
31   * @version $Id: CylindricalBarrelSegmenter.java,v 1.1 2008/12/06 21:53:43 onoprien Exp $
32   */
33  public class CylindricalBarrelSegmenter extends RegionSegmenter {
34    
35  // -- Constructors and initialization :  ---------------------------------------
36  
37    /**
38     * Creates a new instance of CylindricalBarrelSegmenter.
39     * Subdetector name supplied to the constructor is used to provide reasonable 
40     * defaults for strip width and length.
41     */
42    public CylindricalBarrelSegmenter(String subdetectorName) {
43      _sdName = subdetectorName;
44      if (_sdName == "TrackerBarrel") {
45        _stripWidth = 25. * SystemOfUnits.micrometer;
46        _stripLength = 10. * SystemOfUnits.cm;
47      } else if (_sdName == "VertexBarrel") {
48        _stripWidth = 25. * SystemOfUnits.micrometer;
49        _stripLength = 25. * SystemOfUnits.micrometer;
50      }
51    }
52    
53    /** 
54     * Detector-dependent initialization.
55     */
56    public void detectorChanged(Detector detector) {
57      super.detectorChanged(detector);
58      Subdetector sub = detector.getSubdetector(_sdName);
59      if (sub == null) return;
60      _detElts = AbstractSegmenter.getLeaves(sub.getDetectorElement());
61      for (IDetectorElement de : _detElts) {
62        if (!(de.getGeometry().getLogicalVolume().getSolid() instanceof Tube)) {
63          throw new RuntimeException("You are trying to apply CylindricalBarrelSegmenter to detector whose barrel is not made of Tubes");
64        }
65      }
66      Collections.sort(_detElts, new Comparator<IDetectorElement>() {
67        public int compare(IDetectorElement s1, IDetectorElement s2) {
68          return (int)Math.signum(((Tube)(s1.getGeometry().getLogicalVolume().getSolid())).getInnerRadius()
69                                - ((Tube)(s2.getGeometry().getLogicalVolume().getSolid())).getInnerRadius());
70        }
71      });
72      _nLayers = _detElts.size();
73      _radius = new double[_nLayers];
74      _length = new double[_nLayers];
75      _thickness = new double[_nLayers];
76      int postfix = 0;
77      for (IDetectorElement del : _detElts) {
78        IGeometryInfo gInfo = del.getGeometry();
79        Tube solid = (Tube) gInfo.getLogicalVolume().getSolid();
80        double rInner = solid.getInnerRadius();
81        double rOuter = solid.getOuterRadius();
82        _radius[postfix] = (rInner + rOuter)/2.;
83        _length[postfix] = solid.getZHalfLength()*2.;
84        _thickness[postfix] = (rOuter - rInner);
85        postfix++;
86      }
87    }
88    
89  // -- Setters :  ---------------------------------------------------------------
90  
91    /** Set strip width. Default is 5 micron. */
92    public void setStripWidth(double pitch) {
93      _stripWidth = pitch;
94    }
95    
96    /** Set strip length. Default is 10 cm. */
97    public void setStripLength(double length) {
98      _stripLength = length;
99    }
100 // -----------------------------------------------------------------------------
101 
102   /**
103    * Returns sensor ID postfix corresponding to the given position. This postfix must 
104    * be positive  integer, unique within the part of the detector handled by this 
105    * <tt>Segmenter</tt>  object. The final Sensor ID will be constructed taking into
106    * account the prefix set through a call to {@link #setPrefix} method.
107    */
108   public int makePostfix(SimTrackerHit hit) {
109     return hit.getLayer();
110   }
111   
112   /**
113    * Returns maximum postfix value that can be returned by
114    * {@link #makePostfix(SimTrackerHit)} method of this <tt>Segmenter</tt>.
115    */
116   public int getMaxPostfix() {
117     return _nLayers-1;
118   }
119 
120   /** Creates a {@link Sensor} object given the ID. */
121   public Sensor makeSensor(int postfix) {
122     SensorType type = new Cylinder(_radius[postfix], _length[postfix], _thickness[postfix], _stripWidth, _stripLength);
123     return new Sensor(_detElts.get(postfix), postfixToID(postfix), type, _trans, _rot);
124   }
125   
126   /**
127    * Returnes <tt>null</tt> since there is no stereo in cylindrical barel.
128    */
129   public List<Integer> getStereoPartners(int sensorID) {
130     return null;
131   }
132   
133 // -- Private parts :  ---------------------------------------------------------
134   
135   String _sdName;
136   
137   List<IDetectorElement> _detElts;
138   
139   private int _nLayers;
140   private double[] _radius;
141   private double[] _length;
142   private double[] _thickness;
143   private double _stripLength;
144   private double _stripWidth;
145   
146   private CartesianToCylindrical _rot = new CartesianToCylindrical();
147   private BasicHep3Vector _trans = new BasicHep3Vector();
148 
149 }