Print

Print


Commit in lcsim/src/org/lcsim/contrib/onoprien/crux on MAIN
algorithms/ClusteringDriver.java+3-31.7 -> 1.8
algorithms/rosary/RosaryClusterer.java+3-31.6 -> 1.7
auxdrivers/HitMapFilterDriver.java+136-1581.6 -> 1.7
infrastructure/CruxHitFilter.java+13-81.2 -> 1.3
              /CruxHitMap.java+221-771.6 -> 1.7
+376-249
5 modified files
Made CruxHitMap implement List for event display compatibility.
Added functionality to HitMapFilterDriver.

lcsim/src/org/lcsim/contrib/onoprien/crux/algorithms
ClusteringDriver.java 1.7 -> 1.8
diff -u -r1.7 -r1.8
--- ClusteringDriver.java	2 Dec 2008 23:56:08 -0000	1.7
+++ ClusteringDriver.java	9 Dec 2008 23:15:57 -0000	1.8
@@ -22,7 +22,7 @@
  * input hit map from the event, 
  *
  * @author D. Onoprienko
- * @version $Id: ClusteringDriver.java,v 1.7 2008/12/02 23:56:08 onoprien Exp $
+ * @version $Id: ClusteringDriver.java,v 1.8 2008/12/09 23:15:57 onoprien Exp $
  */
 public class ClusteringDriver extends Driver {
   
@@ -91,7 +91,7 @@
     for (int out=0; out<_filters.size(); out++) {
       
       CruxHitFilter filter = _filters.get(out);
-      CruxHitMap filteredMap = (filter == null) ? inMap : inMap.getMap(filter);
+      CruxHitMap filteredMap = (filter == null) ? inMap : inMap.toMap(filter);
       List<Cluster> clusterList;
       if (filteredMap.isEmpty()) {
         clusterList = new ArrayList<Cluster>(0);
@@ -100,7 +100,7 @@
         CruxManager cruxMan = CruxManager.defaultInstance();
         List<CalModule> modules = cruxMan.getGeometry().getModules();
         for (CalModule module : modules) {
-          CruxHitMap moduleMap = filteredMap.getMap(module);
+          CruxHitMap moduleMap = filteredMap.toMap(module);
           if (! moduleMap.isEmpty()) clusterList.addAll(_clusterers.get(out).createClusters(moduleMap));
         }
       } else {

lcsim/src/org/lcsim/contrib/onoprien/crux/algorithms/rosary
RosaryClusterer.java 1.6 -> 1.7
diff -u -r1.6 -r1.7
--- RosaryClusterer.java	2 Dec 2008 23:56:08 -0000	1.6
+++ RosaryClusterer.java	9 Dec 2008 23:15:57 -0000	1.7
@@ -29,7 +29,7 @@
  *
  *
  * @author D. Onoprienko
- * @version $Id: RosaryClusterer.java,v 1.6 2008/12/02 23:56:08 onoprien Exp $
+ * @version $Id: RosaryClusterer.java,v 1.7 2008/12/09 23:15:57 onoprien Exp $
  */
 public class RosaryClusterer extends Driver implements Clusterer, JobEventListener {
 
@@ -108,13 +108,13 @@
   
   public List<Cluster> createClusters(Map<Long,CalorimeterHit> map) {
     
-    CruxHitMap hitMap = (map instanceof CruxHitMap) ? (CruxHitMap)map : new CruxHitMap(map);
+    CruxHitMap hitMap = new CruxHitMap(map);
     _layers = LayerStore.buildStorage(_geom);
     
     // Find Dots and Beads in all layers :
     
     for (LayerStore store : _layers) {
-      CruxHitMap layerMap = hitMap.getMap(store.cruxLayer);
+      CruxHitMap layerMap = hitMap.toMap(store.cruxLayer);
       _dotBeadFinder.findDotsAndBeads(layerMap, store.dots, store.beads);
     }
 

lcsim/src/org/lcsim/contrib/onoprien/crux/auxdrivers
HitMapFilterDriver.java 1.6 -> 1.7
diff -u -r1.6 -r1.7
--- HitMapFilterDriver.java	7 Dec 2008 23:58:45 -0000	1.6
+++ HitMapFilterDriver.java	9 Dec 2008 23:15:57 -0000	1.7
@@ -5,6 +5,7 @@
 
 import org.lcsim.event.CalorimeterHit;
 import org.lcsim.event.EventHeader;
+import org.lcsim.util.hitmap.HitMap;
 
 import org.lcsim.contrib.onoprien.util.job.Driver;
 
@@ -25,14 +26,13 @@
  * used by the filter to look up hits by their <tt>CellID</tt>.
  *
  * @author D. Onoprienko
- * @version $Id: HitMapFilterDriver.java,v 1.6 2008/12/07 23:58:45 onoprien Exp $
+ * @version $Id: HitMapFilterDriver.java,v 1.7 2008/12/09 23:15:57 onoprien Exp $
  */
 public class HitMapFilterDriver extends Driver {
   
 // -- Constructors :  ----------------------------------------------------------
   
   public HitMapFilterDriver() {
-    set("LOG_LEVEL", Level.ALL);
   }
   
 // -- Setters :  ---------------------------------------------------------------
@@ -41,31 +41,31 @@
    * Set any parameter. 
    * The following parameters can be set with this method:
    * <p><dl>
-   * <dt>"INPUT"</dt> <dd>Names of input collections of {@link CalorimeterHit} objects.<br>
+   * <dt>"INPUT"</dt> <dd>Names of input collections or maps of {@link CalorimeterHit} objects.<br>
    *         Several input sources can be combined by calling this method several times, or
-   *         by providing several names in a single call.
-   *         Every input object fetched by this driver from the event record should by an
-   *         instance of either <tt>Map&lt;Long,CalorimeterHit&gt;</tt> or
-   *         <tt>Collection&lt;CalorimeterHit&gt;</tt>. If a collection with the given name 
+   *         by providing several names in a single call. If a collection with the given name 
    *         is not present in the event record, it is assumed to be empty and ignored.</dd>
-   * <dt>"EXCLUDE"</dt> <dd>Names of {@link CalorimeterHit} collections that need to be subtracted
+   * <dt>"EXCLUDE"</dt> <dd>Names of {@link CalorimeterHit} collections or maps that need to be subtracted
    *         from the input collections. Hits present in these collections will not be included into
-   *         the output collections whether or not they pass the filters. Objects fetched by
-   *         this driver from the event record using these names should be instances of either
-   *         <tt>Map&lt;Long,CalorimeterHit&gt;</tt> or <tt>Collection&lt;CalorimeterHit&gt;</tt>.
-   *         Several collections can be excluded either by calling this method several times,
+   *         the output collections whether or not they pass the filters. If a collection with the given name 
+   *         is not present in the event record, it is assumed to be empty and ignored.
+   *         Several collections can be excluded by calling this method several times,
    *         or by providing several names in a single call.</dd>
    * <dt>"OUTPUT"</dt> <dd>The first value is the name under which the output collection should 
-   *         be saved into the event record.<br> The second value is the {@link CruxHitFilter} object 
-   *         to be used for filtering - only hits that pass the filter will be added to this
-   *         output collection.<br>
-   *         The third value is either "MAP" or "LIST", depending on whether the output 
-   *         should be a {@link CruxHitMap} or an <tt>ArrayList&lt;CalorimeterHit&gt;</tt>.<br>
-   *         Filter and/or output type arguments can be omitted (no filtering and "MAP" output are assumed).<br>
+   *         be saved into the event record. If the collection with this name already exists,
+   *         its contents will be added to the output collection without any filtering.<br>
+   *         The second (optional) value is the {@link CruxHitFilter} object - only hits that 
+   *         pass the filter will be added to this output collection. If this parameter
+   *         is omitted, no filtering is applied.<br>
+   *         The third (optional) value is a <tt>String</tt> that defines the type of output
+   *         collection (can be "CruxHitMap", "ArrayList", "Map", "HitMap"). If this parameter
+   *         is omitted, "CruxHitMap" is assumed.<br>
    *         Several output collections can be created, each with its own filter, by calling
    *         this method repeatedly.</dd>
-   * <dt>"ID_TO_HIT_MAP"</dt> <dd>Name of the map (of type <tt>Map&lt;Long,CalorimeterHit&gt;</tt>)
-   *         to be fetched from the event record and assigned to filters before event processing.
+   * <dt>"ID_TO_HIT_MAP"</dt> <dd>Name of the map (of type <tt>Map&lt;Long,CalorimeterHit&gt;</tt>
+   *         or {@link CruxHitMap}) to be fetched from the event record and assigned to filters 
+   *         before event processing. Only filters that did not have a map previously assigned to
+   *         them will be affected.
    *         <br>Default: <tt>null</tt> (input map being filtered is to be used).</dd></dl>
    * 
    * @param name   Name of parameter to be set. Case is ignored.
@@ -89,40 +89,30 @@
         _excludeNames.trimToSize();
       } else if (name.equalsIgnoreCase("OUTPUT")) {
         if (values.length > 3 || values.length < 1) throw new IllegalArgumentException(ERR_INV + name);
-        _outNames.add((String)(values[0]));
-        if (values.length > 1) {
-          if (values[1] instanceof CruxHitFilter) {
-            _filters.add((CruxHitFilter)(values[1]));
-            if (values.length > 2) {
-              String type = (String)(values[2]);
-              if (type.equalsIgnoreCase("MAP")) {
-                _isMap.add(true);
-              } else if (type.equalsIgnoreCase("LIST")) {
-                _isMap.add(false);
-              } else {
-                throw new IllegalArgumentException(ERR_IV + name);
-              }
-            } else {
-              _isMap.add(true);
-            }
-          } else {
-            _filters.add(CruxHitFilter.ALL);
-            String type = (String)(values[1]);
-            if (type.equalsIgnoreCase("MAP")) {
-              _isMap.add(true);
-            } else if (type.equalsIgnoreCase("LIST")) {
-              _isMap.add(false);
+        _outNames.add((String)(values[0])); _outNames.trimToSize();
+        CruxHitFilter filter = CruxHitFilter.ALL;
+        String type = CHM;
+        for (int i=1; i<values.length; i++) {
+          Object v = values[i];
+          if (v instanceof CruxHitFilter) {
+            filter = (CruxHitFilter)v;
+          } else if (v instanceof String) {
+            type = (String)v;
+            if (type.equalsIgnoreCase(CHM)) {
+              type = CHM;
+            } else if (type.equalsIgnoreCase(AL)) {
+              type = AL;
+            } else if (type.equalsIgnoreCase(HM)) {
+              type = HM;
+            } else if (type.equalsIgnoreCase(M)) {
+              type = M;
             } else {
               throw new IllegalArgumentException(ERR_IV + name);
             }
           }
-        } else {
-          _filters.add(CruxHitFilter.ALL);
-          _isMap.add(true);
         }
-        _outNames.trimToSize();
-        _filters.trimToSize();
-        _isMap.trimToSize();
+        _filters.add(filter); _filters.trimToSize();
+        _types.add(type); _types.trimToSize();
       } else if (name.equalsIgnoreCase("ID_TO_HIT_MAP")) {
         _defMapName = (String) value;
       } else {
@@ -140,129 +130,118 @@
     
     super.process(event);
     
-    // Create lists for output collections
-
-    int nOut = _filters.size();
-    if (nOut == 0) {
-      log("No output collections specified", Level.WARNING);
-      return;
-    }
-    ArrayList<HashSet<CalorimeterHit>> outSets = new ArrayList<HashSet<CalorimeterHit>>(nOut);
-    for (int i=0; i<nOut; i++) outSets.add(new HashSet<CalorimeterHit>(1000));
-    
-    // Fetch default hit map and assign it to filters
+    // Create collection of collections of input hits :
     
-    Map<Long, CalorimeterHit> defMap = null;
-    if (_defMapName != null) {
-      defMap = (Map<Long, CalorimeterHit>) event.get(_defMapName);
-      for (CruxHitFilter filter : _filters) {
-        filter.setHitMap(defMap);
-      }
+    ArrayList<Collection<CalorimeterHit>> input = new ArrayList<Collection<CalorimeterHit>>(_inNames.size());
+    for (String name : _inNames) {
+      try {
+        Object col = event.get(name);
+        if (col instanceof Collection) {
+          input.add((Collection<CalorimeterHit>)col);
+        } else if (col instanceof Map) {
+          input.add(((Map<Long,CalorimeterHit>)col).values());
+        } else {
+          throw new IllegalArgumentException();
+        }
+      } catch (IllegalArgumentException x) {}
     }
     
     // Compile a set of hits to exclude 
     
-    HashSet<CalorimeterHit> excludeSet = null;
-    if (! _excludeNames.isEmpty()) {
+    Set<CalorimeterHit> excludeSet;
+    if (_excludeNames.isEmpty()) {
+      excludeSet = Collections.<CalorimeterHit>emptySet();
+    } else {
       excludeSet = new HashSet<CalorimeterHit>(200);
       for (String name : _excludeNames) {
-        Object ob;
         try {
-          ob = event.get(name);
+          Object o = event.get(name);
+          if (o instanceof Collection) {
+            excludeSet.addAll((Collection<CalorimeterHit>)o);
+          } else if (o instanceof Map) {
+            excludeSet.addAll(((Map<Long,CalorimeterHit>)o).values());
+          }
         } catch (IllegalArgumentException x) {break;}
-        try {
-          Map<Long, CalorimeterHit> map = (Map<Long, CalorimeterHit>) ob;
-          excludeSet.addAll(map.values());
-        } catch (ClassCastException x) {
-          Collection<CalorimeterHit> col = (Collection<CalorimeterHit>) ob;
-          excludeSet.addAll(col);
-        }
       }
     }
+
+    // Fetch default hit map and assign it to filters
     
-    // Process input collections
-    
-    int nIn = _inNames.size();
-    if (nIn == 0) log("No input collection specified", Level.WARNING);
+    int nOut = _filters.size();
+    boolean[] mapChanged = new boolean[nOut];
+    if (_defMapName != null) {
+      Map<Long, CalorimeterHit> defMap;
+      Object map = event.get(_defMapName);
+      if (map instanceof Map) {
+        defMap = (Map<Long, CalorimeterHit>) map;
+      } else if (map instanceof CruxHitMap) {
+        defMap = ((CruxHitMap)map).asMap();
+      } else {
+        throw new IllegalArgumentException();
+      }
+      for (int i=0; i<nOut; i++) {
+        CruxHitFilter filter = _filters.get(i);
+        if (filter != CruxHitFilter.ALL && filter.getHitMap() == null) {
+          filter.setHitMap(defMap);
+          mapChanged[i] = true;
+        } else {
+          mapChanged[i] = false;
+        }
+      }
+    }
+
+    // Create CruxHitMaps for output collections
     
-    ArrayList<Collection<CalorimeterHit>> inCollections = new ArrayList<Collection<CalorimeterHit>>(nIn);
-    ArrayList<Map<Long, CalorimeterHit>> inMaps = new ArrayList<Map<Long, CalorimeterHit>>(nIn);
-    Object[] inputs = new Object[nIn];
-    for (int in=0; in<nIn; in++) {
-      Object ob;
+    ArrayList<CruxHitMap> outMaps = new ArrayList<CruxHitMap>(nOut);
+    for (int i=0; i<nOut; i++) {
       try {
-        ob = event.get(_inNames.get(in));
-      } catch (IllegalArgumentException x) {break;}
-      Collection<CalorimeterHit> inCol;
-      boolean isMap;
-      try {
-        Map<Long, CalorimeterHit> map = (Map<Long, CalorimeterHit>) ob;
-        inCol = map.values();
-        isMap = true;
-        if (defMap == null) {
-          for (CruxHitFilter filter : _filters) filter.setHitMap(map);
-        }
-      } catch (ClassCastException x) {
-        try {
-          inCol = (Collection<CalorimeterHit>) ob;
-          isMap = false;
-        } catch (ClassCastException xx) {
-          throw new RuntimeException("Input collection of incompatible type");
+        Object o = event.get(_outNames.get(i));
+        if (o instanceof CruxHitMap) {
+          outMaps.add((CruxHitMap)o);
+        } else if (o instanceof Collection) {
+          outMaps.add(new CruxHitMap((Collection<CalorimeterHit>)o));
+        } else if (o instanceof Map) {
+          outMaps.add(new CruxHitMap(((Map<Long,CalorimeterHit>)o).values()));
         }
+      } catch (IllegalArgumentException x) {
+        outMaps.add(new CruxHitMap());
       }
-      for (CalorimeterHit hit : inCol) {
-        if (excludeSet == null || (! excludeSet.contains(hit))) {
-          for (int out=0; out<nOut; out++) {
-            CruxHitFilter filter = _filters.get(out);
-            boolean accept = (filter == null) ? true : filter.pass(hit);
-            if (accept) outSets.get(out).add(hit);
+    }
+    
+    // Do filtering
+    
+    for (Collection<CalorimeterHit> col : input) {
+      for (CalorimeterHit hit : col) {
+        if (! excludeSet.contains(hit)) {
+          for (int i=0; i<nOut; i++) {
+            if (_filters.get(i).pass(hit)) outMaps.get(i).add(hit);
           }
         }
       }
     }
     
+    // Reset hit maps associated with filters if necessary
+    
+    if (_defMapName != null) {
+      for (int i=0; i<nOut; i++) {
+        if (mapChanged[i]) _filters.get(i).setHitMap(null);
+      }
+    }
+    
     // Save output collections
-
-    for (int out=0; out<_filters.size(); out++) {
-      CruxHitFilter filter = _filters.get(out);
-      if (filter != null) filter.setHitMap(null);
-      HashSet<CalorimeterHit> outSet = outSets.get(out);
-      Object old = null;
-      try {
-        old = event.get(_outNames.get(out));
-      } catch (IllegalArgumentException x) {}
-      if (_isMap.get(out)) {
-        CruxHitMap outMap;
-        if (old == null) {
-          outMap = new CruxHitMap( (int) (1.5 * outSet.size()) );
-        } else {
-          try {
-            outMap = (CruxHitMap) old;
-          } catch (ClassCastException x) {
-            try {
-              Map<Long, CalorimeterHit> oldMap = (Map<Long, CalorimeterHit>) old;
-              outMap = new CruxHitMap(oldMap);
-            } catch (ClassCastException xx) {
-              throw new IllegalArgumentException("Requested output type is inconsistent with identically named existing collection", xx);
-            }
-          }
-        }
-        outMap.add(outSet);
-        event.put(_outNames.get(out), outMap);
-        log("Saved hit map "+ _outNames.get(out) +" with "+ outMap.values().size() +" hits", Level.FINER);
-      } else {
-        if (old != null) {
-          try {
-            Collection<CalorimeterHit> oldList = (Collection<CalorimeterHit>) old;
-            outSet.addAll(oldList);
-          } catch (ClassCastException xx) {
-            throw new IllegalArgumentException(_err1, xx);
-          }
-        }
-        ArrayList<CalorimeterHit> outputList = new ArrayList<CalorimeterHit>(outSet);
-        event.put(_outNames.get(out), outputList, CalorimeterHit.class, 0);
-        log("Saved hit list "+ _outNames.get(out) +" with "+ outputList.size() +" hits", Level.FINER);
+    
+    for (int i=0; i<nOut; i++) {
+      String type = _types.get(i);
+      if (type == CHM) {
+        event.put(_outNames.get(i), outMaps.get(i), CalorimeterHit.class, 0);
+      } else if (type == HM) {
+        event.put(_outNames.get(i), new HitMap(outMaps.get(i).asMap()));
+      } else if (type == AL) {
+        event.put(_outNames.get(i), new ArrayList(outMaps.get(i)), CalorimeterHit.class, 0);
+      } else if (type == M) {
+        event.put(_outNames.get(i), outMaps.get(i).asMap());
       }
+      log("Saved "+ _outNames.get(i) +" with "+ outMaps.size() +" hits as "+ type, Level.FINER);
     }
 
   }
@@ -270,21 +249,20 @@
   
 // -- Private parts :  ---------------------------------------------------------
   
+  static private final String CHM = "CruxHitMap";
+  static private final String HM = "HitMap";
+  static private final String AL = "ArrayList";
+  static private final String M = "Map";
+  
   private ArrayList<String> _inNames = new ArrayList<String>(1);
   
   private ArrayList<String> _excludeNames = new ArrayList<String>(0);
   
-  private ArrayList<CruxHitFilter> _filters = new ArrayList<CruxHitFilter>(0);
-  private ArrayList<String> _outNames = new ArrayList<String>(0);
-  private ArrayList<Boolean> _isMap = new ArrayList<Boolean>(0);
+  private ArrayList<CruxHitFilter> _filters = new ArrayList<CruxHitFilter>(1);
+  private ArrayList<String> _outNames = new ArrayList<String>(1);
+  private ArrayList<String> _types = new ArrayList<String>(1);
   
   private String _defMapName;
   
   private String _err1 = "Requested output type is inconsistent with identically named existing collection";
 }
-
-//* <dt>"CONVERT"</dt> <dd>Boolean value. If <tt>true</tt>, the driver will check whether
-//   *         the {@link CalorimeterHit} objects in input collections are instances of
-//   *         {@link CruxCalHit}, and if not, convert them to {@link CruxCalHit} before
-//   *         adding to output collections.
-//   *         <br>Default: <tt>false</tt>.</dd>

lcsim/src/org/lcsim/contrib/onoprien/crux/infrastructure
CruxHitFilter.java 1.2 -> 1.3
diff -u -r1.2 -r1.3
--- CruxHitFilter.java	7 Dec 2008 23:58:46 -0000	1.2
+++ CruxHitFilter.java	9 Dec 2008 23:15:57 -0000	1.3
@@ -14,37 +14,41 @@
  * with this filter through a call to <tt>setHitMap</tt>.
  *
  * @author D. Onoprienko
- * @version $Id: CruxHitFilter.java,v 1.2 2008/12/07 23:58:46 onoprien Exp $
+ * @version $Id: CruxHitFilter.java,v 1.3 2008/12/09 23:15:57 onoprien Exp $
  */
 abstract public class CruxHitFilter {
   
 // -- Private parts :  ---------------------------------------------------------
 
-  protected Map<Long, CalorimeterHit> _hitMap;
+  protected Map<Long,CalorimeterHit> _hitMap;
+
   
 // -- Constructors :  ----------------------------------------------------------
   
   public CruxHitFilter() {
   }
+
   
 // -- Setters :  ---------------------------------------------------------------
   
   /**
    * Set a mapping of <tt>CellIDs</tt> to hits that may be used by this filter.
    */
-  public void setHitMap(Map<Long, CalorimeterHit> hitMap) {
+  public void setHitMap(Map<Long,CalorimeterHit> hitMap) {
     _hitMap = hitMap;
   }
+
   
 // -- Getters :  ---------------------------------------------------------------
   
   /**
-   * Returns a map of <tt>CellIDs</tt> to hits that has been associated with this filter.
+   * Returns a map of <tt>CellIDs</tt> to hits used by this filter.
    */
-  public Map<Long, CalorimeterHit> getHitMap() {
-    return(_hitMap);
+  public Map<Long,CalorimeterHit> getHitMap() {
+    return _hitMap;
   }
-    
+
+  
 // -- Filtering :  -------------------------------------------------------------
   
   /**
@@ -74,7 +78,8 @@
   public boolean pass(CalorimeterHit hit) {
     return pass(hit.getCellID());
   }
-  
+
+
 // -- Pass-all filter :  -------------------------------------------------------
   
   /** Filter that passes all hits. */

lcsim/src/org/lcsim/contrib/onoprien/crux/infrastructure
CruxHitMap.java 1.6 -> 1.7
diff -u -r1.6 -r1.7
--- CruxHitMap.java	6 Dec 2008 21:53:29 -0000	1.6
+++ CruxHitMap.java	9 Dec 2008 23:15:57 -0000	1.7
@@ -1,154 +1,298 @@
 package org.lcsim.contrib.onoprien.crux.infrastructure;
 
 import java.util.*;
-import org.lcsim.contrib.onoprien.crux.CruxManager;
+
+import org.lcsim.event.CalorimeterHit;
+import org.lcsim.util.hitmap.HitMap;
+
+import org.lcsim.contrib.onoprien.util.job.JobManager;
+
 import org.lcsim.contrib.onoprien.crux.geom.CalLayer;
 import org.lcsim.contrib.onoprien.crux.geom.CalModule;
 import org.lcsim.contrib.onoprien.crux.geom.CalGeometry;
 
-import org.lcsim.event.CalorimeterHit;
 
 /**
- * Mapping of CellID to CalorimeterHits.
- * // FIXME: need to structure by module to speed up access
+ * Class to hold a collection of CalorimeterHits.
+ * The class provides both sequential access to the hits and mapping from <tt>CellID</tt>
+ * to a hit.
+ * <p>
+ * Note that while this class implements <tt>List</tt> interface in order to allow hit
+ * visualization with Wired event display through Jas3 plugin, it does not support all
+ * <tt>List</tt> operations. All methods that take or return an index of an element are
+ * disabled (will throw <tt>UnsupportedOperationException</tt>), and the class's 
+ * <tt>ListIterator</tt> supports only operations of basic <tt>Iterator</tt>. Only one 
+ * copy of each hit is held, no matter how many times it is added to this collection.
  *
  * @author D. Onoprienko
- * @version $Id: CruxHitMap.java,v 1.6 2008/12/06 21:53:29 onoprien Exp $
+ * @version $Id: CruxHitMap.java,v 1.7 2008/12/09 23:15:57 onoprien Exp $
  */
-public class CruxHitMap extends org.lcsim.util.hitmap.HitMap {
+final public class CruxHitMap implements List<CalorimeterHit> {
+  
+// -- Private parts :  ---------------------------------------------------------
+  
+  final private LinkedHashMap<Long, CalorimeterHit> _map;
   
 // -- Constructors and initialization :  ---------------------------------------
   
   /** Default constructor. */
   public CruxHitMap() {
-    super();
-    init();
+    _map = new LinkedHashMap<Long, CalorimeterHit>();
   }
   
   /** Constructs an empty <tt>CruxHitMap</tt> with the specified initial capacity and the default load factor (0.75). */
   public CruxHitMap(int initialCapacity) {
-    super(initialCapacity);
-    init();
+    _map = new LinkedHashMap<Long, CalorimeterHit>(initialCapacity);
   }
   
   /** Copy constructor. */
   public CruxHitMap(CruxHitMap map) {
-    super(map);
-    init();
+    _map = new LinkedHashMap<Long, CalorimeterHit>(map.asMap());
   }
   
   /** Construct from a generic Map<Long,CalorimeterHit> */
   public CruxHitMap(Map<Long,CalorimeterHit> map) {
-    super(map);
-    init();
+    _map = new LinkedHashMap<Long, CalorimeterHit>(map);
   }
   
   /** Construct from a generic Map<Long,CalorimeterHit> */
   public CruxHitMap(Collection<CalorimeterHit> hits) {
-    super((int) (hits.size()*1.5));
-    init();
-    add(hits);
+    _map = new LinkedHashMap<Long, CalorimeterHit>((int)(hits.size()*1.5));
+    addAll(hits);
   }
+
+  
+// -- Implementing Map :  ------------------------------------------------------
+
+  public int size() {return _map.size();}
+
+  public boolean isEmpty() {return _map.isEmpty();}
+
+  public boolean containsKey(Object key) {return _map.containsKey(key);}
+
+  public boolean containsValue(Object value) {return _map.containsValue(value);}
+
+  public CalorimeterHit get(Object key) {return _map.get(key);}
+
+  public CalorimeterHit put(Long key, CalorimeterHit value) {return _map.put(key,value);}
+
+  public void putAll(Map<? extends Long, ? extends CalorimeterHit> m) {_map.putAll(m);}
+
+  public void clear() {_map.clear();}
+
+  public Set<Long> keySet() {return _map.keySet();}
+
+  public Collection<CalorimeterHit> values() {return _map.values();}
+
+  public Set<Map.Entry<Long, CalorimeterHit>> entrySet() {return _map.entrySet();}
+
+  public boolean equals(Object o) {return _map.equals(o);}
+
+  public int hashCode() {return _map.hashCode();}
   
-  private void init() {
-    _geom = CruxManager.defaultInstance().getGeometry();
+  
+// -- Implementing List :  -----------------------------------------------------
+
+  public boolean contains(Object o) {return _map.containsValue(o);}
+
+  public Iterator<CalorimeterHit> iterator() {return _map.values().iterator();}
+
+  public Object[] toArray() {return _map.values().toArray();}
+
+  public <T> T[] toArray(T[] a) {return _map.values().toArray(a);}
+
+  public boolean add(CalorimeterHit hit) {
+    return (_map.put(hit.getCellID(), hit) == null);
+  }
+
+  public boolean remove(Object o) {
+    return (_map.remove(o) != null);
+  }
+
+  public boolean containsAll(Collection<?> c) {return _map.values().containsAll(c);}
+
+  public boolean addAll(Collection<? extends CalorimeterHit> c) {
+    boolean changed = false;
+    for (CalorimeterHit hit : c) changed = (_map.put(hit.getCellID(), hit) != null) || changed;
+    return changed;
+  }
+
+  public boolean addAll(int index, Collection<? extends CalorimeterHit> c) {throw new UnsupportedOperationException();}
+
+  public boolean removeAll(Collection<?> c) {
+    return _map.values().removeAll(c);
+  }
+
+  public boolean retainAll(Collection<?> c) {
+    return _map.values().retainAll(c);
+  }
+
+  public CalorimeterHit get(int index) {throw new UnsupportedOperationException();}
+
+  public CalorimeterHit set(int index, CalorimeterHit element) {throw new UnsupportedOperationException();}
+
+  public void add(int index, CalorimeterHit element) {throw new UnsupportedOperationException();}
+
+  public CalorimeterHit remove(int index) {throw new UnsupportedOperationException();}
+
+  public int indexOf(Object o) {throw new UnsupportedOperationException();}
+
+  public int lastIndexOf(Object o) {throw new UnsupportedOperationException();}
+
+  public ListIterator<CalorimeterHit> listIterator() {
+    return new LstItr();
   }
+
+  public ListIterator<CalorimeterHit> listIterator(int index) {throw new UnsupportedOperationException();}
+
+  public List<CalorimeterHit> subList(int fromIndex, int toIndex) {throw new UnsupportedOperationException();}
+
   
+// -- Views :  -----------------------------------------------------------------
+  
+  /**
+   * Returns a map view of this <tt>CruxHitMap</tt>.
+   * The map is backed by the <tt>CruxHitMap</tt>, so changes to the map are reflected 
+   * in the <tt>CruxHitMap</tt>, and vice-versa.
+   * <p>
+   * Since <tt>CruxHitMap</tt> itself supports all <tt>Map</tt> operations, the only 
+   * purpose of this view is to allow passing <tt>CruxHitMap</tt> to
+   * methods expecting <tt>Map</tt> argument.
+   */
+  public Map<Long, CalorimeterHit> asMap() {
+    return _map;
+  }
+
 // -- Sub-collections :  -------------------------------------------------------
   
-  public ArrayList<CalorimeterHit> getList(CruxHitFilter filter) {
+  /**
+   * Returns a list of hits from this <tt>CruxHitMap</tt> that pass the specified filter.
+   * The returned list is not backed by this <tt>CruxHitMap</tt> and can be modified independently.
+   */
+  public ArrayList<CalorimeterHit> toList(CruxHitFilter filter) {
     ArrayList<CalorimeterHit> out = new ArrayList<CalorimeterHit>(size());
-    if (filter == null) {
-      out.addAll(values());
-    } else {
-      filter.setHitMap(this);
-      for (CalorimeterHit hit : values()) {
-        if (filter.pass(hit)) out.add(hit);
-      }
-      filter.setHitMap(null);
+    boolean noMap = (filter.getHitMap() == null);
+    if (noMap) filter.setHitMap(_map);
+    for (CalorimeterHit hit : values()) {
+      if (filter.pass(hit)) out.add(hit);
     }
+    if (noMap) filter.setHitMap(null);
     return out;
   }
  
-  public CruxHitMap getMap(CruxHitFilter filter) {
-    ArrayList<CalorimeterHit> hits = getList(filter);
+  /**
+   * Returns a new <tt>CruxHitMap</tt> containing only those hits from this <tt>CruxHitMap</tt>
+   * that pass the specified filter.
+   */
+  public CruxHitMap toMap(CruxHitFilter filter) {
+    ArrayList<CalorimeterHit> hits = toList(filter);
     CruxHitMap out = new CruxHitMap((int)(hits.size()*1.5));
-    for (CalorimeterHit hit : hits) {
-      out.add(hit);
-    }
+    out.addAll(hits);
     return out;
   }
   
-  public ArrayList<CalorimeterHit> getList(final CalModule module) {
+  /**
+   * Returns a list of hits from this <tt>CruxHitMap</tt> that belong to the specified module.
+   * The returned list is not backed by this <tt>CruxHitMap</tt> and can be modified independently.
+   */
+  public ArrayList<CalorimeterHit> toList(CalModule module) {
+    final CalModule mod = module;
+    final CalGeometry geom = JobManager.defaultInstance().get(CalGeometry.class);
     CruxHitFilter filter = new CruxHitFilter() {
       public boolean pass(CalorimeterHit hit) {
-        return (module == _geom.getModule(hit));
+        return (mod == geom.getModule(hit));
       }
     };
-    return getList(filter);
+    return toList(filter);
   }
   
-  public CruxHitMap getMap(CalModule module) {
-    ArrayList<CalorimeterHit> hits = getList(module);
+  /**
+   * Returns a new <tt>CruxHitMap</tt> containing only those hits from this <tt>CruxHitMap</tt>
+   * that belong to the specified module.
+   */
+  public CruxHitMap toMap(CalModule module) {
+    ArrayList<CalorimeterHit> hits = toList(module);
     CruxHitMap out = new CruxHitMap((int)(hits.size()*1.5));
-    for (CalorimeterHit hit : hits) {
-      out.add(hit);
-    }
+    out.addAll(hits);
     return out;
   }
   
-  public ArrayList<CalorimeterHit> getList(final CalModule module, final int layer) {
+  /**
+   * Returns a list of hits from this <tt>CruxHitMap</tt> that belong to the specified module and layer.
+   * The returned list is not backed by this <tt>CruxHitMap</tt> and can be modified independently.
+   *
+   * @param  module  Calorimeter module.
+   * @param  layer   Calorimeter layer number as reported by <tt>IDDecoder</tt>.
+   */
+  public ArrayList<CalorimeterHit> toList(CalModule module, int layer) {
+    final CalModule mod = module;
+    final int lay = layer;
+    final CalGeometry geom = JobManager.defaultInstance().get(CalGeometry.class);
     CruxHitFilter filter = new CruxHitFilter() {
       public boolean pass(CalorimeterHit hit) {
-        return (module == _geom.getModule(hit) && layer == hit.getIDDecoder().getLayer());
+        return (mod == geom.getModule(hit) && lay == hit.getIDDecoder().getLayer());
       }
     };
-    return getList(filter);
+    return toList(filter);
   }
   
-  public CruxHitMap getMap(CalModule module, int layer) {
-    ArrayList<CalorimeterHit> hits = getList(module, layer);
+  /**
+   * Returns a new <tt>CruxHitMap</tt> containing only those hits from this <tt>CruxHitMap</tt>
+   * that belong to the specified module and layer.
+   *
+   * @param  module  Calorimeter module.
+   * @param  layer   Calorimeter layer number as reported by <tt>IDDecoder</tt>.
+   */
+  public CruxHitMap toMap(CalModule module, int layer) {
+    ArrayList<CalorimeterHit> hits = toList(module, layer);
     CruxHitMap out = new CruxHitMap((int)(hits.size()*1.5));
-    for (CalorimeterHit hit : hits) {
-      out.add(hit);
-    }
+    out.addAll(hits);
     return out;
   }
   
-  public ArrayList<CalorimeterHit> getList(final CalLayer layer) {
-    CruxHitFilter filter = new CruxHitFilter() {
-      public boolean pass(CalorimeterHit hit) {
-        return (layer.getModule() == _geom.getModule(hit) && layer.getLayerNumber() == hit.getIDDecoder().getLayer());
-      }
-    };
-    return getList(filter);
+  /**
+   * Returns a list of hits from this <tt>CruxHitMap</tt> that belong to the specified calorimeter layer.
+   * The returned list is not backed by this <tt>CruxHitMap</tt> and can be modified independently.
+   */
+  public ArrayList<CalorimeterHit> toList(CalLayer layer) {
+    return toList(layer.getModule(), layer.getLayerNumber());
   }
   
-  public CruxHitMap getMap(CalLayer layer) {
-    ArrayList<CalorimeterHit> hits = getList(layer);
+  /**
+   * Returns a new <tt>CruxHitMap</tt> containing only those hits from this <tt>CruxHitMap</tt>
+   * that belong to the specified calorimeter layer.
+   */
+  public CruxHitMap toMap(CalLayer layer) {
+    ArrayList<CalorimeterHit> hits = toList(layer);
     CruxHitMap out = new CruxHitMap((int)(hits.size()*1.5));
-    for (CalorimeterHit hit : hits) {
-      out.add(hit);
-    }
+    out.addAll(hits);
     return out;
   }
+
+
+// -- ListIterator implementation :  -------------------------------------------
   
-// -- Modify map :  ------------------------------------------------------------
-  
-  public void add(Collection<CalorimeterHit> hitList) {
-    for (CalorimeterHit hit : hitList) put(hit.getCellID(), hit);
-  }
-  
-  public void add(Map<Long,CalorimeterHit> hitMap) {
-    for (CalorimeterHit hit : hitMap.values()) put(hit.getCellID(), hit);
-  }
-  
-  public void add(CalorimeterHit hit) {
-    put(hit.getCellID(), hit);
+  private final class LstItr implements ListIterator<CalorimeterHit> {
+    
+    Iterator<Map.Entry<Long, CalorimeterHit>> itr = _map.entrySet().iterator();
+    
+    public boolean hasNext() {return itr.hasNext();}
+
+    public CalorimeterHit next() {return itr.next().getValue();}
+
+    public boolean hasPrevious() {throw new UnsupportedOperationException();}
+
+    public CalorimeterHit previous() {throw new UnsupportedOperationException();}
+
+    public int nextIndex() {throw new UnsupportedOperationException();}
+
+    public int previousIndex() {throw new UnsupportedOperationException();}
+
+    public void remove() {itr.remove();}
+
+    public void set(CalorimeterHit e) {throw new UnsupportedOperationException();}
+
+    public void add(CalorimeterHit e) {throw new UnsupportedOperationException();}
   }
   
-// -- Private parts :  ---------------------------------------------------------
-  
-  private CalGeometry _geom;
-  
 }
CVSspam 0.2.8