View Javadoc

1   package org.lcsim.recon.tracking.vsegment.geom;
2   
3   import java.util.*;
4   
5   import org.lcsim.event.SimTrackerHit;
6   import org.lcsim.geometry.Detector;
7   
8   /**
9    * Base class for implementing {@link Segmenter}s that describe virtual segmentation 
10   * of a certain part of the detector.
11   * <p>
12   * Within that part, each <tt>Sensor</tt> is identified by a unique integer <tt>postfix</tt>.
13   * Each <tt>RegionSegmenter</tt> can be assigned an integer <tt>prefix</tt>. After that,
14   * <tt>SensorID</tt> values returned by <tt>getSensorID(SimTrackerHit)</tt> method and assigned to
15   * <tt>Sensor</tt> objects created by this segmenter will be composed of bits
16   * containing the <tt>prefix</tt> and bits containing the <tt>postfix</tt>.
17   * <p>
18   * Objects of this class are intended to be used either as top level segmenters
19   * describing segmentation of the whole detector and provided directly to 
20   * {@link SegmentationManager} in its constructor, or as bottom level segmenters
21   * in a tree of <tt>AbstractSegmenters</tt>. In the latter case, they should be added as 
22   * daughters to <tt>ForwardingSegmenters</tt>, and their prefixes will be set automatically.
23   * See {@link AbstractSegmenter} for details on how to chain <tt>Segmenters</tt>.
24   * <p>
25   * Subclasses should implement {@link #makePostfix(SimTrackerHit)}, {@link #makeSensor(int)},
26   * {@link #getMaxPostfix()}, and {@link #isPostfixValid(int)} methods. In addition, 
27   * {@link #detectorChanged(Detector)} method can be overridden if any detector 
28   * dependent initialization is required.
29   *
30   * @author D. Onoprienko
31   * @version $Id: RegionSegmenter.java,v 1.1 2008/12/06 21:53:43 onoprien Exp $
32   */
33  abstract public class RegionSegmenter extends AbstractSegmenter {
34    
35  // -- Constructors :  ----------------------------------------------------------
36    
37    /** Default constructor. */
38    protected RegionSegmenter() {
39    }
40    
41  // -- To be implemented by subclusses :  ---------------------------------------
42    
43    /**
44     * Subclasses should implement this method to return <tt>postfix</tt> corresponding 
45     * to the position of the given simulated hit. 
46     * The <tt>postfix</tt> must be non-negative integer, unique within the part of 
47     * the detector handled by this <tt>Segmenter</tt>  object. If the hit is outside
48     * of any sensor, "-1" should be returned.
49     */
50    abstract protected int makePostfix(SimTrackerHit hit);
51  
52    /**
53     * Subclasses should implement this method to create a new {@link Sensor} object given
54     * the <tt>postfix</tt>. If the postfix is invalid, <tt>null</tt> should be returned.
55     */
56    abstract protected Sensor makeSensor(int postfix);
57    
58    /**
59     * Subclasses should implement this method to return maximum postfix value that can be
60     * returned by {@link #makePostfix(SimTrackerHit)} method of this <tt>Segmenter</tt> object.
61     */
62    abstract protected int getMaxPostfix();
63    
64    /**
65     * Subclasses should override this method to return <tt>true</tt> if the given 
66     * <tt>postfix</tt> corresponds to a valid <tt>Sensor</tt> object that can be created
67     * by this <tt>RegionSegmenter</tt>. Default implementation is provided, returning
68     * <tt>true</tt> if the value of <tt>postfix</tt> is between zero and the value
69     * returned by {@link #getMaxPostfix()}.
70     */
71    protected boolean isPostfixValid(int postfix) {
72      return postfix >= 0 && postfix <= getMaxPostfix();
73    }
74    
75  // -- Implementing Segmenter :  ------------------------------------------------
76    
77    /**
78     * Returns a collection of <tt>Sensors</tt> corresponding to all virtual segments
79     * in the part of the detector handled by this <tt>Segmenter</tt>.
80     */
81    public List<Integer> getSensorIDs() {
82      int nSensors = getMaxPostfix() + 1;
83      ArrayList<Integer> sensorIDs = new ArrayList<Integer>(nSensors);
84      for (int postfix=0; postfix < nSensors; postfix++) {
85        if (isPostfixValid(postfix)) sensorIDs.add(postfixToID(postfix));
86      }
87      //System.out.println("Segmenter "+this+" returning "+sensorIDs.size()+" IDs");
88      return sensorIDs;
89    }
90    
91    /**
92     * Returns integer <tt>SensorID</tt> uniquely identifying a {@link Sensor} object
93     * within the whole detector, given the simulated hit.
94     */
95    public int getSensorID(SimTrackerHit hit) {
96      int postfix = makePostfix(hit);
97  //    if (postfix == -1) {
98  //      System.out.println(" ");
99  //      System.out.println("From RegionSegmenter.getSensorID(hit) :");
100 //      System.out.println("Segmenter " + this + " failed to produce Sensor");
101 //      System.out.println("for hit in " + hit.getSubdetector().getName() + " layer " + hit.getLayer());
102 //      System.out.println(" ");
103 //    }
104     return (postfix == -1) ? -1 : postfixToID(postfix);
105   }
106   
107   /**
108    * Creates a new {@link Sensor} object given full <tt>SensorID</tt>.
109    * For the sake of speed, no checking is done to verify that the supplied 
110    * <tt>SensorID</tt> belongs to the part of the detector that should be handled 
111    * by this <tt>OldSegmenter</tt> - be careful.
112    */
113   public Sensor getSensor(int sensorID) {
114     return makeSensor(idToPostfix(sensorID));
115   }
116   
117   /**
118    * Creates a new {@link Sensor} object given simulated hit.
119    */
120   public Sensor getSensor(SimTrackerHit hit) {
121     int postfix = makePostfix(hit);
122     return (postfix == -1) ? null : makeSensor(postfix);
123   }
124   
125   /** 
126    * Called by the framework whenever detector geometry changes.
127    * Subclasses can override this method if they need to perform any 
128    * detector-dependent initialization.
129    */
130   public void detectorChanged(Detector detector) {
131 //    System.out.println(" ");
132 //    System.out.println("Updated " + this + " with " + detector.getName());
133 //    System.out.println("Created " + (getMaxPostfix()+1) + " sensors");
134   }
135   
136   /**
137    * Returns a list of <tt>Sensors</tt> that might contain hits that should be combined
138    * with hits in the <tt>Sensor</tt> whose <tt>sensorID</tt> is supplied as an argument
139    * to form stereo pairs.
140    * Default implementation returns an empty list. Subclasses may override.
141    */
142   public List<Integer> getStereoPartners(int sensorID) {
143     return Collections.emptyList();
144   }
145   
146 // -- Handling prefixes and postfixes :  ---------------------------------------
147   
148   /**
149    * Set <tt>pretfix</tt> value and <tt>postfix</tt> length for this <tt>Segmenter</tt>.
150    */
151   public void setPrefix(int prefix, int postfixLength) {
152 //    System.out.println("Setting prefix for "+this+" prefix "+prefix+" length "+postfixLength);
153     super.setPrefix(prefix, postfixLength);
154     if (getIdSize(prefix) + postfixLength > 32) {
155       throw new IllegalArgumentException("Combined prefix and postfix length cannot be more than 32");
156     } else if (postfixLength < getNativePostfixLength()) {
157       throw new IllegalArgumentException("Attempt to set insufficient postfix length");
158     }
159   }
160   
161   /**
162    * Returns minimum number of bits required to hold any postfix that can be returned by
163    * {@link #makePostfix(SimTrackerHit)} method of this <tt>Segmenter</tt>.
164    */
165   public int getNativePostfixLength() {
166     return getIdSize(getMaxPostfix());
167   }
168   
169 }