View Javadoc

1   package org.lcsim.recon.tracking.vsegment.geom;
2   import org.lcsim.conditions.ConditionsManager;
3   
4   import java.util.*;
5   
6   import org.lcsim.event.SimTrackerHit;
7   import org.lcsim.geometry.Detector;
8   
9   /**
10   * Base class for implementing {@link Segmenter}s that forward ID or {@link Sensor}
11   * creation calls to their daughter segmenters. See {@link AbstractSegmenter} for
12   * details on how to chain segmenters.
13   * <p>
14   * Subclasses should implement {@link #chooseSegmenter(SimTrackerHit)} method to select
15   * a daughter segmenter that will handle a particular simulated hit. Daughter segmenters
16   * should be added to the parent segmenter through calls to 
17   * {@link #addDaughterSegmenter(AbstractSegmenter)}.
18   *
19   * @author D. Onoprienko
20   * @version $Id: ForwardingSegmenter.java,v 1.1 2008/12/06 21:53:43 onoprien Exp $
21   */
22  abstract public class ForwardingSegmenter extends AbstractSegmenter {
23    
24  // -- Constructors :  ----------------------------------------------------------
25    
26    /** Default constructor. */
27    protected ForwardingSegmenter() {
28      _daughters = new ArrayList<AbstractSegmenter>();
29    }
30    
31  // -- Choosing daughter segmenter :  -------------------------------------------
32    
33    /**
34     * Subclasses should implement this method to choose daughter <tt>Segmenter</tt>
35     * that can handle the given hit.
36     */
37    abstract public AbstractSegmenter chooseSegmenter(SimTrackerHit hit);
38    
39  // -- Implementing Segmenter :  ------------------------------------------------
40    
41    /**
42     * Returns a list of <tt>SensorsID</tt> corresponding to all virtual segments
43     * in the part of the detector handled by this <tt>Segmenter</tt>.
44     */
45    public List<Integer> getSensorIDs() {
46      List<Integer> sensorIDs = null;
47      for (AbstractSegmenter daughter : _daughters) {
48        if (sensorIDs == null) {
49          sensorIDs = daughter.getSensorIDs();
50        } else {
51          sensorIDs.addAll(daughter.getSensorIDs());
52        }
53      }
54      //System.out.println("Segmenter "+this+" returning "+sensorIDs.size()+" IDs");
55      return sensorIDs;
56    }
57  
58    /**
59     * Returns integer <tt>SensorID</tt> uniquely identifying a {@link Sensor} object
60     * within the whole detector, given the simulated hit.
61     */
62    public int getSensorID(SimTrackerHit hit) {
63      AbstractSegmenter daughter = chooseSegmenter(hit);
64      return (daughter == null) ? null : daughter.getSensorID(hit);
65    }
66    
67    /**
68     * Creates a new {@link Sensor} object given full <tt>SensorID</tt>.
69     * Caution: for the sake of speed, no checking is done to veryfy that the 
70     * supplied <tt>SensorID</tt> is valid and should be handled by this <tt>Segmenter</tt>.
71     * Giving this method an invalid <tt>SensorID</tt> may produce unpredictable results.
72     */
73    public Sensor getSensor(int sensorID) {
74      return _daughters.get(idToDaughterIndex(sensorID)).getSensor(sensorID);
75    }
76    
77    /**
78     * Returns a list of <tt>Sensors</tt> that might contain hits that should be combined
79     * with hits in the <tt>Sensor</tt> whose <tt>sensorID</tt> is supplied as an argument
80     * to form stereo pairs. 
81     * Default implementation forwards the call to the appropriate daughter segmenter. 
82     * Subclasses may override.
83     */
84    public List<Integer> getStereoPartners(int sensorID) {
85      return _daughters.get(idToDaughterIndex(sensorID)).getStereoPartners(sensorID);
86    }
87    
88  // -- Initialization :  --------------------------------------------------------
89    
90    /**
91     * Detector dependent initialization.
92     * Subclasses should override this method if they need to perform any detector
93     * dependent initialization, but they should call {@link #updateDaughterSegmenters(Detector)}
94     * from this method to have their daughter <tt>Segmenter</tt>s initialized as well.
95     */
96    public void detectorChanged(Detector detector) {
97  //    System.out.println(" ");
98  //    System.out.println("Updating " + this + " with " + detector.getName());
99      updateDaughterSegmenters(detector);
100   }
101   
102   /** 
103    * Calls {@link #detectorChanged(Detector)} methods of daughter <tt>Segmenter</tt>s.
104    * If subclasses override {@link #detectorChanged(Detector)} method, they should
105    * call this method to have daughter <tt>Segmenter</tt>s initialized.
106    */
107   protected void updateDaughterSegmenters(Detector detector) {
108     for (AbstractSegmenter daughter : _daughters) daughter.detectorChanged(detector);
109   }
110   
111 // -- Handling of prefixes and postfixes :  ------------------------------------
112   
113   /**
114    * Set <tt>pretfix</tt> value and <tt>postfix</tt> length for this <tt>Segmenter</tt>.
115    */
116   public void setPrefix(int prefix, int postfixLength) {
117     //System.out.println("Setting prefix for "+this+" prefix "+prefix+" length "+postfixLength);
118     super.setPrefix(prefix, postfixLength);
119     _daughters.trimToSize();
120     int daughterIdLdength = getIdSize(_daughters.size()-1);
121     _daughterPostfixLength = postfixLength - daughterIdLdength;
122     _daughterIdMask = 0;
123     for (int i=0; i<daughterIdLdength; i++) _daughterIdMask = (_daughterIdMask << 1) | 1;
124     _daughterIdMask = _daughterIdMask << _daughterPostfixLength;
125     for (int daughterIndex=0; daughterIndex < _daughters.size(); daughterIndex++) {
126       _daughters.get(daughterIndex).setPrefix((prefix << daughterIdLdength) | daughterIndex , _daughterPostfixLength);
127     }
128   }
129   
130   /**
131    * Extract daughter <tt>Segmenter</tt> index from full <tt>SensorID</tt>.
132    */
133   protected int idToDaughterIndex(int sensorID) {
134     return (_daughterIdMask & sensorID) >> _daughterPostfixLength;
135   }
136   
137   /**
138    * Returns minimum <tt>postfix</tt> length required by this <tt>Segmenter</tt>
139    * to accomodate all its daughters and their <tt>postfix</tt>es.
140    */
141   protected int getNativePostfixLength() {
142     int daughterIdLdength = getIdSize(_daughters.size()-1);
143     int maxDaughterPostfixLength = 0;
144     for (AbstractSegmenter daughter : _daughters) {
145       maxDaughterPostfixLength = Math.max(daughter.getNativePostfixLength(), maxDaughterPostfixLength);
146     }
147     return daughterIdLdength + maxDaughterPostfixLength;
148   }
149   
150 // -- Adding / Removing daughters :  -------------------------------------------
151 
152   /** Add daughter <tt>Segmenter</tt>. */
153   public void addDaughterSegmenter(AbstractSegmenter daughter) {
154     _daughters.add(daughter);
155   }
156   
157   /** Remove daughter <tt>Segmenter</tt>. */
158   public void removeDaughterSegmenter(AbstractSegmenter daughter) {
159     _daughters.remove(daughter);
160   }
161   
162   /** Remove all daughter <tt>Segmenter</tt>s. */
163   public void removeAllDaughterSegmenters() {
164     _daughters.clear();
165   }
166 
167 // -- Private parts :  ---------------------------------------------------------
168 
169   private ArrayList<AbstractSegmenter> _daughters;
170   
171   protected int _daughterPostfixLength;
172   protected int _daughterIdMask;
173 
174 }