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 }