Author: [log in to unmask] Date: Thu May 28 23:44:54 2015 New Revision: 3057 Log: Updated GTP Monte Carlo drivers to ensure that all cluster hits are properly included in an LCIO event. This prevents null pointer exceptions that can occur when referencing a hit from a different event than the associated cluster. Modified: java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/GTPClusterDriver.java java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/GTPClusterer.java java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/LegacyClusterer.java Modified: java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/GTPClusterDriver.java ============================================================================= --- java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/GTPClusterDriver.java (original) +++ java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/GTPClusterDriver.java Thu May 28 23:44:54 2015 @@ -23,7 +23,7 @@ public GTPClusterDriver() { clusterer = ClustererFactory.create("GTPClusterer"); gtp = (GTPClusterer) clusterer; - setWriteClusterCollection(false); + setWriteClusterCollection(true); } /** @@ -36,7 +36,7 @@ * false</code> that the symmetric window should be used. */ @Deprecated - void setLimitClusterRange(boolean limitClusterRange) { + public void setLimitClusterRange(boolean limitClusterRange) { gtp.setLimitClusterRange(limitClusterRange); } @@ -86,4 +86,14 @@ public void setVerbose(boolean verbose) { gtp.setVerbose(verbose); } + + @Override + public void setWriteClusterCollection(boolean state) { + // Set the flag as appropriate with the superclass. + super.setWriteClusterCollection(state); + + // Also tell the clusterer whether it should persist its hit + // collection or not. + gtp.setWriteHitCollection(state); + } } Modified: java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/GTPClusterer.java ============================================================================= --- java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/GTPClusterer.java (original) +++ java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/GTPClusterer.java Thu May 28 23:44:54 2015 @@ -2,6 +2,7 @@ import java.util.ArrayList; import java.util.HashMap; +import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Map; @@ -33,7 +34,7 @@ * @author Sho Uemura */ public class GTPClusterer extends AbstractClusterer { - + /** * The minimum energy required for a hit to be considered as a * cluster center. Hits with energy less than this value will be @@ -54,7 +55,7 @@ * clustering. */ private LinkedList<Map<Long, CalorimeterHit>> hitBuffer; - + /** * Whether an asymmetric or symmetric window should be used for * adding hits to a cluster. @@ -66,9 +67,19 @@ */ private boolean verbose = false; + /** + * Sets whether the clusterer should store the collection of hits + * that are part of clusters. This needs to be true if the clusters + * are to be written out to LCIO. + */ + private boolean writeHitCollection = true; + + /** + * Instantiates the clusterer. + */ GTPClusterer() { super(new String[] { "seedEnergyThreshold", "clusterWindow" }, new double[] { 0.00, 2.}); - } + } /** * Sets the clustering algorithm parameters. @@ -276,20 +287,45 @@ // Store each hit in a set by its cell ID so that it may be // easily acquired later. HashMap<Long, CalorimeterHit> hitMap = new HashMap<Long, CalorimeterHit>(); - for (CalorimeterHit hit : hits) { + for(CalorimeterHit hit : hits) { hitMap.put(hit.getCellID(), hit); } - + // Remove the last event from the hit buffer and add the new one. hitBuffer.removeLast(); hitBuffer.addFirst(hitMap); - + // Run the clustering algorithm on the buffer. List<Cluster> clusterList = getClusters(); - + + // The MC GTP algorithm collects hits from across events; to be + // stored in LCIO format properly, it needs to separately store + // its clusters' hits in a collection. + if(writeHitCollection) { + // Create a set to store the hits so that each one may be + // stored only once. + Set<CalorimeterHit> hitSet = new HashSet<CalorimeterHit>(); + + // Loop over all clusters and add their hits to the set. + for(Cluster cluster : clusterList) { + for(CalorimeterHit hit : cluster.getCalorimeterHits()) { + hitSet.add(hit); + } + } + + // Convert the set into a List object so that it can be stored + // in LCIO. + List<CalorimeterHit> clusterHits = new ArrayList<CalorimeterHit>(hitSet.size()); + clusterHits.addAll(hitSet); + + // Place the list of hits into the event stream. + event.put("GTPHits", hits, CalorimeterHit.class, 0); + } + + // Return the clusters. return clusterList; } - + /** * Sets the number of clock cycles before and after a given cycle * that will be used when checking whether a given hit is a local @@ -352,6 +388,17 @@ } /** + * Sets whether the set of hits associated with an event's clusters + * should be written to the data stream and persisted in LCIO. This + * must be true if the clusters are to be persisted. + * @param state - <code>true</code> indicates that the hits will be + * persisted and <code>false</code> that they will not. + */ + void setWriteHitCollection(boolean state) { + writeHitCollection = state; + } + + /** * Indicates the type of cluster that is generated by this algorithm. * @return Returns the type of cluster as a <code>ClusterType</code> * object, specifically, <code>ClusterType.GTP</code>. @@ -359,5 +406,5 @@ @Override public ClusterType getClusterType() { return ClusterType.GTP; - } + } } Modified: java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/LegacyClusterer.java ============================================================================= --- java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/LegacyClusterer.java (original) +++ java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/LegacyClusterer.java Thu May 28 23:44:54 2015 @@ -5,7 +5,6 @@ import java.util.Map; import java.util.Set; -import org.hps.recon.ecal.EcalUtils; import org.lcsim.event.CalorimeterHit; import org.lcsim.event.Cluster; import org.lcsim.event.EventHeader;