1 package org.lcsim.recon.tracking.trfzp; 2 // ClusFindZPlane2 3 4 import java.util.List; 5 import java.util.ArrayList; 6 import java.util.Iterator; 7 8 import org.lcsim.recon.tracking.trfutil.Assert; 9 import org.lcsim.recon.tracking.trfutil.TRFMath; 10 11 import org.lcsim.recon.tracking.trfbase.Cluster; 12 import org.lcsim.recon.tracking.trfbase.Hit; 13 import org.lcsim.recon.tracking.trfbase.Surface; 14 import org.lcsim.recon.tracking.trfbase.ETrack; 15 import org.lcsim.recon.tracking.trfbase.TrackVector; 16 import org.lcsim.recon.tracking.trfbase.TrackError; 17 18 import org.lcsim.recon.tracking.trflayer.ClusterFindManager; 19 20 /** 21 * Cluster finder for a z plane. It maintains a map of 22 * clusters of type ZPlane2 indexed by x position so 23 * the clusters near a track can be retrieved quickly. 24 *<p> 25 * A track is defined to be near a cluster if the chi-square difference 26 * between the corresponding hit measurement and prediction is less 27 * than _max_chsq_diff. 28 * 29 *@author Norman A. Graf 30 *@version 1.0 31 * 32 */ 33 34 public class ClusFindZPlane2 extends ClusterFindManager 35 { 36 37 38 // static methods 39 40 // 41 42 /** 43 *Return a String representation of the class' type name. 44 *Included for completeness with the C++ version. 45 * 46 * @return A String representation of the class' type name. 47 */ 48 public static String typeName() 49 { return "ClusFindZPlane2"; } 50 51 // 52 53 /** 54 *Return a String representation of the class' type name. 55 *Included for completeness with the C++ version. 56 * 57 * @return A String representation of the class' type name. 58 */ 59 public static String staticType() 60 { return typeName(); } 61 62 // attributes 63 64 // surface 65 private SurfZPlane _szp; 66 67 // maximum allowed chi-square difference 68 private double _max_chsq_diff; 69 70 // clusters 71 private List _clusters; 72 73 74 // methods 75 76 // 77 78 /** 79 *Construct an instance from the z location of the plane and the maximum chi-square 80 *difference which defines the nearness of a hit to a track. 81 * 82 * @param zpos The z position of the z plane. 83 * @param max_chsq_diff The maximum chi-square for a track-hit association. 84 */ 85 public ClusFindZPlane2(double zpos, double max_chsq_diff) 86 { 87 _clusters = new ArrayList(); //use a TreeMap to automatically sort 88 _szp = new SurfZPlane(zpos); 89 _max_chsq_diff = max_chsq_diff; 90 } 91 92 // 93 94 /** 95 *Add a cluster to this ClusterFindManager. 96 * The cluster must be of type ClusCylPhi or ClusCylPhiZ. 97 * 98 * @param clus The Cluster to add. 99 * @return 0 if successful. 100 */ 101 public int addCluster( Cluster clus) 102 { 103 // Extract the cluster position depending on type 104 if ( clus.type().equals(ClusZPlane2.staticType()) ) 105 { 106 ClusZPlane2 clu = ( ClusZPlane2) clus; 107 Assert.assertTrue( clu.surface().equals(_szp) ); 108 } else 109 { 110 Assert.assertTrue(false); 111 return 1; 112 } 113 114 // Check there is no other cluster at this position. 115 if ( _clusters.contains(clus)) 116 { 117 Assert.assertTrue(false); 118 System.exit(2); 119 } 120 // Store the cluster. 121 _clusters.add(clus); 122 123 return 0; 124 125 } 126 127 // 128 129 /** 130 *Drop all clusters from this manager. 131 * 132 */ 133 public void dropClusters() 134 { 135 _clusters.clear(); 136 } 137 138 // 139 140 /** 141 *Return the surface. 142 * 143 * @return The Surface associated to this manager. 144 */ 145 public Surface surface() 146 { return _szp; } 147 148 // 149 150 /** 151 *Return all the clusters. 152 * 153 * @return The list of clusters managed by this manager. 154 */ 155 public List clusters() 156 { 157 // Create the list of clusters. 158 List clusters = new ArrayList(); 159 160 // Loop over clusters and add to output list. 161 162 for ( Iterator iclu=_clusters.iterator(); iclu.hasNext(); ) 163 clusters.add( iclu.next() ); 164 165 return clusters; 166 167 } 168 169 // 170 171 /** 172 *Return all the clusters near a track at the surface. Nearness is delimited by the 173 *maximum chi-squared between the track prediction and the cluster measurement. 174 * 175 * Clusters have been ordered by axy. 176 * The nearby subset is returned in the same order. 177 * 178 * @param tre The ETrack for which to return clusters. 179 * @return A list of clusters near the track tre. 180 */ 181 public List clusters( ETrack tre) 182 { 183 // Create the list of clusters. 184 List clusters = new ArrayList(); 185 186 // Check the track surface. 187 if ( !tre.surface().equals(_szp) ) 188 { 189 Assert.assertTrue(false); 190 return clusters; 191 } 192 193 // If there are no clusters, return the empty list. 194 if ( _clusters.size()==0 ) return clusters; 195 196 //for time being loop over all the clusters. 197 // need to be smarter later 198 199 for(Iterator it = _clusters.iterator(); it.hasNext(); ) 200 { 201 //get the cluster 202 Cluster clu = (Cluster) it.next(); 203 // is cluster within range? 204 if (chsq_diffzp2(clu,tre) < _max_chsq_diff ) 205 { 206 // if so add it to the list 207 clusters.add( clu ); 208 } 209 } 210 211 // Return the nearby clusters. 212 return clusters; 213 } 214 215 216 /** 217 * Return the maximum chi-square difference which defines a hit to be near a track. 218 * 219 * @return The maximum chi-square for a track-hit association. 220 */ 221 public double maxChsqDiff() 222 { return _max_chsq_diff ;} 223 224 // 225 226 /** 227 *Return a String representation of the class' type name. 228 *Included for completeness with the C++ version. 229 * 230 * @return A String representation of the class' type name. 231 */ 232 public String type() 233 { return staticType(); } 234 235 // 236 237 /** 238 *output stream 239 * 240 * @return A String representation of this instance. 241 */ 242 public String toString() 243 { 244 StringBuffer sb = new StringBuffer("2D Cluster finder for \n" + _szp +"\n"); 245 sb.append("Maximum chi-square difference is " 246 + _max_chsq_diff + ".\n"); 247 return sb.toString(); 248 } 249 250 251 //********************************************************************** 252 // Helper functions. 253 //********************************************************************** 254 255 // Calculate the chi-square difference between and cluster and a track. 256 // Only x components are taken into account for calculated returned chisq_diff 257 // Real chisquare are returned in double *chisq variable 258 // It is assumed the cluster generates exactly one prediction and that 259 // this prediction has two dimension. 260 261 private static double chsq_diffzp2( Cluster clus, ETrack tre) 262 { 263 264 ClusZPlane2 clu = ( ClusZPlane2)(clus); 265 TrackVector vec = tre.vector(); 266 TrackError err = tre.error(); 267 268 double diff0 = clu.x() - vec.get(SurfZPlane.IX ); 269 double diff1 = clu.y() - vec.get(SurfZPlane.IY ); 270 271 if ( diff0 == 0. && diff1 == 0. ) return 0.; 272 273 double e11 = err.get(SurfZPlane.IX,SurfZPlane.IX); 274 double e22 = err.get(SurfZPlane.IY,SurfZPlane.IY); 275 double e12 = err.get(SurfZPlane.IY,SurfZPlane.IX); 276 double a = e11 + clu.dX2(); 277 double b = e12 + clu.dXdY(); 278 double c = e22 + clu.dY2(); 279 double det = a*c-b*b; 280 281 if ( det == 0. ) return 1.e15; 282 283 double chisq = (c*diff0*diff0 + a*diff1*diff1 - 2*b*diff0*diff1)/det; 284 285 if ( chisq < 0 ) return 1.e15; 286 287 return chisq; 288 289 } 290 291 292 }