Print

Print


Commit in lcsim/src/org/lcsim/contrib/onoprien/crux on MAIN
algorithms/ClusteringDriver.java+2-11.3 -> 1.4
algorithms/rosary/Bead.java+2-11.1 -> 1.2
                 /Crack.java+2-11.1 -> 1.2
                 /Dot.java+2-11.1 -> 1.2
                 /DotAndBeadFinder.java+3-11.1 -> 1.2
                 /LayerStore.java+6-31.1 -> 1.2
                 /RosaryClusterer.java+8-61.1 -> 1.2
                 /RosaryNode.java+2-11.1 -> 1.2
                 /RosaryNodeCluster.java+2-11.1 -> 1.2
diagnostics/ClusteringTest.java+3-11.2 -> 1.3
infrastructure/CruxCalLayer.java+25-71.1 -> 1.2
              /CruxCalModule.java+28-351.2 -> 1.3
              /CruxCluster.java+5-51.1 -> 1.2
              /CruxConfig.java+111-531.2 -> 1.3
              /CruxEvent.java+5-21.2 -> 1.3
              /CruxGeometry.java+36-61.2 -> 1.3
              /CruxHitMap.java+5-21.2 -> 1.3
              /CruxManager.java+8-31.2 -> 1.3
tests/TestDriverRosary.java+2-11.1 -> 1.2
util/ConstHep3Vector.java+97added 1.1
    /ConstList.java-3951.2 removed
+354-526
1 added + 1 removed + 19 modified, total 21 files


lcsim/src/org/lcsim/contrib/onoprien/crux/algorithms
ClusteringDriver.java 1.3 -> 1.4
diff -u -r1.3 -r1.4
--- ClusteringDriver.java	22 Apr 2008 18:27:54 -0000	1.3
+++ ClusteringDriver.java	27 Jun 2008 02:55:20 -0000	1.4
@@ -2,6 +2,7 @@
 
 import java.util.*;
 import java.util.logging.Level;
+import org.lcsim.contrib.onoprien.crux.infrastructure.CruxCalModule;
 
 import org.lcsim.event.Cluster;
 import org.lcsim.event.EventHeader;
@@ -18,7 +19,7 @@
  * input hit map from the event, 
  *
  * @author D. Onoprienko
