View Javadoc

1   package org.lcsim.recon.tracking.vsegment.geom;
2   
3   import java.util.*;
4   
5   import org.lcsim.detector.IDetectorElement;
6   import org.lcsim.detector.IGeometryInfo;
7   import org.lcsim.detector.IPhysicalVolume;
8   
9   /**
10   * Base class for {@link ForwardingSegmenter}s and {@link RegionSegmenter}s that 
11   * can be chained together to describe virtual segmentation of the entire detector.
12   * <p>
13   * A <tt>ForwardingSegmenter</tt> can have any number of daughter segmenters, each 
14   * handling a particular part of the detector. Each daughter is either another 
15   * <tt>ForwardingSegmenter</tt>, or a <tt>RegionSegmenter</tt> that does the actual
16   * {@link Sensor} object creation, and assigns an integer ID (<tt>postfix</tt>) to
17   * each <tt>Sensor</tt> within the region it is responsible for. The result is a tree
18   * of segmenters, with <tt>ForwardingSegmenter</tt>s at its top and intermediate nodes,
19   * and <tt>RegionSegmenter</tt>s as its leaves. {@link SegmentationManager} automatically
20   * assigns prefixes to all <tt>RegionSegmenter</tt>s, making sure that <tt>SensorID</tt>
21   * they assign to <tt>Sensors</tt> are unique within the whole detector. 
22   * <p>
23   * See {@link org.lcsim.contrib.onoprien.tracking.ExampleDriver1} for an example of 
24   * chaining several different segmenters.
25   *
26   * @author D. Onoprienko
27   * @version $Id: AbstractSegmenter.java,v 1.1 2008/12/06 21:53:43 onoprien Exp $
28   */
29  abstract public class AbstractSegmenter implements Segmenter {
30    
31  // -- Constructors :  ----------------------------------------------------------
32    
33    AbstractSegmenter() {
34    }
35  // -- Handling of prefixes and postfixes :  ------------------------------------
36    
37    /** 
38     * Set <tt>prefix</tt> for this <tt>Segmenter</tt>.
39     * The number of bits reserved for <tt>postfix</tt> will be calculated automatically.
40     * For the top level <tt>Segmenter</tt>, this method will be called by
41     * <tt>SegmentationManager</tt> with <tt>prefix</tt> equal to zero.
42     */
43    void setPrefix(int prefix) {
44      setPrefix(prefix, getNativePostfixLength());
45    }
46    
47    /**
48     * Set <tt>pretfix</tt> value and <tt>postfix</tt> length for this <tt>Segmenter</tt>.
49     */
50    void setPrefix(int prefix, int postfixLength) {
51      _prefix = prefix;
52      _postfixLength = postfixLength;
53      _postfixMask = 0;
54      for (int i=0; i<postfixLength; i++) _postfixMask = (_postfixMask << 1) | 1;
55      _prefixTemplate = prefix << _postfixLength;
56    }
57    
58    
59    /**
60     * Returns minimum number of bits required to hold any postfix that can be used
61     * by this <tt>Segmenter</tt>.
62     */
63    abstract protected int getNativePostfixLength();
64    
65    /**
66     * Get <tt>prefix</tt> used by this <tt>OldSegmenter</tt>.
67     */
68    final protected int getPrefix() {
69      return _prefix;
70    }
71    
72    /** Convert <tt>postfix</tt> to full <tt>SensorID</tt>. */
73    final protected int postfixToID(int postfix) {
74      return (postfix == -1) ? -1 : (_prefixTemplate | postfix);
75    }
76  
77    /** Extract <tt>postfix</tt> from full <tt>SensorID</tt>. */
78    final protected int idToPostfix(int sensorID) {
79      return sensorID & _postfixMask;
80    }
81    
82  // -- Static utility methods :  ------------------------------------------------
83    
84    /**
85     * Returns the number of bits required to hold an integer between <tt>0</tt> and <tt>maxID</tt>.
86     */
87    static int getIdSize(int maxID) {
88      return (int) Math.ceil(Math.log(maxID+0.8)/Math.log(2.));
89    }
90    
91    /**
92     * Returns a list of sensitive lowest-level decendents of the diven detector element.
93     * FIXME: This should be a DetectorElement method !
94     */
95    static public List<IDetectorElement> getLeaves(IDetectorElement del) {
96      ArrayList<IDetectorElement> out = new ArrayList<IDetectorElement>();
97      if (del.hasChildren()) {
98        for (IDetectorElement child : del.getChildren()) {
99          out.addAll(getLeaves(child));
100       }
101     } else {
102       IGeometryInfo gInfo = del.getGeometry();
103       if (gInfo != null) {
104         IPhysicalVolume pVol = gInfo.getPhysicalVolume();
105         if (pVol != null) out.add(del);
106 //        if (pVol != null && pVol.isSensitive()) out.add(del); Returns false for every volume - why ?
107       }
108     }
109     return out;
110   }
111   
112 // -- Private parts :  ---------------------------------------------------------
113 
114   protected int _prefix;
115   protected int _postfixLength;
116   protected int _postfixMask;
117   protected int _prefixTemplate;
118   
119 }