Author: [log in to unmask]
Date: Wed Jan 21 17:23:33 2015
New Revision: 1964
Log:
Uploaded correct version of the GTP clustering algorithm.
Modified:
java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/GTPClusterer.java
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 Wed Jan 21 17:23:33 2015
@@ -14,60 +14,66 @@
import org.lcsim.event.base.BaseCluster;
/**
- * Class <code>GTPCalorimeterClusterer</code> processes events and converts hits
- * into clusters, where appropriate. It uses the modified 2014 clustering algorithm.<br/>
+ * Class <code>GTPCalorimeterClusterer</code> processes events and
+ * converts hits into clusters, where appropriate. It uses the modified
+ * 2014 clustering algorithm.<br/>
* <br/>
- * For a hit to be a cluster center, it is required to have an energy above some
- * tunable minimum threshold. Additionally, the hit must be a local maximum with
- * respect to its neighbors and itself over a tunable (default 2) clock cycles.
- * Hits that pass these checks are then required to additional have a total
- * cluster energy that exceeds another tunable minimum threshold.<br/>
+ * For a hit to be a cluster center, it is required to have an energy
+ * above some tunable minimum threshold. Additionally, the hit must be
+ * a local maximum with respect to its neighbors and itself over a tunable
+ * (default 2) clock cycles. Hits that pass these checks are then required
+ * to additional have a total cluster energy that exceeds another tunable
+ * minimum threshold.<br/>
* <br/>
- * A hit is added to a cluster as a component if it has a non-zero energy and
- * within the aforementioned tunable time buffer used for clustering and is
- * either at the same location as the seed hit or is a neighbor to the seed hit.
+ * A hit is added to a cluster as a component if it has a non-zero energy
+ * and within the aforementioned tunable time buffer used for clustering
+ * and is either at the same location as the seed hit or is a neighbor
+ * to the seed hit.
* @author Kyle McCarty
* @author Sho Uemura
*/
public class GTPClusterer extends AbstractClusterer {
/**
- * <b>seedEnergyThreshold</b><br/><br/>
- * <code>private double <b>seedEnergyThreshold</b></code><br/><br/>
- * The minimum energy required for a hit to be considered as a cluster
- * center. Hits with energy less than this value will be ignored.
+ * The minimum energy required for a hit to be considered as a
+ * cluster center. Hits with energy less than this value will be
+ * ignored.
*/
private double seedEnergyThreshold;
/**
- * <b>clusterWindow</b><br/><br/>
- * <code>private int <b>clusterWindow</b></code><br/><br/>
- * Indicates the number of FADC clock cycles (each cycle is 4 ns) before and
- * after a given cycle that should be considered when checking if a cluster
- * is a local maximum in space-time.
+ * Indicates the number of FADC clock cycles (each cycle is 4 ns)
+ * before and after a given cycle that should be considered when
+ * checking if a cluster is a local maximum in space-time.
*/
private int clusterWindow;
/**
- * <b>hitBuffer</b><br/><br/>
- * <code>private LinkedList<List<CalorimeterHit>> <b>hitBuffer</b></code><br/><br/>
- * Stores a set of all the hits occurring in each clock cycle for the number
- * of clock cycles that should be considered for clustering.
+ * Stores a set of all the hits occurring in each clock cycle for
+ * the number of clock cycles that should be considered for
+ * clustering.
*/
private LinkedList<Map<Long, CalorimeterHit>> hitBuffer;
/**
- * <b>limitClusterRange</b><br/><br/>
- * <code>private boolean <b>limitClusterRange</b></code><br/><br/>
* Whether an asymmetric or symmetric window should be used for
* adding hits to a cluster.
*/
private boolean limitClusterRange = false;
+ /**
+ * Sets whether debug text should be written.
+ */
+ private boolean verbose = false;
+
GTPClusterer() {
- super(new String[] { "seedEnergyThreshold", "clusterWindow" }, new double[] { 0.05, 2.});
+ super(new String[] { "seedEnergyThreshold", "clusterWindow" }, new double[] { 0.00, 2.});
}
+ /**
+ * Sets the clustering algorithm parameters.
+ */
+ @Override
public void initialize() {
// Set cuts.
setSeedEnergyThreshold(getCuts().getValue("seedEnergyThreshold"));
@@ -87,10 +93,10 @@
}
/**
- * Generates a list of clusters from the current hit buffer. The "present"
- * event is taken to be the list of hits occurring at index
- * <code>clusterWindow</code>, which is the middle of the buffer.
- *
+ * Generates a list of clusters from the current hit buffer. The
+ * "present" event is taken to be the list of hits occurring at
+ * index <code>clusterWindow</code>, which is the middle of the
+ * buffer.
* @return Returns a <code>List</code> of <code>HPSEcalCluster
* </code> objects generated from the current event.
*/
@@ -101,24 +107,32 @@
// Get the list of hits at the current time in the event buffer.
Map<Long, CalorimeterHit> currentHits = hitBuffer.get(clusterWindow);
- // DEBUG :: Print the cluster window.
- System.out.printf("%n%nEvent:%n");
- int window = (hitBuffer.size() - 1) / 2;
- int bufferNum = 0;
- for(Map<Long, CalorimeterHit> bufferMap : hitBuffer) {
- System.out.printf("Buffer %d:%n", hitBuffer.size() - bufferNum - window - 1);
- CalorimeterHit hit = null;
-
- for(Entry<Long, CalorimeterHit> entry : bufferMap.entrySet()) {
- hit = entry.getValue();
- System.out.printf("\t(%3d, %3d) --> %.4f (%.4f)%n", hit.getIdentifierFieldValue("ix"),
- hit.getIdentifierFieldValue("iy"), hit.getCorrectedEnergy(), hit.getRawEnergy());
- }
-
- bufferNum++;
- }
-
- if(currentHits.isEmpty()) { System.out.println("\tNo hits this event!"); }
+ // VERBOSE :: Print the cluster window.
+ if(verbose) {
+ // Print the event header.
+ System.out.printf("%n%nEvent:%n");
+
+ // Calculate some constants.
+ int window = (hitBuffer.size() - 1) / 2;
+ int bufferNum = 0;
+
+ // Print out all of the hits in the event buffer.
+ for(Map<Long, CalorimeterHit> bufferMap : hitBuffer) {
+ System.out.printf("Buffer %d:%n", hitBuffer.size() - bufferNum - window - 1);
+ CalorimeterHit hit = null;
+
+ for(Entry<Long, CalorimeterHit> entry : bufferMap.entrySet()) {
+ hit = entry.getValue();
+ System.out.printf("\t(%3d, %3d) --> %.4f (%.4f)%n", hit.getIdentifierFieldValue("ix"),
+ hit.getIdentifierFieldValue("iy"), hit.getCorrectedEnergy(), hit.getRawEnergy());
+ }
+
+ bufferNum++;
+ }
+
+ // If there are not hits, indicate this.
+ if(currentHits.isEmpty()) { System.out.println("\tNo hits this event!"); }
+ }
// For a hit to be a cluster center, it must be a local maximum
// both with respect to its neighbors and itself both in the
@@ -128,10 +142,12 @@
// Get the actual hit object.
CalorimeterHit currentHit = currentHits.get(currentID);
- // DEBUG :: Print the current cluster.
- System.out.printf("Cluster Check:%n");
- System.out.printf("\t(%3d, %3d) --> %.4f%n", currentHit.getIdentifierFieldValue("ix"),
- currentHit.getIdentifierFieldValue("iy"), currentHit.getCorrectedEnergy(), currentHit.getRawEnergy());
+ // VERBOSE :: Print the current cluster.
+ if(verbose) {
+ System.out.printf("Cluster Check:%n");
+ System.out.printf("\t(%3d, %3d) --> %.4f%n", currentHit.getIdentifierFieldValue("ix"),
+ currentHit.getIdentifierFieldValue("iy"), currentHit.getCorrectedEnergy(), currentHit.getRawEnergy());
+ }
// Store the energy of the current hit.
double currentEnergy = currentHit.getRawEnergy();
@@ -139,7 +155,13 @@
// If the hit energy is lower than the minimum threshold,
// then we immediately reject this hit as a possible cluster.
if (currentEnergy < seedEnergyThreshold) {
- System.out.printf("\tREJECT :: Does not exceed seed threshold %.4f.%n", seedEnergyThreshold);
+ // VERBOSE :: Note the reason the potential seed was
+ // rejected.
+ if(verbose) {
+ System.out.printf("\tREJECT :: Does not exceed seed threshold %.4f.%n", seedEnergyThreshold);
+ }
+
+ // Skip to the next potential seed.
continue seedLoop;
}
@@ -147,6 +169,8 @@
// starting with the cluster seed candidate.
BaseCluster cluster = createBasicCluster();
cluster.addHit(currentHit);
+ cluster.setPosition(currentHit.getDetectorElement().getGeometry().getPosition().v());
+ cluster.setNeedsPropertyCalculation(false);
// Get the set of neighbors for this hit.
Set<Long> neighbors = neighborMap.get(currentHit.getCellID());
@@ -164,9 +188,16 @@
// is larger than then original hit. If it is, we may
// stop the comparison because this is not a cluster.
if (bufferHitEnergy > currentEnergy) {
- System.out.printf("\tREJECT :: Buffer hit surpasses hit energy.");
- System.out.printf("\tBUFFER HIT :: (%3d, %3d) --> %.4f%n", bufferHit.getIdentifierFieldValue("ix"),
- bufferHit.getIdentifierFieldValue("iy"), bufferHit.getCorrectedEnergy(), bufferHit.getRawEnergy());
+ // VERBOSE :: Output the reason the potential
+ // seed was rejected along with the
+ // hit that caused it.
+ if(verbose) {
+ System.out.printf("\tREJECT :: Buffer hit surpasses hit energy.");
+ System.out.printf("\tBUFFER HIT :: (%3d, %3d) --> %.4f%n", bufferHit.getIdentifierFieldValue("ix"),
+ bufferHit.getIdentifierFieldValue("iy"), bufferHit.getCorrectedEnergy(), bufferHit.getRawEnergy());
+ }
+
+ // Skip to the next potential seed.
continue seedLoop;
}
@@ -192,9 +223,16 @@
// If it is, we may stop the comparison because this
// is not a cluster.
if (neighborHitEnergy > currentEnergy) {
- System.out.printf("\tREJECT :: Buffer hit surpasses hit energy.%n");
- System.out.printf("\tBUFFER HIT :: (%3d, %3d) --> %.4f%n", neighborHit.getIdentifierFieldValue("ix"),
- neighborHit.getIdentifierFieldValue("iy"), neighborHit.getCorrectedEnergy(), neighborHit.getRawEnergy());
+ // VERBOSE :: Output the reason the potential
+ // seed was rejected along with the
+ // hit that caused it.
+ if(verbose) {
+ System.out.printf("\tREJECT :: Buffer hit surpasses hit energy.%n");
+ System.out.printf("\tBUFFER HIT :: (%3d, %3d) --> %.4f%n", neighborHit.getIdentifierFieldValue("ix"),
+ neighborHit.getIdentifierFieldValue("iy"), neighborHit.getCorrectedEnergy(), neighborHit.getRawEnergy());
+ }
+
+ // Skip to the next potential seed.
continue seedLoop;
}
@@ -214,12 +252,15 @@
// Add the cluster to the list of clusters.
clusters.add(cluster);
- System.out.printf("Cluster added.%n");
- System.out.printf("\t(%3d, %3d) --> %.4f GeV --> %d hits%n", cluster.getCalorimeterHits().get(0).getIdentifierFieldValue("ix"),
- cluster.getCalorimeterHits().get(0).getIdentifierFieldValue("iy"), cluster.getEnergy(), cluster.getCalorimeterHits().size());
- for(CalorimeterHit hit : cluster.getCalorimeterHits()) {
- System.out.printf("\t\tCLUSTER HIT :: (%3d, %3d) --> %.4f%n", hit.getIdentifierFieldValue("ix"),
- hit.getIdentifierFieldValue("iy"), hit.getCorrectedEnergy(), hit.getRawEnergy());
+ // VERBOSE :: Output the clusters generated from this event.
+ if(verbose) {
+ System.out.printf("Cluster added.%n");
+ System.out.printf("\t(%3d, %3d) --> %.4f GeV --> %d hits%n", cluster.getCalorimeterHits().get(0).getIdentifierFieldValue("ix"),
+ cluster.getCalorimeterHits().get(0).getIdentifierFieldValue("iy"), cluster.getEnergy(), cluster.getCalorimeterHits().size());
+ for(CalorimeterHit hit : cluster.getCalorimeterHits()) {
+ System.out.printf("\t\tCLUSTER HIT :: (%3d, %3d) --> %.4f%n", hit.getIdentifierFieldValue("ix"),
+ hit.getIdentifierFieldValue("iy"), hit.getCorrectedEnergy(), hit.getRawEnergy());
+ }
}
}
@@ -228,10 +269,9 @@
}
/**
- * Places hits from the current event into the event hit buffer and
- * processes the buffer to extract clusters. Clusters are then stored in the
- * event object.
- *
+ * Places hits from the current event into the event hit buffer
+ * and processes the buffer to extract clusters. Clusters are then
+ * stored in the event object.
* @param event - The event to process.
*/
public List<Cluster> createClusters(EventHeader event, List<CalorimeterHit> hits) {
@@ -253,17 +293,15 @@
}
/**
- * 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 maximum in both time
- * and space. Note that a value of
- * <code>N
- * </code> indicates that
- * <code>N</code> clock cycles before and
- * <code>N</code> clock cycles after will be considered. Thusly, a total of
- * <code>2N + 1</code> clock cycles will be used total.
- *
- * @param clusterWindow - The number of additional clock cycles to include
- * in the clustering checks. A negative value will be treated as zero.
+ * 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
+ * maximum in both time and space. Note that a value of <code>N</code>
+ * indicates that <code>N</code> clock cycles before and
+ * <code>N</code> clock cycles after will be considered. Thusly, a
+ * total of <code>2N + 1</code> clock cycles will be used.
+ * @param clusterWindow - The number of additional clock cycles to
+ * include in the clustering checks. A negative value will be treated
+ * as zero.
*/
void setClusterWindow(int clusterWindow) {
// The cluster window of must always be at least zero.
@@ -281,19 +319,17 @@
* Sets whether hits should be added to a cluster from the entire
* cluster window or just the "future" hits, plus one clock-cycle
* of "past" hits as a safety buffer to account for time uncertainty.
- *
- * @param limitClusterRange - <code>true</code> indicates that
- * the asymmetric clustering window should be used and <code>
- * false</code> that the symmetric window should be used.
+ * @param limitClusterRange - <code>true</code> indicates that the
+ * asymmetric clustering window should be used and <code>false</code>
+ * that the symmetric window should be used.
*/
void setLimitClusterRange(boolean limitClusterRange) {
this.limitClusterRange = limitClusterRange;
}
/**
- * Sets the minimum energy threshold below which hits will not be considered
- * as cluster centers.
- *
+ * Sets the minimum energy threshold below which hits will not be
+ * considered as cluster centers.
* @param seedEnergyThreshold - The minimum energy for a cluster center.
*/
void setSeedEnergyThreshold(double seedEnergyThreshold) {
@@ -306,7 +342,12 @@
this.seedEnergyThreshold = seedEnergyThreshold;
}
}
-
+
+ /**
+ * 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>.
+ */
@Override
public ClusterType getClusterType() {
return ClusterType.GTP;
|