- * @version $Id: ClusteringDriver.java,v 1.3 2008/04/22 18:27:54 onoprien Exp $
+ * @version $Id: ClusteringDriver.java,v 1.4 2008/06/27 02:55:20 onoprien Exp $
  */
 public class ClusteringDriver extends CruxDriver {
   

lcsim/src/org/lcsim/contrib/onoprien/crux/algorithms/rosary
Bead.java 1.1 -> 1.2
diff -u -r1.1 -r1.2
--- Bead.java	22 Apr 2008 18:27:54 -0000	1.1
+++ Bead.java	27 Jun 2008 02:55:20 -0000	1.2
@@ -1,6 +1,7 @@
 package org.lcsim.contrib.onoprien.crux.algorithms.rosary;
 
 import java.util.*;
+import org.lcsim.contrib.onoprien.crux.infrastructure.CruxCalLayer;
 
 import org.lcsim.event.CalorimeterHit;
 import org.lcsim.event.Cluster;
@@ -11,7 +12,7 @@
  *
  *
  * @author D. Onoprienko
- * @version $Id: Bead.java,v 1.1 2008/04/22 18:27:54 onoprien Exp $
+ * @version $Id: Bead.java,v 1.2 2008/06/27 02:55:20 onoprien Exp $
  */
 public class Bead extends RosaryNodeCluster {
   

lcsim/src/org/lcsim/contrib/onoprien/crux/algorithms/rosary
Crack.java 1.1 -> 1.2
diff -u -r1.1 -r1.2
--- Crack.java	22 Apr 2008 18:27:54 -0000	1.1
+++ Crack.java	27 Jun 2008 02:55:20 -0000	1.2
@@ -1,12 +1,13 @@
 package org.lcsim.contrib.onoprien.crux.algorithms.rosary;
 
+import org.lcsim.contrib.onoprien.crux.infrastructure.CruxCalLayer;
 import org.lcsim.contrib.onoprien.crux.infrastructure.*;
 
 /**
  * Class to represent a crack in a {@link Rosary} - a layer with no clusters attached.
  *
  * @author D. Onoprienko
- * @version $Id: Crack.java,v 1.1 2008/04/22 18:27:54 onoprien Exp $
+ * @version $Id: Crack.java,v 1.2 2008/06/27 02:55:20 onoprien Exp $
  */
 public class Crack extends RosaryNode {
   

lcsim/src/org/lcsim/contrib/onoprien/crux/algorithms/rosary
Dot.java 1.1 -> 1.2
diff -u -r1.1 -r1.2
--- Dot.java	22 Apr 2008 18:27:54 -0000	1.1
+++ Dot.java	27 Jun 2008 02:55:20 -0000	1.2
@@ -1,6 +1,7 @@
 package org.lcsim.contrib.onoprien.crux.algorithms.rosary;
 
 import java.util.*;
+import org.lcsim.contrib.onoprien.crux.infrastructure.CruxCalLayer;
 
 import org.lcsim.event.CalorimeterHit;
 import org.lcsim.event.Cluster;
@@ -11,7 +12,7 @@
  *
  *
  * @author D. Onoprienko
- * @version $Id: Dot.java,v 1.1 2008/04/22 18:27:54 onoprien Exp $
+ * @version $Id: Dot.java,v 1.2 2008/06/27 02:55:20 onoprien Exp $
  */
 public class Dot extends RosaryNodeCluster {
   

lcsim/src/org/lcsim/contrib/onoprien/crux/algorithms/rosary
DotAndBeadFinder.java 1.1 -> 1.2
diff -u -r1.1 -r1.2
--- DotAndBeadFinder.java	22 Apr 2008 18:27:54 -0000	1.1
+++ DotAndBeadFinder.java	27 Jun 2008 02:55:20 -0000	1.2
@@ -1,6 +1,8 @@
 package org.lcsim.contrib.onoprien.crux.algorithms.rosary;
 
 import java.util.*;
+import org.lcsim.contrib.onoprien.crux.infrastructure.CruxCalLayer;
+import org.lcsim.contrib.onoprien.crux.infrastructure.CruxGeometry;
 
 import org.lcsim.event.Cluster;
 import org.lcsim.recon.cluster.nn.NearestNeighborClusterer;
@@ -12,7 +14,7 @@
  * Clusterer that creates {@link Dot}s and {@link Beads} on a layer.
  *
  * @author D. Onoprienko
- * @version $Id: DotAndBeadFinder.java,v 1.1 2008/04/22 18:27:54 onoprien Exp $
+ * @version $Id: DotAndBeadFinder.java,v 1.2 2008/06/27 02:55:20 onoprien Exp $
  */
 public class DotAndBeadFinder implements CruxEventListener {
   

lcsim/src/org/lcsim/contrib/onoprien/crux/algorithms/rosary
LayerStore.java 1.1 -> 1.2
diff -u -r1.1 -r1.2
--- LayerStore.java	22 Apr 2008 18:27:54 -0000	1.1
+++ LayerStore.java	27 Jun 2008 02:55:20 -0000	1.2
@@ -1,6 +1,9 @@
 package org.lcsim.contrib.onoprien.crux.algorithms.rosary;
 
 import java.util.*;
+import org.lcsim.contrib.onoprien.crux.infrastructure.CruxCalLayer;
+import org.lcsim.contrib.onoprien.crux.infrastructure.CruxCalModule;
+import org.lcsim.contrib.onoprien.crux.infrastructure.CruxGeometry;
 
 import org.lcsim.event.CalorimeterHit;
 import org.lcsim.geometry.IDDecoder;
@@ -12,7 +15,7 @@
  * that belong to a particular layer of a particular calorimeter module.
  *
  * @author D. Onoprienko
- * @version $Id: LayerStore.java,v 1.1 2008/04/22 18:27:54 onoprien Exp $
+ * @version $Id: LayerStore.java,v 1.2 2008/06/27 02:55:20 onoprien Exp $
  */
 public class LayerStore {
   
@@ -32,11 +35,11 @@
   static public LayerStore[] buildStorage(CruxGeometry geom) {
     List<CruxCalModule> modList = geom.getModules();
     List<CruxCalLayer> layerList = modList.get(modList.size()-1).getLayers();
-    int nLayers = layerList.get(layerList.size()-1).getID()+1;
+    int nLayers = layerList.get(layerList.size()-1).getLayerID()+1;
     LayerStore[] storage = new LayerStore[nLayers];
     for (CruxCalModule mod : modList) {
       for (CruxCalLayer layer : mod.getLayers()) {
-        storage[layer.getID()] = new LayerStore(layer);
+        storage[layer.getLayerID()] = new LayerStore(layer);
       }      
     }
     return storage;

lcsim/src/org/lcsim/contrib/onoprien/crux/algorithms/rosary
RosaryClusterer.java 1.1 -> 1.2
diff -u -r1.1 -r1.2
--- RosaryClusterer.java	22 Apr 2008 18:27:54 -0000	1.1
+++ RosaryClusterer.java	27 Jun 2008 02:55:20 -0000	1.2
@@ -5,6 +5,8 @@
 
 import hep.physics.vec.BasicHep3Vector;
 import hep.physics.vec.Hep3Vector;
+import org.lcsim.contrib.onoprien.crux.infrastructure.CruxCalLayer;
+import org.lcsim.contrib.onoprien.crux.infrastructure.CruxGeometry;
 import org.lcsim.detector.IDetectorElement;
 import org.lcsim.event.CalorimeterHit;
 import org.lcsim.event.Cluster;
@@ -21,7 +23,7 @@
  *
  *
  * @author D. Onoprienko
- * @version $Id: RosaryClusterer.java,v 1.1 2008/04/22 18:27:54 onoprien Exp $
+ * @version $Id: RosaryClusterer.java,v 1.2 2008/06/27 02:55:20 onoprien Exp $
  */
 public class RosaryClusterer extends CruxDriver implements Clusterer, CruxEventListener {
   
@@ -167,7 +169,7 @@
       return reverseThreadingDirection(rosary);
     }
     
-    List<Dot> dots = searchForDots(rosary, trajectory, _layers[layer.getID()]);
+    List<Dot> dots = searchForDots(rosary, trajectory, _layers[layer.getLayerID()]);
     int nDots = dots.size();
     if (nDots > 0) {
       rosary.addNode(dots.get(0));
@@ -177,12 +179,12 @@
         seeds.add(branch);
       }
     } else {
-      Bead bead = searchForBead(rosary, trajectory, _layers[layer.getID()]);
+      Bead bead = searchForBead(rosary, trajectory, _layers[layer.getLayerID()]);
       if (bead != null) {
         rosary.addNode(bead);
       } else {
         if (rosary.getNodeCount(DOT) == 1 && !rosary.isTracked()) {
-          dots = searchForProximityDots(rosary, trajectory, _layers[layer.getID()]);
+          dots = searchForProximityDots(rosary, trajectory, _layers[layer.getLayerID()]);
           nDots = dots.size();
           if (nDots > 0) {
             rosary.addNode(dots.get(0));
@@ -215,7 +217,7 @@
    * <tt>Dots</tt> that contain at least one of the nearest neighbours.</i>
    */
   protected List<Dot> searchForDots(Rosary rosary, Trajectory trajectory, LayerStore store) {
-    Hep3Vector pos = trajectory.getOrigin();
+    Hep3Vector pos = trajectory.getPoint();
     long cell = store.decoder.findCellContainingXYZ(pos);
     Dot dot = store.dotMap.get(cell);
     ArrayList<Dot> out;
@@ -243,7 +245,7 @@
    */
   protected Bead searchForBead(Rosary rosary, Trajectory trajectory, LayerStore store) {
     if (store.beads.isEmpty()) return null;
-    Hep3Vector pos = trajectory.getOrigin();
+    Hep3Vector pos = trajectory.getPoint();
     return store.beadMap.get(store.decoder.findCellContainingXYZ(pos));
   }
   

lcsim/src/org/lcsim/contrib/onoprien/crux/algorithms/rosary
RosaryNode.java 1.1 -> 1.2
diff -u -r1.1 -r1.2
--- RosaryNode.java	22 Apr 2008 18:27:54 -0000	1.1
+++ RosaryNode.java	27 Jun 2008 02:55:20 -0000	1.2
@@ -1,6 +1,7 @@
 package org.lcsim.contrib.onoprien.crux.algorithms.rosary;
 
 import java.util.*;
+import org.lcsim.contrib.onoprien.crux.infrastructure.CruxCalLayer;
 
 import org.lcsim.contrib.onoprien.crux.infrastructure.*;
 
@@ -9,7 +10,7 @@
  * the {@link Rosary} in a particular layer.
  *
  * @author D. Onoprienko
- * @version $Id: RosaryNode.java,v 1.1 2008/04/22 18:27:54 onoprien Exp $
+ * @version $Id: RosaryNode.java,v 1.2 2008/06/27 02:55:20 onoprien Exp $
  */
 public class RosaryNode {
   

lcsim/src/org/lcsim/contrib/onoprien/crux/algorithms/rosary
RosaryNodeCluster.java 1.1 -> 1.2
diff -u -r1.1 -r1.2
--- RosaryNodeCluster.java	22 Apr 2008 18:27:54 -0000	1.1
+++ RosaryNodeCluster.java	27 Jun 2008 02:55:20 -0000	1.2
@@ -4,6 +4,7 @@
 
 import hep.physics.vec.BasicHep3Vector;
 import hep.physics.vec.Hep3Vector;
+import org.lcsim.contrib.onoprien.crux.infrastructure.CruxCalLayer;
 import org.lcsim.event.CalorimeterHit;
 import org.lcsim.event.Cluster;
 
@@ -13,7 +14,7 @@
  * Class that represents a rosary node that contains calorimeter hits - either {@link Dot} or {@link Bead}.
  *
  * @author D. Onoprienko
- * @version $Id: RosaryNodeCluster.java,v 1.1 2008/04/22 18:27:54 onoprien Exp $
+ * @version $Id: RosaryNodeCluster.java,v 1.2 2008/06/27 02:55:20 onoprien Exp $
  */
 public class RosaryNodeCluster extends RosaryNode {
   

lcsim/src/org/lcsim/contrib/onoprien/crux/diagnostics
ClusteringTest.java 1.2 -> 1.3
diff -u -r1.2 -r1.3
--- ClusteringTest.java	22 Apr 2008 18:27:54 -0000	1.2
+++ ClusteringTest.java	27 Jun 2008 02:55:20 -0000	1.3
@@ -2,6 +2,8 @@
 
 import java.util.*;
 import java.util.logging.Level;
+import org.lcsim.contrib.onoprien.crux.infrastructure.CruxCalModule;
+import org.lcsim.contrib.onoprien.crux.infrastructure.CruxGeometry;
 
 import org.lcsim.event.CalorimeterHit;
 import org.lcsim.event.EventHeader;
@@ -17,7 +19,7 @@
  *
  *
  * @author D. Onoprienko
- * @version $Id: ClusteringTest.java,v 1.2 2008/04/22 18:27:54 onoprien Exp $
+ * @version $Id: ClusteringTest.java,v 1.3 2008/06/27 02:55:20 onoprien Exp $
  */
 public class ClusteringTest extends CruxDriver implements CruxEventListener {
   

lcsim/src/org/lcsim/contrib/onoprien/crux/infrastructure
CruxCalLayer.java 1.1 -> 1.2
diff -u -r1.1 -r1.2
--- CruxCalLayer.java	22 Apr 2008 18:27:54 -0000	1.1
+++ CruxCalLayer.java	27 Jun 2008 02:55:20 -0000	1.2
@@ -3,21 +3,24 @@
 import org.lcsim.detector.IDetectorElement;
 import org.lcsim.geometry.IDDecoder;
 
+import org.lcsim.contrib.onoprien.crux.swim.Surface;
+
 /**
  * Class that represents a layer inside a calorimeter module.
  *
  * @author D. Onoprienko
- * @version $Id: CruxCalLayer.java,v 1.1 2008/04/22 18:27:54 onoprien Exp $
+ * @version $Id: CruxCalLayer.java,v 1.2 2008/06/27 02:55:20 onoprien Exp $
  */
 public class CruxCalLayer implements Comparable<CruxCalLayer> {
   
 // -- Constructors :  ----------------------------------------------------------
   
-  public CruxCalLayer(CruxCalModule module, int layer, IDetectorElement detectorElement, int id) {
+  public CruxCalLayer(CruxCalModule module, IDetectorElement detectorElement, int ordinal, int layerID, int layerNumber) {
     _module = module;
-    _layer = layer;
+    _ordinal = ordinal;
     _detEl = detectorElement;
-    _id = id;
+    _layer = layerNumber;
+    _id = layerID;
   }
   
 // -- Getters :  ---------------------------------------------------------------
@@ -27,29 +30,42 @@
     return _module;
   }
   
+  /** Returns reference surface of this layer. */
+  public Surface getReferenceSurface() {
+    return _refSurf;
+  }
+  
   /** 
    * Returns layer number as reported by {@link IDDecoder} for hits in this layer.
    * Note that layers in a module are not necessarily numbered starting from zero.
    */
-  public int getLayer() {
+  public int getLayerNumber() {
     return _layer;
   }
   
   /** 
    * Returns global layer ID (unique within the detector).
-   * IDs for all <tt>CruxCalModules</tt> in the detector form a continuous sequence 
+   * IDs for all <tt>CruxCalLayers</tt> in the detector form a continuous sequence 
    * starting with 0, in the increasing module ID order (increasing layer number inside
    * modules).
    */
-  public int getID() {
+  public int getLayerID() {
     return _id;
   }
   
+  /**
+   * Returns layer position in a module, numbered from inside to outside, starting from zero.
+   */
+  public int getLayerOrdinal() {
+    return _ordinal;
+  }
+  
   /** Returns <tt>DetectorElement</tt> associated with this layer. */
   public IDetectorElement getDetectorElement() {
     return _detEl;
   }
   
+  
 // -- Ordering :  --------------------------------------------------------------
   
   /** Defines natural ordering of layers (increasing ID order). */
@@ -62,5 +78,7 @@
   private CruxCalModule _module;
   private int _layer;
   private int _id;
+  private int _ordinal;
   private IDetectorElement _detEl;
+  private Surface _refSurf;
 }

lcsim/src/org/lcsim/contrib/onoprien/crux/infrastructure
CruxCalModule.java 1.2 -> 1.3
diff -u -r1.2 -r1.3
--- CruxCalModule.java	22 Apr 2008 18:27:54 -0000	1.2
+++ CruxCalModule.java	27 Jun 2008 02:55:20 -0000	1.3
@@ -8,49 +8,24 @@
  * Class to represent a part of the calorimeter.
  *
  * @author D. Onoprienko
- * @version $Id: CruxCalModule.java,v 1.2 2008/04/22 18:27:54 onoprien Exp $
+ * @version $Id: CruxCalModule.java,v 1.3 2008/06/27 02:55:20 onoprien Exp $
  */
 public class CruxCalModule {
   
   public enum Attribute {ECAL, HCAL, BARREL, ENDCAP, SOUTH, NORTH}
   
-// -- Constructors :  ----------------------------------------------------------
+// -- Constructors and initialization :  ---------------------------------------
   
-  public CruxCalModule() {
-    _name = "";
-  }
-  
-  public CruxCalModule(String name) {
-    _name = name;
-  }
-  
-  public CruxCalModule(int id, String name, EnumSet<Attribute> attributes) {
-    _id = id;
+  public CruxCalModule(String name, EnumSet<Attribute> attributes, String subdetectorName) {
     _name = name;
     _attributes = attributes;
+    _sdName = subdetectorName;
   }
-  
-// -- Setters :  ---------------------------------------------------------------
-  
-  public void setID(int id) {_id = id;}
-  
-  public void setName(String name) {_name = name;}
-  
-  public void setAttributes(Attribute... attributes) {
-    _attributes = EnumSet.noneOf(Attribute.class);
-    for (Attribute att : attributes) _attributes.add(att);
-  }
-  
-  public void setSubdetectorName(String subDetName) {
-    _sdName = subDetName;
-  }
-  
-  public void setSubdetector(Subdetector subDet) {
+
+  public void initialize(int moduleID, Subdetector subDet, List<CruxCalLayer> layers) {
+    _id = moduleID;
     _sd = subDet;
-  }
-  
-  public void setLayers(ArrayList<CruxCalLayer> layers) {
-    _layers = layers;
+    _layers = new ArrayList<CruxCalLayer>(layers);
   }
   
 // -- Getters :  ---------------------------------------------------------------
@@ -100,8 +75,26 @@
   }
   
   public List<CruxCalLayer> getLayers() {
-    return _layers;
-  } 
+    return Collections.unmodifiableList(_layers);
+  }
+  
+  public CruxCalLayer getLayerByOrdinal(int ordinal) {
+    try {
+      return _layers.get(ordinal);
+    } catch (IndexOutOfBoundsException x) {
+      return null;
+    }
+  }
+  
+  public CruxCalLayer getLayerByNumber(int layerNumber) {
+    int ordinal = layerNumber - _layers.get(0).getLayerNumber();
+    return getLayerByOrdinal(ordinal);
+  }
+  
+  public CruxCalLayer getLayerByID(int layerID) {
+    int ordinal = layerID - _layers.get(0).getLayerID();
+    return getLayerByOrdinal(ordinal);
+  }
   
 // -- Private parts :  ---------------------------------------------------------
   

lcsim/src/org/lcsim/contrib/onoprien/crux/infrastructure
CruxCluster.java 1.1 -> 1.2
diff -u -r1.1 -r1.2
--- CruxCluster.java	2 Apr 2008 22:30:10 -0000	1.1
+++ CruxCluster.java	27 Jun 2008 02:55:20 -0000	1.2
@@ -4,17 +4,17 @@
 
 import hep.physics.matrix.SymmetricMatrix;
 import hep.physics.vec.BasicHep3Vector;
+import org.lcsim.contrib.onoprien.crux.infrastructure.CruxCalModule;
+import org.lcsim.contrib.onoprien.crux.infrastructure.CruxGeometry;
 import org.lcsim.event.CalorimeterHit;
 import org.lcsim.event.Cluster;
 import org.lcsim.geometry.Subdetector;
 
-import org.lcsim.contrib.onoprien.crux.util.ConstList;
-
 /**
  * Class representing a cluster of calorimeter hits.
  *
  * @author D. Onoprienko
- * @version $Id: CruxCluster.java,v 1.1 2008/04/02 22:30:10 onoprien Exp $
+ * @version $Id: CruxCluster.java,v 1.2 2008/06/27 02:55:20 onoprien Exp $
  */
 public class CruxCluster implements Cluster {
   
@@ -175,7 +175,7 @@
    * Returns a list of clusters that have been combined to this cluster.
    */
   public List<Cluster> getClusters() {
-    return new ConstList<Cluster>(_clusters);
+    return Collections.<Cluster>unmodifiableList(_clusters);
   }
   
   /** 
@@ -184,7 +184,7 @@
    */
   public List<CalorimeterHit> getCalorimeterHits() {
     if (_clusters.isEmpty()) {
-      return new ConstList<CalorimeterHit>(_hits);
+      return Collections.unmodifiableList(_hits);
     } else {
       HashSet<CalorimeterHit> hits = new HashSet<CalorimeterHit>(100);
       hits.addAll(_hits);

lcsim/src/org/lcsim/contrib/onoprien/crux/infrastructure
CruxConfig.java 1.2 -> 1.3
diff -u -r1.2 -r1.3
--- CruxConfig.java	22 Apr 2008 18:27:54 -0000	1.2
+++ CruxConfig.java	27 Jun 2008 02:55:20 -0000	1.3
@@ -2,6 +2,7 @@
 
 import java.util.*;
 
+import hep.physics.vec.Hep3Vector;
 import org.lcsim.detector.IDetectorElement;
 import org.lcsim.detector.IDetectorElementVisitor;
 import org.lcsim.event.CalorimeterHit;
@@ -9,11 +10,24 @@
 import org.lcsim.geometry.Detector;
 import org.lcsim.geometry.Subdetector;
 import org.lcsim.geometry.subdetector.BarrelEndcapFlag;
+
+import org.lcsim.contrib.onoprien.crux.infrastructure.CruxCalLayer;
+import org.lcsim.contrib.onoprien.crux.infrastructure.CruxCalModule;
+import org.lcsim.contrib.onoprien.crux.swim.Surface;
+import org.lcsim.contrib.onoprien.crux.swim.Trajectory;
+import org.lcsim.contrib.onoprien.crux.swim.ZDisk;
+import org.lcsim.contrib.onoprien.crux.swim.ZCylinder;
+
+import static org.lcsim.contrib.onoprien.crux.infrastructure.CruxCalModule.Attribute.*;
+
 /**
  * Crux package custom configuration class.
  * <p>
  * This class is intended to be a single location where all the ugly detector-specific
- * of running mode specific code is placed.
+ * or running mode specific code is placed. {@link CruxManager} creates a single instance
+ * of this class, and calls its {@link #detectorChanged detectorChanged(CruxEvent)} method once the event processing 
+ * starts, before calling any other {@link CruxEventListener}s. During event processing,
+ * any client class has access to <tt>CruxConfig</tt> singleton through {@link CruxManager#getConfig()}.
  * <p>
  * Current content:
  * <ul>
@@ -25,7 +39,7 @@
  * </ul>
  *
  * @author D. Onoprienko
- * @version $Id: CruxConfig.java,v 1.2 2008/04/22 18:27:54 onoprien Exp $
+ * @version $Id: CruxConfig.java,v 1.3 2008/06/27 02:55:20 onoprien Exp $
  */
 public class CruxConfig {
   
@@ -63,41 +77,51 @@
 // -- Division of calorimeter into modules :  ----------------------------------
   
   protected void moduleConstruct() {
-    
-    CruxCalModule ecalBarrel = new CruxCalModule("ECAL_BARREL");
-    ecalBarrel.setAttributes(CruxCalModule.Attribute.ECAL, CruxCalModule.Attribute.BARREL);
-    ecalBarrel.setSubdetectorName("EMBarrel");
-    
-    CruxCalModule hcalBarrel = new CruxCalModule("HCAL_BARREL");
-    hcalBarrel.setAttributes(CruxCalModule.Attribute.HCAL, CruxCalModule.Attribute.BARREL);
-    hcalBarrel.setSubdetectorName("HADBarrel");
-    
-    CruxCalModule ecalEndSouth = new CruxCalModule("ECAL_ENDCAP_SOUTH");
-    ecalEndSouth.setAttributes(CruxCalModule.Attribute.ECAL, CruxCalModule.Attribute.ENDCAP, CruxCalModule.Attribute.SOUTH);
-    ecalEndSouth.setSubdetectorName("EMEndcap");
-    
-    CruxCalModule ecalEndNorth = new CruxCalModule("ECAL_ENDCAP_NORTH");
-    ecalEndNorth.setAttributes(CruxCalModule.Attribute.ECAL, CruxCalModule.Attribute.ENDCAP, CruxCalModule.Attribute.NORTH);
-    ecalEndNorth.setSubdetectorName("EMEndcap");
-    
-    CruxCalModule hcalEndSouth = new CruxCalModule("HCAL_ENDCAP_SOUTH");
-    hcalEndSouth.setAttributes(CruxCalModule.Attribute.HCAL, CruxCalModule.Attribute.ENDCAP, CruxCalModule.Attribute.SOUTH);
-    hcalEndSouth.setSubdetectorName("HADEndcap");
-    
-    CruxCalModule hcalEndNorth = new CruxCalModule("HCAL_ENDCAP_NORTH");
-    hcalEndNorth.setAttributes(CruxCalModule.Attribute.HCAL, CruxCalModule.Attribute.ENDCAP, CruxCalModule.Attribute.NORTH);
-    hcalEndNorth.setSubdetectorName("HADEndcap");
-    
-    _modules = new CruxCalModule[] {ecalBarrel, hcalBarrel, ecalEndSouth, ecalEndNorth, hcalEndSouth, hcalEndNorth};
-    for (int i=0; i<_modules.length; i++) _modules[i].setID(i);
   }
   
   protected void moduleInit(CruxEvent cruxEvent) {
+    
+    // create modules
+    
+    CruxCalModule eBar = new CruxCalModule("ECAL_BARREL", EnumSet.of(ECAL, BARREL), "EMBarrel");
+    CruxCalModule hBar = new CruxCalModule("HCAL_BARREL", EnumSet.of(HCAL, BARREL), "HADBarrel");
+    CruxCalModule eSouthEnd = new CruxCalModule("ECAL_ENDCAP_SOUTH", EnumSet.of(ECAL, ENDCAP, SOUTH), "EMEndcap");
+    CruxCalModule eNorthEnd = new CruxCalModule("ECAL_ENDCAP_NORTH", EnumSet.of(ECAL, ENDCAP, NORTH), "EMEndcap");
+    CruxCalModule hSouthEnd = new CruxCalModule("HCAL_ENDCAP_SOUTH", EnumSet.of(HCAL, ENDCAP, SOUTH), "HADEndcap");
+    CruxCalModule hNorthEnd = new CruxCalModule("HCAL_ENDCAP_NORTH", EnumSet.of(HCAL, ENDCAP, NORTH), "HADEndcap");
+    
+    _modules = new ArrayList<CruxCalModule>(6);
+    Collections.addAll(_modules, eBar, hBar, eSouthEnd, eNorthEnd, hSouthEnd, hNorthEnd);
+    
+    // neighbors
+    
+    List<CruxCalModule> emptyList = Collections.emptyList();
+    _previousModules = new ArrayList<List<CruxCalModule>>(6);
+    Collections.addAll( _previousModules,
+      emptyList,
+      new ArrayList<CruxCalModule>(Arrays.asList(new CruxCalModule[]{eBar})),
+      emptyList,
+      emptyList,
+      new ArrayList<CruxCalModule>(Arrays.asList(new CruxCalModule[]{eSouthEnd})),
+      new ArrayList<CruxCalModule>(Arrays.asList(new CruxCalModule[]{eNorthEnd}))
+    );
+    _nextModules = new ArrayList<List<CruxCalModule>>(6);
+    Collections.addAll(_nextModules,
+      new ArrayList<CruxCalModule>(Arrays.asList(new CruxCalModule[]{hBar})),
+      emptyList,
+      new ArrayList<CruxCalModule>(Arrays.asList(new CruxCalModule[]{hSouthEnd})),
+      new ArrayList<CruxCalModule>(Arrays.asList(new CruxCalModule[]{hNorthEnd})),
+      emptyList,
+      emptyList
+    );
+    
+    // assign DetectorElements
+    
     Detector det = cruxEvent.getDetector();
     int idOffset = 0;
+    int moduleID = 0;
     for (CruxCalModule module : _modules) {
       Subdetector sd = det.getSubdetector(module.getSubdetectorName());
-      module.setSubdetector(sd);
       final List<IDetectorElement> deList = new ArrayList<IDetectorElement>(50);
       sd.getDetectorElement().traverseDescendantsPreOrder(new IDetectorElementVisitor() {
         public void visit(IDetectorElement de) {
@@ -108,7 +132,7 @@
         }
         public boolean isDone() {return false;}
       });
-      ArrayList<CruxCalLayer> layerList = new ArrayList<CruxCalLayer>(deList.size());
+      TreeMap<Integer, IDetectorElement> deMap = new TreeMap<Integer, IDetectorElement>();
       for (IDetectorElement de : deList) {
         String name = de.getName();
         if (module.isBarrel() || 
@@ -116,12 +140,18 @@
           name = name.replaceFirst(".*layer","");
           name = name.replaceFirst(".*sensor","");
           int layer = Integer.parseInt(name);
-          int id = idOffset + layer;
-          layerList.add(new CruxCalLayer(module, layer, de, id));
+          deMap.put(layer, de);
         }
       }
-      Collections.sort(layerList);
-      module.setLayers(layerList);
+      ArrayList<CruxCalLayer> layerList = new ArrayList<CruxCalLayer>(deMap.size());
+      int ordinal = 0;
+      for (Map.Entry<Integer, IDetectorElement> entry : deMap.entrySet()) {
+        int layer = entry.getKey();
+        int id = idOffset + layer;
+        layerList.add(new CruxCalLayer(module, entry.getValue(), ordinal, id, layer));
+        ordinal++;
+      }
+      module.initialize(moduleID++, sd, layerList);
       idOffset += layerList.size();
     }
   }
@@ -133,35 +163,63 @@
     IDDecoder decoder = hit.getIDDecoder();
     decoder.setID(hit.getCellID());
     Subdetector subDet = decoder.getSubdetector();
-    if (subDet == _modules[0].getSubdetector()) {
-      return _modules[0];
-    } else if (subDet == _modules[1].getSubdetector()) {
-      return _modules[1];
+    if (subDet == _modules.get(0).getSubdetector()) {
+      return _modules.get(0);
+    } else if (subDet == _modules.get(1).getSubdetector()) {
+      return _modules.get(1);
     } else {
       BarrelEndcapFlag flag = decoder.getBarrelEndcapFlag();
-      if (subDet == _modules[2].getSubdetector()) {
-        return (flag.isEndcapSouth()) ? _modules[2] : _modules[3] ;
+      if (subDet == _modules.get(2).getSubdetector()) {
+        return (flag.isEndcapSouth()) ? _modules.get(2) : _modules.get(3) ;
       } else {
-        return (flag.isEndcapSouth()) ? _modules[4] : _modules[5] ;
+        return (flag.isEndcapSouth()) ? _modules.get(4) : _modules.get(5) ;
       }
     }
   }
   
-  /**
-   * Looks up <tt>CruxCalLayer</tt> the hit belongs to.
-   * As implemented, only works if layers in modules are numbered staring from zero.
-   */
-  public CruxCalLayer getLayer(CalorimeterHit hit) {
-    int iLayer = hit.getIDDecoder().getLayer();
-    CruxCalModule module = getModule(hit);
-    return module.getLayers().get(iLayer);
+  /** Returns a list of all modules. */
+  public List<CruxCalModule> getModules() {
+    return Collections.unmodifiableList(_modules);
   }
   
-  public CruxCalModule[] getModules() {
-    return _modules;
+  /**
+   * Returns a list of layers the specified trajectory might cross after coming out of the 
+   * given layer - more likely first. The origing of the trajectory should belong to the
+   * specified layer - no checking is done.
+   * <i>Current implementation: next layer in the same subdetector. Need to handle
+   *    transitions between barrel and endcap, curling.</i>
+   */
+  public List<CruxCalLayer> findNeighbors(CruxCalLayer layer, Trajectory trajectory) {
+    Surface surface = layer.getReferenceSurface();
+    Hep3Vector dir = trajectory.getDirection();
+    Hep3Vector pos = trajectory.getPoint();
+    double dirSign;
+    if (surface instanceof ZDisk) {
+      dirSign = dir.z()*pos.z();
+    } else {
+      dirSign = pos.x()*dir.x() + pos.y()*dir.y();
+    }
+    int iDirSign = (int) Math.signum(dirSign);
+    CruxCalModule module = layer.getModule();
+    CruxCalLayer nextLayer = module.getLayerByOrdinal(layer.getLayerOrdinal()+iDirSign);
+    ArrayList<CruxCalLayer> out = new ArrayList<CruxCalLayer>();
+    if (nextLayer == null) {
+      if (iDirSign > 0) {
+        List<CruxCalModule> nextModules =  _nextModules.get(module.getID());
+        for (CruxCalModule mod : nextModules) out.add(mod.getLayerByOrdinal(0));
+      } else {
+        List<CruxCalModule> nextModules =  _previousModules.get(module.getID());
+        for (CruxCalModule mod : nextModules) out.add(mod.getLayerByOrdinal(mod.getLayers().size()-1));
+      }
+    } else {
+      out.add(nextLayer);
+    }
+    return out;
   }
 
-  protected CruxCalModule[] _modules;
+  protected ArrayList<CruxCalModule> _modules;
+  protected ArrayList<List<CruxCalModule>> _previousModules;
+  protected ArrayList<List<CruxCalModule>> _nextModules;
   
 // -- Private parts :  ---------------------------------------------------------
   

lcsim/src/org/lcsim/contrib/onoprien/crux/infrastructure
CruxEvent.java 1.2 -> 1.3
diff -u -r1.2 -r1.3
--- CruxEvent.java	22 Apr 2008 18:27:54 -0000	1.2
+++ CruxEvent.java	27 Jun 2008 02:55:20 -0000	1.3
@@ -1,5 +1,6 @@
 package org.lcsim.contrib.onoprien.crux.infrastructure;
 
+import org.lcsim.contrib.onoprien.crux.infrastructure.CruxGeometry;
 import org.lcsim.geometry.Detector;
 import org.lcsim.event.EventHeader;
 
@@ -7,7 +8,7 @@
  * Class that represents an event dispatched by {@link CruxManager}.
  *
  * @author D. Onoprienko
- * @version $Id: CruxEvent.java,v 1.2 2008/04/22 18:27:54 onoprien Exp $
+ * @version $Id: CruxEvent.java,v 1.3 2008/06/27 02:55:20 onoprien Exp $
  */
 public class CruxEvent {
   
@@ -23,7 +24,9 @@
   /** Returns <tt>CruxManager</tt> object that fired this event. */
   public CruxManager getCruxManager() {return _cruxMan;}  
   
-  /** Returns <tt>CruxGeometry</tt> object describing the current geometry. */
+  /**
+   * Returns <tt>CruxGeometry</tt> object describing the current geometry.
+   */
   public CruxGeometry getGeometry() {return _cruxMan.getGeometry();}
   
   /** Returns <tt>Detector</tt> object describing the current geometry. */

lcsim/src/org/lcsim/contrib/onoprien/crux/infrastructure
CruxGeometry.java 1.2 -> 1.3
diff -u -r1.2 -r1.3
--- CruxGeometry.java	22 Apr 2008 18:27:54 -0000	1.2
+++ CruxGeometry.java	27 Jun 2008 02:55:20 -0000	1.3
@@ -12,9 +12,11 @@
 /**
  * Singleton of this class is created by {@link CruxManager}, and provides various 
  * detector geometry related services to other classes.
- *
+ * 
+ * 
+ * 
  * @author D. Onoprienko
- * @version $Id: CruxGeometry.java,v 1.2 2008/04/22 18:27:54 onoprien Exp $
+ * @version $Id: CruxGeometry.java,v 1.3 2008/06/27 02:55:20 onoprien Exp $
  */
 public class CruxGeometry implements CruxEventListener {
   
@@ -29,7 +31,7 @@
     _config = _cruxMan.getConfig();
     
     _detector = cruxEvent.getDetector();
-    _modules = _config.getModules();
+    _modules = new ArrayList(_config.getModules());
   }
   
 // -- Getters :  ---------------------------------------------------------------
@@ -41,7 +43,7 @@
   
   /** Returns a list of calorimeter modules. */
   public List<CruxCalModule> getModules() {
-    return Arrays.asList(_modules);
+    return Collections.unmodifiableList(_modules);
   }
   
   /** Returns calorimeter module the given hit belongs to. */
@@ -50,7 +52,9 @@
   }
   
   public CruxCalLayer getLayer(CalorimeterHit hit) {
-    return _config.getLayer(hit);
+    int iLayer = hit.getIDDecoder().getLayer();
+    CruxCalModule module = getModule(hit);
+    return module.getLayerByNumber(iLayer);
   }
   
   /** Returns <tt>true</tt> id the given hit belongs to EM calorimeter. */
@@ -66,6 +70,30 @@
 // -- Trajectory propagation :  ------------------------------------------------
   
   /**
+   * Returns a list of layers the specified trajectory might cross after coming out of the 
+   * given layer - more likely first. The origin of the trajectory should belong to the
+   * specified layer - no checking is done.
+   */
+  public List<CruxCalLayer> findNeighbors(CruxCalLayer layer, Trajectory trajectory) {
+    return _config.findNeighbors(layer, trajectory);
+  }
+
+  /**
+   * Propagates the given trajectory from the specified layer to the next calorimeter layer it crosses.
+   * <tt>CruxCalLayer</tt> object associated with that layer is returned, and
+   * the origin of the supplied <tt>Trajectory</tt> is set to a point where it
+   * crosses that layer's reference surface.
+   */
+  public CruxCalLayer propagateToNextLayer(CruxCalLayer currentLayer, Trajectory trajectory) {
+    List<CruxCalLayer> nextLayers = findNeighbors(currentLayer, trajectory);
+    for (CruxCalLayer candidate : nextLayers) {
+      Hep3Vector pos = propagateToLayer(trajectory, candidate);
+      if (pos != null) return candidate;
+    }
+    return null;
+  }
+  
+  /**
    * Propagates the given trajectory to the next calorimeter layer it crosses.
    * <tt>CruxCalLayer</tt> object associated with that layer is returned, and
    * the origin of the supplied <tt>Trajectory</tt> is set to a point where it
@@ -79,6 +107,8 @@
    * Propagates the given trajectory to the given calorimeter layer.
    * Returns the point where the trajectory intersects the layer's reference surface.
    * Origin of the supplied <tt>Trajectory</tt> is set to that point.
+   * If the trajectory does not cross the specified layer, <tt>null</tt> is returned
+   * and the trajectory is not changed.
    */  
   public Hep3Vector propagateToLayer(Trajectory trajectory, CruxCalLayer layer) {
     throw new UnsupportedOperationException();  // FIXME
@@ -96,5 +126,5 @@
   private CruxConfig _config;
 
   private Detector _detector;
-  private CruxCalModule[] _modules;
+  private ArrayList<CruxCalModule> _modules;
 }

lcsim/src/org/lcsim/contrib/onoprien/crux/infrastructure
CruxHitMap.java 1.2 -> 1.3
diff -u -r1.2 -r1.3
--- CruxHitMap.java	22 Apr 2008 18:27:54 -0000	1.2
+++ CruxHitMap.java	27 Jun 2008 02:55:20 -0000	1.3
@@ -1,6 +1,9 @@
 package org.lcsim.contrib.onoprien.crux.infrastructure;
 
 import java.util.*;
+import org.lcsim.contrib.onoprien.crux.infrastructure.CruxCalLayer;
+import org.lcsim.contrib.onoprien.crux.infrastructure.CruxCalModule;
+import org.lcsim.contrib.onoprien.crux.infrastructure.CruxGeometry;
 
 import org.lcsim.event.CalorimeterHit;
 
@@ -8,7 +11,7 @@
  *
  *
  * @author D. Onoprienko
- * @version $Id: CruxHitMap.java,v 1.2 2008/04/22 18:27:54 onoprien Exp $
+ * @version $Id: CruxHitMap.java,v 1.3 2008/06/27 02:55:20 onoprien Exp $
  */
 public class CruxHitMap extends org.lcsim.util.hitmap.HitMap {
   
@@ -109,7 +112,7 @@
   public ArrayList<CalorimeterHit> getList(final CruxCalLayer layer) {
     CruxHitFilter filter = new CruxHitFilter() {
       public boolean pass(CalorimeterHit hit) {
-        return (layer.getModule() == _geom.getModule(hit) && layer.getLayer() == hit.getIDDecoder().getLayer());
+        return (layer.getModule() == _geom.getModule(hit) && layer.getLayerNumber() == hit.getIDDecoder().getLayer());
       }
     };
     return getList(filter);

lcsim/src/org/lcsim/contrib/onoprien/crux/infrastructure
CruxManager.java 1.2 -> 1.3
diff -u -r1.2 -r1.3
--- CruxManager.java	22 Apr 2008 18:27:54 -0000	1.2
+++ CruxManager.java	27 Jun 2008 02:55:20 -0000	1.3
@@ -7,6 +7,7 @@
 import org.lcsim.conditions.ConditionsEvent;
 import org.lcsim.conditions.ConditionsManager;
 import org.lcsim.conditions.ConditionsManager.ConditionsSetNotFoundException;
+import org.lcsim.contrib.onoprien.crux.infrastructure.CruxGeometry;
 import org.lcsim.event.CalorimeterHit;
 import org.lcsim.event.EventHeader;
 import org.lcsim.geometry.Detector;
@@ -21,9 +22,11 @@
  * <li>Provides access to {@link CruxConfig} object - all kinds of deta specific functionality.
  * <li>Allows setting the default {@link CruxClusterValidator}.
  * </ul>
- *
+ * 
+ * 
+ * 
  * @author D. Onoprienko
- * @version $Id: CruxManager.java,v 1.2 2008/04/22 18:27:54 onoprien Exp $
+ * @version $Id: CruxManager.java,v 1.3 2008/06/27 02:55:20 onoprien Exp $
  */
 public class CruxManager extends CruxDriver implements ConditionsListener {
   
@@ -56,7 +59,9 @@
     return _defInstance;
   }
   
-  /** Returns <tt>CruxGeometry</tt> object associated with this <tt>CruxManager</tt>. */
+  /**
+   * Returns <tt>CruxGeometry</tt> object associated with this <tt>CruxManager</tt>.
+   */
   public CruxGeometry getGeometry() {
     return _geom;
   }

lcsim/src/org/lcsim/contrib/onoprien/crux/tests
TestDriverRosary.java 1.1 -> 1.2
diff -u -r1.1 -r1.2
--- TestDriverRosary.java	22 Apr 2008 18:27:54 -0000	1.1
+++ TestDriverRosary.java	27 Jun 2008 02:55:20 -0000	1.2
@@ -2,6 +2,7 @@
 
 import java.util.*;
 import java.util.logging.Level;
+import org.lcsim.contrib.onoprien.crux.infrastructure.CruxGeometry;
 
 import org.lcsim.digisim.DigiSimDriver;
 import org.lcsim.digisim.SimCalorimeterHitsDriver;
@@ -27,7 +28,7 @@
  *
  *
  * @author D. Onoprienko
- * @version $Id: TestDriverRosary.java,v 1.1 2008/04/22 18:27:54 onoprien Exp $
+ * @version $Id: TestDriverRosary.java,v 1.2 2008/06/27 02:55:20 onoprien Exp $
  */
 public class TestDriverRosary extends CruxDriver {
   

lcsim/src/org/lcsim/contrib/onoprien/crux/util
ConstHep3Vector.java added at 1.1
diff -N ConstHep3Vector.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ConstHep3Vector.java	27 Jun 2008 02:55:20 -0000	1.1
@@ -0,0 +1,97 @@
+package org.lcsim.contrib.onoprien.crux.util;
+
+import java.io.Serializable;
+
+import hep.physics.vec.Hep3Vector;
+import hep.physics.vec.VecOp;
+
+/**
+ * Immutable implementation of <tt>Hep3Vector</tt>.
+ * <p>
+ * Coordinates supplied to constructors are interpreted as cartesian.
+ * The class is identical to <tt>hep.physics.vec.BasicHep3Vector</t> except:
+ * <ul><li>No <tt>set</tt> method, making it immutable
+ *     <li>Constructor that takes <tt>Hep3Vector</tt>
+ *     <li>No input array length check in constructors.</ul>
+ *
+ * @author D. Onoprienko
+ * @version $Id: ConstHep3Vector.java,v 1.1 2008/06/27 02:55:20 onoprien Exp $
+ */
+final public class ConstHep3Vector implements Hep3Vector, Serializable {
+  
+// -- Constructors :  ----------------------------------------------------------
+  
+  public ConstHep3Vector() {
+    _x = 0.;
+    _y = 0.;
+    _z = 0.;
+  }
+
+  public ConstHep3Vector(double x, double y, double z) {
+    _x = x;
+    _y = y;
+    _z = z;
+   }
+  
+  public ConstHep3Vector(double[] d) {
+    _x = d[0];
+    _y = d[1];
+    _z = d[2];
+  }
+  
+  public ConstHep3Vector(float[] f) {
+    _x = f[0];
+    _y = f[1];
+    _z = f[2];
+  }
+  
+  public ConstHep3Vector(Hep3Vector vector) {
+    _x = vector.x();
+    _y = vector.y();
+    _z = vector.z();
+  }
+  
+// -- Implementing Hep3Vector :  -----------------------------------------------
+  
+  public double x() {
+    return _x;
+  }
+  public double y() {
+    return _y;
+  }
+  public double z() {
+    return _z;
+  }
+  public double magnitude() {
+    return Math.sqrt(_x*_x + _y*_y + _z*_z);
+  }
+  public double magnitudeSquared() {
+    return _x*_x + _y*_y + _z*_z;
+  }
+  public double[] v() {
+    return new double[] { _x, _y, _z };
+  }
+  
+// -- Overriding Object :  -----------------------------------------------------
+
+  public boolean equals(Object obj) {
+    if (obj instanceof Hep3Vector) {
+      Hep3Vector that = (Hep3Vector) obj;
+      return _x == that.x() && _y == that.y() && _z == that.z();
+    } else {
+      return false;
+    }
+  }
+  
+  public String toString() {
+    return VecOp.toString(this);
+  }
+  
+  public int hashCode() {
+    return (int) (Double.doubleToLongBits(_x) + Double.doubleToLongBits(_y) + Double.doubleToLongBits(_z));
+  }
+  
+// -- Private parts :  ---------------------------------------------------------
+  
+  double _x, _y, _z;
+}

lcsim/src/org/lcsim/contrib/onoprien/crux/util
ConstList.java removed after 1.2
diff -N ConstList.java
--- ConstList.java	4 Apr 2008 18:29:02 -0000	1.2
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1,395 +0,0 @@
-package org.lcsim.contrib.onoprien.crux.util;
-
-import java.util.*;
-
-/**
- * Immutable list backed by the list supplied to the constructor.
- * Useful for passing the original list to client code without copying it, when the
- * client should not be able to modify the list, or when the client expects 
- * <tt>List&lt;E&gt;</tt> but the original list is of type <tt>List&lt;<i>Subclass of</i> E&gt;</tt>.
- * <p>
- * An attempt to modify a list of this type will result in <tt>UnsupportedOperationException</tt>.
- * The <tt>ConstList</tt> object is backed by the list that was supplied to its constructor, 
- * so changes in the original list are reflected in the <tt>ConstList</tt>.
- *
- * @author D. Onoprienko
- * @version $Id: ConstList.java,v 1.2 2008/04/04 18:29:02 onoprien Exp $
- */
-public class ConstList<E> implements List<E> {
-  
-// -- Constructors :  ----------------------------------------------------------
-  
-  public ConstList(List<? extends E> list) {
-    _list = list;
-  }
-  
-// -- Implementing List :  -----------------------------------------------------
-  
-  /**
-   * Returns the number of elements in this list.  If this list contains
-   * more than <tt>Integer.MAX_VALUE</tt> elements, returns
-   * <tt>Integer.MAX_VALUE</tt>.
-   *
-   * @return the number of elements in this list
-   */
-  public int size() {return _list.size();}
-  
-  /**
-   * Returns <tt>true</tt> if this list contains no elements.
-   *
-   * @return <tt>true</tt> if this list contains no elements
-   */
-  public boolean isEmpty() {return _list.isEmpty();}
-  
-  /**
-   * Returns <tt>true</tt> if this list contains the specified element.
-   * More formally, returns <tt>true</tt> if and only if this list contains
-   * at least one element <tt>e</tt> such that
-   * <tt>(o==null&nbsp;?&nbsp;e==null&nbsp;:&nbsp;o.equals(e))</tt>.
-   *
-   * @param o element whose presence in this list is to be tested
-   * @return <tt>true</tt> if this list contains the specified element
-   * @throws ClassCastException if the type of the specified element
-   *         is incompatible with this list (optional)
-   * @throws NullPointerException if the specified element is null and this
-   *         list does not permit null elements (optional)
-   */
-  public boolean contains(Object o) {return _list.contains(o);}
-  
-  /**
-   * Returns an iterator over the elements in this list in proper sequence.
-   *
-   * @return an iterator over the elements in this list in proper sequence
-   */
-  public Iterator<E> iterator() {return listIterator(0);}
-  
-  /**
-   * Returns an array containing all of the elements in this list in proper
-   * sequence (from first to last element).
-   *
-   * <p>The returned array will be "safe" in that no references to it are
-   * maintained by this list.  (In other words, this method must
-   * allocate a new array even if this list is backed by an array).
-   * The caller is thus free to modify the returned array.
-   *
-   * <p>This method acts as bridge between array-based and collection-based
-   * APIs.
-   *
-   * @return an array containing all of the elements in this list in proper
-   *         sequence
-   * @see Arrays#asList(Object[])
-   */
-  public Object[] toArray() {return _list.toArray();}
-  
-  /**
-   * Returns an array containing all of the elements in this list in
-   * proper sequence (from first to last element); the runtime type of
-   * the returned array is that of the specified array.  If the list fits
-   * in the specified array, it is returned therein.  Otherwise, a new
-   * array is allocated with the runtime type of the specified array and
-   * the size of this list.
-   *
-   * <p>If the list fits in the specified array with room to spare (i.e.,
-   * the array has more elements than the list), the element in the array
-   * immediately following the end of the list is set to <tt>null</tt>.
-   * (This is useful in determining the length of the list <i>only</i> if
-   * the caller knows that the list does not contain any null elements.)
-   *
-   * <p>Like the {@link #toArray()} method, this method acts as bridge between
-   * array-based and collection-based APIs.  Further, this method allows
-   * precise control over the runtime type of the output array, and may,
-   * under certain circumstances, be used to save allocation costs.
-   *
-   * <p>Suppose <tt>x</tt> is a list known to contain only strings.
-   * The following code can be used to dump the list into a newly
-   * allocated array of <tt>String</tt>:
-   *
-   * <pre>
-   *     String[] y = x.toArray(new String[0]);</pre>
-   *
-   * Note that <tt>toArray(new Object[0])</tt> is identical in function to
-   * <tt>toArray()</tt>.
-   *
-   * @param a the array into which the elements of this list are to
-   *          be stored, if it is big enough; otherwise, a new array of the
-   *          same runtime type is allocated for this purpose.
-   * @return an array containing the elements of this list
-   * @throws ArrayStoreException if the runtime type of the specified array
-   *         is not a supertype of the runtime type of every element in
-   *         this list
-   * @throws NullPointerException if the specified array is null
-   */
-  public <T> T[] toArray(T[] a) {return _list.toArray(a);}
-  
-  
-  // Modification Operations
-  
-  /**
-   * Unsupported optional operation.
-   *
-   * @throws UnsupportedOperationException.
-   */
-  public boolean add(E e) {throw new UnsupportedOperationException();}
-  
-  /**
-   * Unsupported optional operation.
-   *
-   * @throws UnsupportedOperationException.
-   */
-  public boolean remove(Object o) {throw new UnsupportedOperationException();}
-  
-  
-  // Bulk Modification Operations
-  
-  /**
-   * Returns <tt>true</tt> if this list contains all of the elements of the
-   * specified collection.
-   *
-   * @param  c collection to be checked for containment in this list
-   * @return <tt>true</tt> if this list contains all of the elements of the
-   *         specified collection
-   * @throws ClassCastException if the types of one or more elements
-   *         in the specified collection are incompatible with this
-   *         list (optional)
-   * @throws NullPointerException if the specified collection contains one
-   *         or more null elements and this list does not permit null
-   *         elements (optional), or if the specified collection is null
-   * @see #contains(Object)
-   */
-  public boolean containsAll(Collection<?> c) {return _list.containsAll(c);}
-  
-  /**
-   * Unsupported optional operation.
-   *
-   * @throws UnsupportedOperationException.
-   */
-  public boolean addAll(Collection<? extends E> c) {throw new UnsupportedOperationException();}
-  
-  /**
-   * Unsupported optional operation.
-   *
-   * @throws UnsupportedOperationException.
-   */
-  public boolean addAll(int index, Collection<? extends E> c) {throw new UnsupportedOperationException();}
-  
-  /**
-   * Unsupported optional operation.
-   *
-   * @throws UnsupportedOperationException.
-   */
-  public boolean removeAll(Collection<?> c) {throw new UnsupportedOperationException();}
-  
-  /**
-   * Unsupported optional operation.
-   *
-   * @throws UnsupportedOperationException.
-   */
-  public boolean retainAll(Collection<?> c) {throw new UnsupportedOperationException();}
-  
-  /**
-   * Unsupported optional operation.
-   *
-   * @throws UnsupportedOperationException.
-   */
-  public void clear() {throw new UnsupportedOperationException();}
-  
-  
-  // Comparison and hashing
-  
-  /**
-   * Compares the specified object with this list for equality.  Returns
-   * <tt>true</tt> if and only if the specified object is also a list, both
-   * lists have the same size, and all corresponding pairs of elements in
-   * the two lists are <i>equal</i>.  (Two elements <tt>e1</tt> and
-   * <tt>e2</tt> are <i>equal</i> if <tt>(e1==null ? e2==null :
-   * e1.equals(e2))</tt>.)  In other words, two lists are defined to be
-   * equal if they contain the same elements in the same order.  This
-   * definition ensures that the equals method works properly across
-   * different implementations of the <tt>List</tt> interface.
-   *
-   * @param o the object to be compared for equality with this list
-   * @return <tt>true</tt> if the specified object is equal to this list
-   */
-  public boolean equals(Object o) {return _list.equals(o);}
-  
-  /**
-   * Returns the hash code value for this list.  The hash code of a list
-   * is defined to be the result of the following calculation:
-   * <pre>
-   *  int hashCode = 1;
-   *  Iterator&lt;E&gt; i = list.iterator();
-   *  while (i.hasNext()) {
-   *      E obj = i.next();
-   *      hashCode = 31*hashCode + (obj==null ? 0 : obj.hashCode());
-   *  }
-   * </pre>
-   * This ensures that <tt>list1.equals(list2)</tt> implies that
-   * <tt>list1.hashCode()==list2.hashCode()</tt> for any two lists,
-   * <tt>list1</tt> and <tt>list2</tt>, as required by the general
-   * contract of {@link Object#hashCode}.
-   *
-   * @return the hash code value for this list
-   * @see Object#equals(Object)
-   * @see #equals(Object)
-   */
-  public int hashCode() {return _list.hashCode();}
-  
-  
-  // Positional Access Operations
-  
-  /**
-   * Returns the element at the specified position in this list.
-   *
-   * @param index index of the element to return
-   * @return the element at the specified position in this list
-   * @throws IndexOutOfBoundsException if the index is out of range
-   *         (<tt>index &lt; 0 || index &gt;= size()</tt>)
-   */
-  public E get(int index) {return _list.get(index);}
-  
-  /**
-   * Unsupported optional operation.
-   *
-   * @throws UnsupportedOperationException.
-   */
-  public E set(int index, E element) {throw new UnsupportedOperationException();}
-  
-  /**
-   * Unsupported optional operation.
-   *
-   * @throws UnsupportedOperationException.
-   */
-  public void add(int index, E element) {throw new UnsupportedOperationException();}
-  
-  /**
-   * Unsupported optional operation.
-   *
-   * @throws UnsupportedOperationException.
-   */
-  public E remove(int index) {throw new UnsupportedOperationException();}
-  
-  
-  // Search Operations
-  
-  /**
-   * Returns the index of the first occurrence of the specified element
-   * in this list, or -1 if this list does not contain the element.
-   * More formally, returns the lowest index <tt>i</tt> such that
-   * <tt>(o==null&nbsp;?&nbsp;get(i)==null&nbsp;:&nbsp;o.equals(get(i)))</tt>,
-   * or -1 if there is no such index.
-   *
-   * @param o element to search for
-   * @return the index of the first occurrence of the specified element in
-   *         this list, or -1 if this list does not contain the element
-   * @throws ClassCastException if the type of the specified element
-   *         is incompatible with this list (optional)
-   * @throws NullPointerException if the specified element is null and this
-   *         list does not permit null elements (optional)
-   */
-  public int indexOf(Object o) {return _list.indexOf(o);}
-  
-  /**
-   * Returns the index of the last occurrence of the specified element
-   * in this list, or -1 if this list does not contain the element.
-   * More formally, returns the highest index <tt>i</tt> such that
-   * <tt>(o==null&nbsp;?&nbsp;get(i)==null&nbsp;:&nbsp;o.equals(get(i)))</tt>,
-   * or -1 if there is no such index.
-   *
-   * @param o element to search for
-   * @return the index of the last occurrence of the specified element in
-   *         this list, or -1 if this list does not contain the element
-   * @throws ClassCastException if the type of the specified element
-   *         is incompatible with this list (optional)
-   * @throws NullPointerException if the specified element is null and this
-   *         list does not permit null elements (optional)
-   */
-  public int lastIndexOf(Object o) {return _list.lastIndexOf(o);}
-  
-  
-  // List Iterators
-  
-  /**
-   * Returns a list iterator over the elements in this list (in proper
-   * sequence).
-   *
-   * @return a list iterator over the elements in this list (in proper
-   *         sequence)
-   */
-  public ListIterator<E> listIterator() {return listIterator(0);}
-  
-  /**
-   * Returns a list iterator of the elements in this list (in proper
-   * sequence), starting at the specified position in this list.
-   * The specified index indicates the first element that would be
-   * returned by an initial call to {@link ListIterator#next next}.
-   * An initial call to {@link ListIterator#previous previous} would
-   * return the element with the specified index minus one.
-   *
-   * @param index index of first element to be returned from the
-   *              list iterator (by a call to the <tt>next</tt> method)
-   * @return a list iterator of the elements in this list (in proper
-   *         sequence), starting at the specified position in this list
-   * @throws IndexOutOfBoundsException if the index is out of range
-   *         (<tt>index &lt; 0 || index &gt; size()</tt>)
-   */
-  public ListIterator<E> listIterator(int index) {return new ListItr(_list.listIterator(index));}
-  
-  // View
-  
-  /**
-   * Returns a view of the portion of this list between the specified
-   * <tt>fromIndex</tt>, inclusive, and <tt>toIndex</tt>, exclusive.  (If
-   * <tt>fromIndex</tt> and <tt>toIndex</tt> are equal, the returned list is
-   * empty.)  The returned list is backed by this list, so non-structural
-   * changes in the returned list are reflected in this list, and vice-versa.
-   * The returned list supports all of the optional list operations supported
-   * by this list.<p>
-   *
-   * This method eliminates the need for explicit range operations (of
-   * the sort that commonly exist for arrays).   Any operation that expects
-   * a list can be used as a range operation by passing a subList view
-   * instead of a whole list.  For example, the following idiom
-   * removes a range of elements from a list:
-   * <pre>
-   *      list.subList(from, to).clear();
-   * </pre>
-   * Similar idioms may be constructed for <tt>indexOf</tt> and
-   * <tt>lastIndexOf</tt>, and all of the algorithms in the
-   * <tt>Collections</tt> class can be applied to a subList.<p>
-   *
-   * The semantics of the list returned by this method become undefined if
-   * the backing list (i.e., this list) is <i>structurally modified</i> in
-   * any way other than via the returned list.  (Structural modifications are
-   * those that change the size of this list, or otherwise perturb it in such
-   * a fashion that iterations in progress may yield incorrect results.)
-   *
-   * @param fromIndex low endpoint (inclusive) of the subList
-   * @param toIndex high endpoint (exclusive) of the subList
-   * @return a view of the specified range within this list
-   * @throws IndexOutOfBoundsException for an illegal endpoint index value
-   *         (<tt>fromIndex &lt; 0 || toIndex &gt; size ||
-   *         fromIndex &gt; toIndex</tt>)
-   */
-  public List<E> subList(int fromIndex, int toIndex) {return new ConstList(_list.subList(fromIndex, toIndex));}
-  
-// -- Private parts :  ---------------------------------------------------------
-  
-  protected List<? extends E> _list;
-  
-// -- ListIterator class :  ----------------------------------------------------
-  
-  private class ListItr implements ListIterator<E> {
-    ListItr(ListIterator<? extends E> itr) {_itr = itr;}
-    public void add(E e) {throw new UnsupportedOperationException();}
-    public boolean hasNext() {return _itr.hasNext();}
-    public boolean hasPrevious() {return _itr.hasPrevious();}
-    public int nextIndex() {return _itr.nextIndex();}
-    public E next() {return _itr.next();}
-    public E previous() {return _itr.previous();}
-    public int previousIndex() {return _itr.previousIndex();}
-    public void remove() {throw new UnsupportedOperationException();}
-    public void set(E e) {throw new UnsupportedOperationException();}
-    private ListIterator<? extends E> _itr;
-  }
-  
-}
CVSspam 0.2.8