Author: [log in to unmask] Date: Mon Jan 5 19:06:11 2015 New Revision: 1876 Log: Add some more clustering utility methods. Modified: java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/ClusterUtilities.java Modified: java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/ClusterUtilities.java ============================================================================= --- java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/ClusterUtilities.java (original) +++ java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/ClusterUtilities.java Mon Jan 5 19:06:11 2015 @@ -11,6 +11,8 @@ import org.lcsim.event.CalorimeterHit; import org.lcsim.event.Cluster; +import org.lcsim.event.MCParticle; +import org.lcsim.event.SimCalorimeterHit; import org.lcsim.event.base.BaseCluster; import org.lcsim.geometry.subdetector.HPSEcal3; @@ -20,7 +22,6 @@ * @see org.lcsim.event.Cluster * @see org.lcsim.event.base.BaseCluster */ -// TODO: Add method to get MCParticles (see getUniqueMCParticles from BaseCluster). public final class ClusterUtilities { private ClusterUtilities() { @@ -62,18 +63,14 @@ */ public static Cluster createBasicCluster(List<CalorimeterHit> clusterHits) { BaseCluster cluster = new BaseCluster(); - double totalEnergy = 0; for (CalorimeterHit clusterHit : clusterHits) { cluster.addHit(clusterHit); - totalEnergy += clusterHit.getCorrectedEnergy(); - } - cluster.setEnergy(totalEnergy); + } return cluster; } /** - * Compute the raw energy of a cluster which is just the - * sum of all its hit energies. + * Compute the raw energy of a cluster which is just the sum of all its hit energies. * @param cluster The input cluster. * @return The total raw energy. */ @@ -90,7 +87,7 @@ * @param cluster The input cluster. * @return The hit with the highest energy value. */ - public static CalorimeterHit getHighestEnergyHit(Cluster cluster) { + public static CalorimeterHit findHighestEnergyHit(Cluster cluster) { if (cluster.getCalorimeterHits().size() == 1) { return cluster.getCalorimeterHits().get(0); } @@ -104,6 +101,7 @@ /** * Sort the hits in the cluster using a <code>Comparator</code>. * This method will not change the hits in place. It returns a new list. + * The algorithm does not disambiguate between hits with equal energies. * @param cluster The input cluster. * @param comparator The Comparator to use for sorting. * @param reverseOrder True to use reverse rather than default ordering. @@ -117,5 +115,87 @@ } Collections.sort(sortedHits, sortComparator); return sortedHits; - } + } + + /** + * Find hits in a Cluster that are not shared with other Clusters. + * @param cluster The input cluster. + * @param clusters The list of clusters. + * @return The list of unshared hits. + */ + public static List<CalorimeterHit> findUnsharedHits(Cluster cluster, List<Cluster> clusters) { + Set<CalorimeterHit> allHits = new HashSet<CalorimeterHit>(); + List<CalorimeterHit> unsharedHits = new ArrayList<CalorimeterHit>(); + for (Cluster otherCluster : clusters) { + if (otherCluster != cluster) { + allHits.addAll(otherCluster.getCalorimeterHits()); + } + } + for (CalorimeterHit clusterHit : cluster.getCalorimeterHits()) { + if (!allHits.contains(clusterHit)) { + unsharedHits.add(clusterHit); + } + } + return unsharedHits; + } + + /** + * Find the seed hit of a Cluster, without any disambiguation when + * energy is equal. + * @param cluster The input Cluster. + * @return The seed hit. + */ + public CalorimeterHit findSeedHit(Cluster cluster) { + if (cluster.getSize() == 0) { + // There are no hits! + return null; + } else if (cluster.getSize() == 1) { + // There is a single hit. + return cluster.getCalorimeterHits().get(0); + } else { + // Sort hits and return one with highest energy. + return findHighestEnergyHit(cluster); + } + } + + /** + * Find the unique set of MCParticles that are referenced by the + * hits of the Cluster. + * @param clusters The input Cluster. + * @return The set of unique MCParticles. + */ + public static Set<MCParticle> findMCParticles(List<Cluster> clusters) { + Set<MCParticle> particles = new HashSet<MCParticle>(); + for (Cluster cluster : clusters) { + for (CalorimeterHit hit : cluster.getCalorimeterHits()) { + if (hit instanceof SimCalorimeterHit) { + SimCalorimeterHit simHit = (SimCalorimeterHit)hit; + for (int i = 0; i < simHit.getMCParticleCount(); i++) { + particles.add(simHit.getMCParticle(i)); + } + } + } + } + return particles; + } + + /** + * Find CalorimeterHits that are not present in a collection of Clusters. + * @param clusters The input Clusters. + * @param hits The input Calorimeter hits. + * @return The list of CalorimeterHits that were not clustered. + */ + public static List<CalorimeterHit> findRejectedHits(List<Cluster> clusters, List<CalorimeterHit> hits) { + List<CalorimeterHit> rejectedHits = new ArrayList<CalorimeterHit>(); + Set<CalorimeterHit> clusterHits = new HashSet<CalorimeterHit>(); + for (Cluster cluster : clusters) { + clusterHits.addAll(cluster.getCalorimeterHits()); + } + for (CalorimeterHit hit : hits) { + if (!clusterHits.contains(hit)) { + rejectedHits.add(hit); + } + } + return rejectedHits; + } }