java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal
--- java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/EcalClusterIC.java 2014-05-24 00:20:02 UTC (rev 634)
+++ java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/EcalClusterIC.java 2014-05-25 22:00:58 UTC (rev 635)
@@ -1,4 +1,4 @@
-package org.hps.recon.ecal;
+package main.java.org.hps.recon.ecal;
import java.io.FileWriter;
import java.io.IOException;
@@ -6,6 +6,7 @@
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -21,251 +22,406 @@
/**
* This Driver creates clusters from the CalorimeterHits of an
* {@link org.lcsim.geometry.subdetectur.HPSEcal3} detector.
+ *
+ * This clustering logic is based on that from the CLAS-Note-2005-001.
+ * This sorts hits from highest to lowest energy and build clusters around
+ * each local maximum/seed hit. Common hits are distributed between clusters
+ * when minimum between two clusters. There is a threshold cut for minimum
+ * hit energy, minimum cluster energy, and minimum seed hit energy. There is
+ * also a timing threshold with respect to the seed hit. All of these parameters
+ * are tunable and should be refined with more analysis.
*
*
- * @author Holly Szumila-Vance <h[log in to unmask]>
+ * @author Holly Szumila-Vance <h[log in to unmask]>
+ * @author Kyle McCarty <[log in to unmask]>
*
*/
public class EcalClusterIC extends Driver {
-
+ // File writer to output cluster results.
FileWriter writeHits;
- HPSEcal3 ecal;
+ // LCIO collection name for calorimeter hits.
String ecalCollectionName;
+ // Name of the calorimeter detector object.
String ecalName = "Ecal";
+ // LCIO cluster collection name to which to write.
String clusterCollectionName = "EcalClusters";
+ // File path to which to write event display output.
+ String outfile = "cluster-hit-IC.txt";
// Map of crystals to their neighbors.
NeighborMap neighborMap = null;
- //Minimum energy that counts as hit
- double Emin = 0.001;
-
- public EcalClusterIC() {
- }
-
+ // Minimum energy threshold for hits; lower energy hits will be
+ // excluded from clustering. Units in GeV.
+ double hitEnergyThreshold = 0.0075;
+ // Minimum energy threshold for seed hits; if seed hit is below
+ // cluster is excluded from output. Units in GeV.
+ double seedEnergyThreshold = 0.2;
+ // Minimum energy threshold for cluster hits; if total cluster
+ // energy is below, the cluster is excluded. Units in GeV.
+ double clusterEnergyThreshold = 0.4;
+ // A Comparator that sorts CalorimeterHit objects from highest to
+ // lowest energy.
+ private static final EnergyComparator ENERGY_COMP = new EnergyComparator();
+ // Track the event number for the purpose of outputting to event
+ // display format.
+ private int eventNum = -1;
+ // Apply time cut to hits
+ boolean timeCut = false;
+ // Minimum time cut window range. Units in ns.
+ double minTime = 0.0;
+ // Maximum time cut window range. Units in ns.
+ double timeWindow = 20.0;
+
+
public void setClusterCollectionName(String clusterCollectionName) {
this.clusterCollectionName = clusterCollectionName;
}
-
+
public void setEcalCollectionName(String ecalCollectionName) {
this.ecalCollectionName = ecalCollectionName;
}
-
+
public void setEcalName(String ecalName) {
this.ecalName = ecalName;
}
+
+ /**
+ * Minimum energy for a hit to be used in a cluster. Default of 0.0075 GeV
+ *
+ * @param hitEnergyThreshold
+ */
+ public void sethitEnergyThreshold(double hitEnergyThreshold) {
+ this.hitEnergyThreshold = hitEnergyThreshold;
+ }
+ /**
+ * Minimum energy for a seed hit. Default of 0.2 GeV
+ *
+ * @param seedEnergyThreshold
+ */
+ public void setseedEnergyThreshold(double seedEnergyThreshold) {
+ this.seedEnergyThreshold = seedEnergyThreshold;
+ }
+
+ /**
+ * Minimum energy for a cluster. Default of 0.4 GeV
+ *
+ * @param clusterEnergyThreshold
+ */
+ public void setclusterEnergyThreshold(double clusterEnergyThreshold) {
+ this.clusterEnergyThreshold = clusterEnergyThreshold;
+ }
+
+ /**
+ * Apply time cuts to hits. Defaults to false.
+ *
+ * @param timeCut
+ */
+ public void setTimeCut(boolean timeCut) {
+ this.timeCut = timeCut;
+ }
+
+ /**
+ * Minimum hit time, if timeCut is true. Default of 0 ns.
+ *
+ * @param minTime
+ */
+ public void setMinTime(double minTime) {
+ this.minTime = minTime;
+ }
+
+ /**
+ * Width of time window, if timeCut is true. Default of 20 ns.
+ *
+ * @param timeWindow
+ */
+ public void setTimeWindow(double timeWindow) {
+ this.timeWindow = timeWindow;
+ }
+
+
public void startOfData() {
+ // Make sure that the calorimeter hit collection name is defined.
if (ecalCollectionName == null) {
throw new RuntimeException("The parameter ecalCollectionName was not set!");
}
-
+
+ // Make sure the name of calorimeter detector is defined.
if (ecalName == null) {
throw new RuntimeException("The parameter ecalName was not set!");
}
-
+
+ // Create a file writer and clear the output file, if it exists.
try {
- writeHits = new FileWriter("cluster-hit-IC.txt");
+ writeHits = new FileWriter(outfile);
writeHits.write("");
- } catch (IOException e) {
- };
+ }
+ catch(IOException e) { }
}
public void detectorChanged(Detector detector) {
- // Get the Subdetector.
- ecal = (HPSEcal3) detector.getSubdetector(ecalName);
-
- // Cache ref to neighbor map.
+ // Get the calorimeter.
+ HPSEcal3 ecal = (HPSEcal3) detector.getSubdetector(ecalName);
+
+ // Store the map of neighbor crystals for the current calorimeter set-up.
neighborMap = ecal.getNeighborMap();
}
public void process(EventHeader event) {
-
-
-
+ // Make sure the current event contains calorimeter hits.
if (event.hasCollection(CalorimeterHit.class, ecalCollectionName)) {
- // Get the list of raw ECal hits.
- List<CalorimeterHit> hits = event.get(CalorimeterHit.class, ecalCollectionName);
-
- // Make a hit map for quick lookup by ID.
- Map<Long, CalorimeterHit> hitMap = new HashMap<Long, CalorimeterHit>();
-
- for (CalorimeterHit hit : hits) {
- hitMap.put(hit.getCellID(), hit);
+ // Get the list of raw calorimeter hits.
+ List<CalorimeterHit> hitList = event.get(CalorimeterHit.class, ecalCollectionName);
+
+ // Generate clusters from the calorimeter hits.
+ List<HPSEcalCluster> clusterList = null;
+ try { clusterList = createClusters(hitList); }
+ catch(IOException e) { }
+
+ // If clusters were successfully created, put them in the event.
+ if(clusterList != null) {
+ int flag = 1 << LCIOConstants.CLBIT_HITS;
+ event.put(clusterCollectionName, clusterList, HPSEcalCluster.class, flag);
}
-
- //System.out.println("Number of ECal hits: "+hitMap.size());
-
- // Put Cluster collection into event.
- int flag = 1 << LCIOConstants.CLBIT_HITS;
- try {
-
- event.put(clusterCollectionName, createClusters(hitMap), HPSEcalCluster.class, flag);
- } catch (IOException e) {
- }
}
}
- public List<HPSEcalCluster> createClusters(Map<Long, CalorimeterHit> map) throws IOException {
-
- // New Cluster list to be added to event.
- List<HPSEcalCluster> clusters = new ArrayList<HPSEcalCluster>();
-
- //Create a Calorimeter hit list in each event, then sort with highest energy first
- ArrayList<CalorimeterHit> chitList = new ArrayList<CalorimeterHit>(map.size());
- for (CalorimeterHit h : map.values()) {
- if (h.getCorrectedEnergy() > Emin) {
- chitList.add(h);
- }
-
- Collections.sort(chitList, new EnergyComparator());
+ public List<HPSEcalCluster> createClusters(List<CalorimeterHit> hitList) throws IOException {
+ // Create a list to store the newly created clusters in.
+ ArrayList<HPSEcalCluster> clusterList = new ArrayList<HPSEcalCluster>();
+
+ // Sort the list of hits by energy.
+ Collections.sort(hitList, ENERGY_COMP);
+
+ // Filter the hit list of any hits that fail to pass the
+ // designated threshold.
+ filterLoop:
+ for(int index = hitList.size() - 1; index >= 0; index--) {
+ // If the hit is below threshold or outside of time window, kill it.
+ if((hitList.get(index).getCorrectedEnergy() < hitEnergyThreshold)||
+ (timeCut && (hitList.get(index).getTime() < minTime || hitList.get(index).getTime() > minTime + timeWindow))) {
+ hitList.remove(index);
+ }
+
+ // Since the hits are sorted by energy from highest to
+ // lowest, any hit that is above threshold means that all
+ // subsequent hits will also be above threshold. Continue through
+ // list to check in time window.
+ else { continue; }
}
-
- //New Seed list containing each local maximum energy hit
- List<CalorimeterHit> seedHits = new ArrayList<CalorimeterHit>();
-
- //Create map to contain common hits for evaluation later, key is crystal and values are seed
+
+ // Create a map to connect the cell ID of a calorimeter crystal
+ // to the hit which occurred in that crystal.
+ HashMap<Long, CalorimeterHit> hitMap = new HashMap<Long, CalorimeterHit>();
+ for (CalorimeterHit hit : hitList) { hitMap.put(hit.getCellID(), hit); }
+
+ // Map a crystal to a list of all clusters in which it is a member.
Map<CalorimeterHit, List<CalorimeterHit>> commonHits = new HashMap<CalorimeterHit, List<CalorimeterHit>>();
-
- //Created map to contain seeds with listed hits, key is crystal, and value is seed
- Map<CalorimeterHit, CalorimeterHit> clusterHits = new HashMap<CalorimeterHit, CalorimeterHit>();
-
- //Create map to contain the total energy of each cluster
- Map<CalorimeterHit, Double> seedEnergy = new HashMap<CalorimeterHit, Double>();
-
- //Quick Map to access hits from cell IDs
- Map<Long, CalorimeterHit> hitID = new HashMap<Long, CalorimeterHit>();
-
- //List to contain all hits already put into clusters
- List<CalorimeterHit> clusterHitList = new ArrayList<CalorimeterHit>();
-
- //Fill Map with cell ID and hit
- for (CalorimeterHit hit : chitList) {
- hitID.put(hit.getCellID(), hit);
- }
-
- for (CalorimeterHit hit : chitList) {
- Set<Long> neighbors = neighborMap.get(hit.getCellID()); //get all neighbors of hit
- List<CalorimeterHit> neighborHits = new ArrayList<CalorimeterHit>();
+
+ // Map a crystal to the seed of the cluster of which it is a member.
+ HashMap<CalorimeterHit, CalorimeterHit> hitSeedMap = new HashMap<CalorimeterHit, CalorimeterHit>();
+
+ // Set containing hits immediately around a seed hit.
+ HashSet<CalorimeterHit> surrSeedSet = new HashSet<CalorimeterHit>();
+
+ // Loop through all calorimeter hits to locate seeds and perform
+ // first pass calculations for component and common hits.
+ for (CalorimeterHit hit : hitList) {
+ // Get the set of all neighboring crystals to the current hit.
+ Set<Long> neighbors = neighborMap.get(hit.getCellID());
+
+ // Generate a list to store any neighboring hits in.
+ ArrayList<CalorimeterHit> neighborHits = new ArrayList<CalorimeterHit>();
+
+ // Sort through the set of neighbors and, if a hit exists
+ // which corresponds to a neighbor, add it to the list of
+ // neighboring hits.
for (Long neighbor : neighbors) {
- if (hitID.containsKey(neighbor)) {//map contains (neighbor's cell id, neighbor hit)
- neighborHits.add(hitID.get(neighbor));
- }
+ // Get the neighboring hit.
+ CalorimeterHit neighborHit = hitMap.get(neighbor);
+
+ // If it exists, add it to the list.
+ if(neighborHit != null) { neighborHits.add(neighborHit); }
}
-
- Collections.sort(neighborHits, new EnergyComparator());
-
- boolean highestE = true;
- for (CalorimeterHit neighborHit : neighborHits) {//check for seed hit
- if (hit.getCorrectedEnergy() > neighborHit.getCorrectedEnergy()) {
- continue;
- } else {
- highestE = false;
- break;
- }
+
+ // Track whether the current hit is a seed hit or not.
+ boolean isSeed = true;
+
+ // Loops through all the neighboring hits to determine if
+ // the current hit is the local maximum within its set of
+ // neighboring hits.
+ seedHitLoop:
+ for(CalorimeterHit neighbor : neighborHits) {
+ if(hit.getCorrectedEnergy() <= neighbor.getCorrectedEnergy()) {
+ isSeed = false;
+ break seedHitLoop;
+ }
}
-
- if (highestE == true) {//seed hit, local maximum
- seedHits.add(hit);
- clusterHits.put(hit, hit);
- clusterHitList.add(hit);
- } //not seed hit
+
+ // If this hit is a seed hit, just map it to itself.
+ if (isSeed) { hitSeedMap.put(hit, hit); }
+
+ // If this hit is not a seed hit, see if it should be
+ // attached to any neighboring seed hits.
else {
- //builds immediate clusters around seed hits
+ // Sort through the list of neighboring hits.
for (CalorimeterHit neighborHit : neighborHits) {
- //if neighbor to seed, add to seed
- if (seedHits.contains(neighborHit) && !clusterHits.containsKey(hit)) {
- CalorimeterHit seed = clusterHits.get(neighborHit);
- clusterHits.put(hit, seed);
- clusterHitList.add(hit);
- } //if neighbor to two seeds, add to common hits
- else if (seedHits.contains(neighborHit) && clusterHits.containsKey(hit)) {
- CalorimeterHit prevSeed = clusterHits.get(neighborHit);
- CalorimeterHit currSeed = clusterHits.get(hit);
- List<CalorimeterHit> commonHitList = new ArrayList<CalorimeterHit>();
- commonHitList.add(prevSeed);
- commonHitList.add(currSeed);
- commonHits.put(hit, commonHitList);
- }
+ // Check whether the neighboring hit is a seed.
+ if(hitSeedMap.get(neighborHit) == neighborHit) {
+ // If the neighboring hit is a seed hit and the
+ // current hit has been associated with a cluster,
+ // then it is a common hit between its previous
+ // seed and the neighboring seed.
+ if (hitSeedMap.containsKey(hit)) {
+ // Check and see if a list of common seeds
+ // for this hit already exists or not.
+ List<CalorimeterHit> commonHitList = commonHits.get(hit);
+
+ // If it does not, make a new one.
+ if(commonHitList == null) { commonHitList = new ArrayList<CalorimeterHit>(); }
+
+ // Add the neighbors to the seeds to set of
+ // common seeds.
+ commonHitList.add(neighborHit);
+ commonHitList.add(hitSeedMap.get(hit));
+
+ // Put the common seed list back into the set.
+ commonHits.put(hit, commonHitList);
+ }
+
+ // If the neighboring hit is a seed hit and the
+ // current hit has not been added to a cluster yet
+ // associate it with the neighboring seed and note
+ // that it has been clustered.
+ else {
+ hitSeedMap.put(hit, neighborHit);
+ surrSeedSet.add(hit);
+ }
+ }
}
}
- }
-
- //loop over hit list, find neighbors, compare energies, add to list
- for (CalorimeterHit nHit : chitList) {
- Set<Long> neighbors2 = neighborMap.get(nHit.getCellID()); //get all neighbors of hit
- List<CalorimeterHit> neighborHits2 = new ArrayList<CalorimeterHit>();
- for (Long neighbor : neighbors2) {
- if (hitID.containsKey(neighbor)) {//map contains (neighbor's cell id, neighbor hit)
- if (!clusterHitList.contains(hitID.get(neighbor))) {
- neighborHits2.add(hitID.get(neighbor));
- }
+ } // End primary seed loop.
+
+ // Performs second pass calculations for component hits.
+ secondaryHitsLoop:
+ for (CalorimeterHit secondaryHit : hitList) {
+ // If the secondary hit is not associated with a seed, then
+ // the rest of there is nothing further to be done.
+ if(!hitSeedMap.containsKey(secondaryHit)) { continue secondaryHitsLoop; }
+
+ // Get the secondary hit's neighboring crystals.
+ Set<Long> secondaryNeighbors = neighborMap.get(secondaryHit.getCellID());
+
+ // Make a list to store the hits associated with the
+ // neighboring crystals.
+ List<CalorimeterHit> secondaryNeighborHits = new ArrayList<CalorimeterHit>();
+
+ // Loop through the neighboring crystals.
+ for (Long secondaryNeighbor : secondaryNeighbors) {
+ // Get the hit associated with the neighboring crystal.
+ CalorimeterHit secondaryNeighborHit = hitMap.get(secondaryNeighbor);
+
+ // If the neighboring crystal exists and is not already
+ // in a cluster, add it to the list of neighboring hits.
+ if (secondaryNeighborHit != null && !hitSeedMap.containsKey(secondaryNeighborHit)) { //!clusteredHitSet.contains(secondaryNeighborHit)) {
+ secondaryNeighborHits.add(secondaryNeighborHit);
}
}
-
- Collections.sort(neighborHits2, new EnergyComparator());
- for (CalorimeterHit neighbor : neighborHits2) {
- if (clusterHits.containsKey(nHit) && neighbor.getCorrectedEnergy() < nHit.getCorrectedEnergy()) {
- CalorimeterHit seed = clusterHits.get(nHit);
- clusterHits.put(neighbor, seed);
- clusterHitList.add(neighbor);
- } else {
- continue;
+
+ // Loop over the secondary neighbor hits.
+ for (CalorimeterHit secondaryNeighborHit : secondaryNeighborHits) {
+ // If the neighboring hit is of lower energy than the
+ // current secondary hit, then associate the neighboring
+ // hit with the current secondary hit's seed.
+ if (secondaryNeighborHit.getCorrectedEnergy() < secondaryHit.getCorrectedEnergy()) {
+ hitSeedMap.put(secondaryNeighborHit, hitSeedMap.get(secondaryHit));
}
}
- }
- //loop over cluster hits, compare energies of neighbors with diff seeds, if min->add to commonHits
- for (CalorimeterHit mHit : clusterHitList) {
- //exclude seed hits as possible common hits
- if (clusterHits.get(mHit) != mHit) {
-
- Set<Long> neighbors3 = neighborMap.get(mHit.getCellID()); //get all neighbors of hit
- List<CalorimeterHit> neighborHits3 = new ArrayList<CalorimeterHit>();
- for (Long neighbor : neighbors3) {
- if (hitID.containsKey(neighbor)) {//map contains (neighbor's cell id, neighbor hit)
- neighborHits3.add(hitID.get(neighbor));
-
- }
+ } // End component hits loop.
+
+ // Performs second pass calculations for common hits.
+ commonHitsLoop:
+ for (CalorimeterHit clusteredHit : hitSeedMap.keySet()) {
+ // Seed hits are never common hits and can be skipped.
+ if(hitSeedMap.get(clusteredHit) == clusteredHit || surrSeedSet.contains(clusteredHit)) { continue commonHitsLoop; }
+
+ // Get the current clustered hit's neighboring crystals.
+ Set<Long> clusteredNeighbors = neighborMap.get(clusteredHit.getCellID());
+
+ // Store a list of all the clustered hits neighboring
+ // crystals which themselves contain hits.
+ List<CalorimeterHit> clusteredNeighborHits = new ArrayList<CalorimeterHit>();
+
+ // Loop through the neighbors and see if they have hits.
+ for (Long neighbor : clusteredNeighbors) {
+ // Get the hit associated with the neighbor.
+ CalorimeterHit clusteredNeighborHit = hitMap.get(neighbor);
+
+ // If it exists, add it to the neighboring hit list.
+ if (clusteredNeighborHit != null) {
+ clusteredNeighborHits.add(clusteredNeighborHit);
}
-
- Collections.sort(neighborHits3, new EnergyComparator());
-
- CalorimeterHit compSeed = clusterHits.get(mHit);
- for (CalorimeterHit neighbor : neighborHits3) {
- if (clusterHits.containsKey(neighbor) && clusterHits.get(neighbor) != compSeed) {//borders clusters
- if (mHit.getCorrectedEnergy() < neighbor.getCorrectedEnergy()) {
- //add to common hits,
- List<CalorimeterHit> commonHitList = new ArrayList<CalorimeterHit>();
- commonHitList.add(compSeed);
- commonHitList.add(clusterHits.get(neighbor));
- commonHits.put(mHit, commonHitList);
- }
+ }
+
+ // Get the seed hit associated with this clustered hit.
+ CalorimeterHit clusteredHitSeed = hitSeedMap.get(clusteredHit);
+
+ // Loop over the clustered neighbor hits.
+ for (CalorimeterHit clusteredNeighborHit : clusteredNeighborHits) {
+ // Check to make sure that the clustered neighbor hit
+ // is not already associated with the current clustered
+ // hit's seed.
+ if (hitSeedMap.get(clusteredNeighborHit) != clusteredHitSeed) {
+ if (clusteredHit.getCorrectedEnergy() < clusteredNeighborHit.getCorrectedEnergy()) {
+ // Check and see if a list of common seeds
+ // for this hit already exists or not.
+ List<CalorimeterHit> commonHitList = commonHits.get(clusteredHit);
+
+ // If it does not, make a new one.
+ if(commonHitList == null) { commonHitList = new ArrayList<CalorimeterHit>(); }
+
+ // Add the neighbors to the seeds to set of
+ // common seeds.
+ commonHitList.add(clusteredHitSeed);
+ commonHitList.add(hitSeedMap.get(clusteredNeighborHit));
+
+ // Put the common seed list back into the set.
+ commonHits.put(clusteredHit, commonHitList);
}
}
}
+ } // End common hits loop.
+
+ // Remove any common hits from the clustered hits collection.
+ for(CalorimeterHit commonHit : commonHits.keySet()) {
+ hitSeedMap.remove(commonHit);
}
-
- //remove common hits from cluster hits list
- for (CalorimeterHit commHit : clusterHitList) {
- if (clusterHitList.contains(commHit) && commonHits.containsKey(commHit)) {
- clusterHits.remove(commHit);
- } else {
- continue;
+
+
+
+ /*
+ * All hits are sorted from above. The next part of the code is for calculating energies. Still
+ * needs implementation into new cluster collection so as to preserve shared hit energy
+ * distribution within clusters.
+ */
+
+ //Create map to contain the total energy of each cluster
+ Map<CalorimeterHit, Double> seedEnergy = new HashMap<CalorimeterHit, Double>();
+
+ // Get energy of each cluster, excluding common hits
+ for (CalorimeterHit iSeed : hitList) {
+ if(hitSeedMap.get(iSeed) == iSeed) {
+ seedEnergy.put(iSeed, 0.0);
}
}
-
-
-
- //Get energy of each cluster, excluding common hits
- for (CalorimeterHit iSeed : seedHits) {
- seedEnergy.put(iSeed, 0.0);
- }
+
//Putting total cluster energies excluding common hit energies into map with seed keys
- for (Map.Entry<CalorimeterHit, CalorimeterHit> entry : clusterHits.entrySet()) {
+ for (Map.Entry<CalorimeterHit, CalorimeterHit> entry : hitSeedMap.entrySet()) {
CalorimeterHit eSeed = entry.getValue();
double eEnergy = seedEnergy.get(eSeed);
eEnergy += entry.getKey().getRawEnergy();
seedEnergy.put(eSeed, eEnergy);
}
-
+
//Distribute common hit energies with clusters
Map<CalorimeterHit, Double> seedEnergyTot = seedEnergy;
for (Map.Entry<CalorimeterHit, List<CalorimeterHit>> entry1 : commonHits.entrySet()) {
@@ -273,8 +429,8 @@
List<CalorimeterHit> commSeedList = entry1.getValue();
CalorimeterHit seedA = commSeedList.get(0);
CalorimeterHit seedB = commSeedList.get(1);
- double eFractionA = seedEnergy.get(seedA) / (seedEnergy.get(seedA) + seedEnergy.get(seedB));
- double eFractionB = seedEnergy.get(seedB) / (seedEnergy.get(seedA) + seedEnergy.get(seedB));
+ double eFractionA = seedEnergy.get(seedA)/(seedEnergy.get(seedA)+seedEnergy.get(seedB));
+ double eFractionB = seedEnergy.get(seedB)/(seedEnergy.get(seedA)+seedEnergy.get(seedB));
double currEnergyA = seedEnergyTot.get(seedA);
double currEnergyB = seedEnergyTot.get(seedB);
currEnergyA += eFractionA * commonCell.getCorrectedEnergy();
@@ -283,93 +439,96 @@
seedEnergyTot.put(seedA, currEnergyA);
seedEnergyTot.put(seedB, currEnergyB);
}
-
-
- //Do some system.out for number of crystals in each cluster, energy of each cluster
- for (Map.Entry<CalorimeterHit, Double> entryEnergy : seedEnergyTot.entrySet()) {
- // System.out.println(entryEnergy.getKey().getCellID()+"\t"+entryEnergy.getKey().getCorrectedEnergy()+
- // "\t"+entryEnergy.getValue());
- }
-
- // System.out.println("Number of clusters: "+seedHits.size());
-
-
- /* if (map.size() != 0) {
- writeHits.append("Event" + "\t" + "1" + "\n");
- for (CalorimeterHit n : chitList) {
- writeHits.append("EcalHit" + "\t" + n.getIdentifierFieldValue("ix") + "\t" + n.getIdentifierFieldValue("iy")
- + "\t" + n.getCorrectedEnergy() + "\n");
+
+
+
+
+ /*
+ * Prints the results in event display format. Not analyzed
+ * for efficiency, as this will ultimately not be a part of
+ * the driver and should be handled by the event display output
+ * driver instead.
+ */
+ // Only write to the output file is something actually exists.
+ if (hitMap.size() != 0) {
+ // Increment the event number.
+ eventNum++;
+
+ // Write the event header.
+// writeHits.append(String.format("Event\t%d%n", eventNum));
+
+ // Write the calorimeter hits that passed the energy cut.
+ for (CalorimeterHit n : hitList) {
+ int hix = n.getIdentifierFieldValue("ix");
+ int hiy = n.getIdentifierFieldValue("iy");
+ double energy = n.getCorrectedEnergy();
+// writeHits.append(String.format("EcalHit\t%d\t%d\t%f%n", hix, hiy, energy));
}
-
- for (Map.Entry<CalorimeterHit, CalorimeterHit> entry2 : clusterHits.entrySet()) {
- if (entry2.getKey() == entry2.getValue()) {//seed
- writeHits.append("Cluster" + "\t" + entry2.getKey().getIdentifierFieldValue("ix")
- + "\t" + entry2.getKey().getIdentifierFieldValue("iy") + "\t" + seedEnergyTot.get(entry2.getKey()) + "\n");
-
+
+
+ for (Map.Entry<CalorimeterHit, CalorimeterHit> entry2 : hitSeedMap.entrySet()) {
+ if ((entry2.getKey() == entry2.getValue())&&(entry2.getKey().getCorrectedEnergy()>=seedEnergyThreshold)
+ &&(seedEnergyTot.get(entry2.getKey())>=clusterEnergyThreshold)) {//seed and passes all thresholds
+ int six = entry2.getKey().getIdentifierFieldValue("ix");
+ int siy = entry2.getKey().getIdentifierFieldValue("iy");
+ double energy = seedEnergyTot.get(entry2.getKey());
+// writeHits.append(String.format("Cluster\t%d\t%d\t%f%n", six, siy, energy));
+
HPSEcalCluster cluster = new HPSEcalCluster(entry2.getKey());
cluster.addHit(entry2.getKey());
- for (Map.Entry<CalorimeterHit, CalorimeterHit> entry3 : clusterHits.entrySet()) {
+ for (Map.Entry<CalorimeterHit, CalorimeterHit> entry3 : hitSeedMap.entrySet()) {
if (entry3.getValue() == entry2.getValue()) {
- writeHits.append("CompHit" + "\t" + entry3.getKey().getIdentifierFieldValue("ix") + "\t"
- + entry3.getKey().getIdentifierFieldValue("iy") + "\n");
-
+ int ix = entry3.getKey().getIdentifierFieldValue("ix");
+ int iy = entry3.getKey().getIdentifierFieldValue("iy");
+// writeHits.append(String.format("CompHit\t%d\t%d%n", ix, iy));
+
cluster.addHit(entry3.getKey());
}
}
for (Map.Entry<CalorimeterHit, List<CalorimeterHit>> entry4 : commonHits.entrySet()) {
if (entry4.getValue().contains(entry2.getKey())) {
- writeHits.append("SharHit" + "\t" + entry4.getKey().getIdentifierFieldValue("ix") + "\t"
- + entry4.getKey().getIdentifierFieldValue("iy") + "\n");
-
+ int ix = entry4.getKey().getIdentifierFieldValue("ix");
+ int iy = entry4.getKey().getIdentifierFieldValue("iy");
+// writeHits.append(String.format("SharHit\t%d\t%d%n", ix, iy));
+
cluster.addHit(entry4.getKey());
-
}
}
- clusters.add(cluster);
+ clusterList.add(cluster);
}
}
- writeHits.append("EndEvent\n");
-
- }*/
-
- //Clear all maps for next event iteration
- hitID.clear();
- clusterHits.clear();
- seedHits.clear();
- commonHits.clear();
- chitList.clear();
- seedEnergy.clear();
-
- return clusters;
-
-
-
-
+
+ // Write the event termination header.
+// writeHits.append("EndEvent\n");
+ } //End event display output loop.
+
+
+
+
+
+ // Return the resulting cluster list.
+ return clusterList;
}
-
+
public void endOfData() {
- try {
- writeHits.close();
- } catch (IOException e) {
- }
+ // Close the event display output writer.
+ try { writeHits.close(); }
+ catch (IOException e) { }
}
-
- private class EnergyComparator implements Comparator<CalorimeterHit> {
-
- @Override
+
+ private static class EnergyComparator implements Comparator<CalorimeterHit> {
public int compare(CalorimeterHit o1, CalorimeterHit o2) {
- // TODO Auto-generated method stub
- double diff = o1.getCorrectedEnergy() - o2.getCorrectedEnergy();
- if (diff < 0) {
- return 1;
- }
- if (diff > 0) {
- return -1;
- } else {
- return 0;
- }
+ // If the energies are equivalent, the same, the two hits
+ // are considered equivalent.
+ if(o1.getCorrectedEnergy() == o2.getCorrectedEnergy()) { return 0; }
+
+ // Higher energy hits are ranked higher than lower energy hits.
+ else if(o1.getCorrectedEnergy() > o2.getCorrectedEnergy()) { return -1; }
+
+ // Lower energy hits are ranked lower than higher energy hits.
+ else { return 1; }
}
}
}