Author: [log in to unmask]
Date: Tue Mar 3 16:01:55 2015
New Revision: 2235
Log:
Updated trigger diagnostics. Basic GUI component added. Still under construction.
Added:
java/trunk/users/src/main/java/org/hps/users/kmccarty/ClusterMatchStatus.java
java/trunk/users/src/main/java/org/hps/users/kmccarty/DiagSnapshot.java (with props)
java/trunk/users/src/main/java/org/hps/users/kmccarty/TriggerDiagnosticGUIDriver.java (with props)
java/trunk/users/src/main/java/org/hps/users/kmccarty/diagpanel/
java/trunk/users/src/main/java/org/hps/users/kmccarty/diagpanel/AbstractTablePanel.java (with props)
java/trunk/users/src/main/java/org/hps/users/kmccarty/diagpanel/ClusterTablePanel.java (with props)
java/trunk/users/src/main/java/org/hps/users/kmccarty/diagpanel/ComponentUtils.java (with props)
java/trunk/users/src/main/java/org/hps/users/kmccarty/diagpanel/DiagnosticUpdatable.java (with props)
java/trunk/users/src/main/java/org/hps/users/kmccarty/diagpanel/TableTextModel.java (with props)
Modified:
java/trunk/users/src/main/java/org/hps/users/kmccarty/PairTrigger.java
java/trunk/users/src/main/java/org/hps/users/kmccarty/SinglesTrigger.java
java/trunk/users/src/main/java/org/hps/users/kmccarty/TriggerDiagnosticDriver.java
Added: java/trunk/users/src/main/java/org/hps/users/kmccarty/ClusterMatchStatus.java
=============================================================================
--- java/trunk/users/src/main/java/org/hps/users/kmccarty/ClusterMatchStatus.java (added)
+++ java/trunk/users/src/main/java/org/hps/users/kmccarty/ClusterMatchStatus.java Tue Mar 3 16:01:55 2015
@@ -0,0 +1,254 @@
+package org.hps.users.kmccarty;
+
+import java.awt.Point;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.hps.readout.ecal.triggerbank.SSPCluster;
+import org.lcsim.event.Cluster;
+
+public class ClusterMatchStatus {
+ // Track cluster statistics.
+ private int sspClusters = 0;
+ private int reconClusters = 0;
+ private int matches = 0;
+ private int failEnergy = 0;
+ private int failPosition = 0;
+ private int failHitCount = 0;
+
+ // Plot binning values.
+ private static final int TIME_BIN = 4;
+ private static final double ENERGY_BIN = 0.01;
+ private static final int TIME_BIN_HALF = TIME_BIN / 2;
+ private static final double ENERGY_BIN_HALF = ENERGY_BIN / 2;
+
+ // Track plotting values for reconstructed and SSP clusters.
+ private Map<Integer, Integer> sspHitCountBins = new HashMap<Integer, Integer>();
+ private Map<Integer, Integer> reconHitCountBins = new HashMap<Integer, Integer>();
+ private Map<Point, Integer> sspPositionBins = new HashMap<Point, Integer>();
+ private Map<Point, Integer> reconPositionBins = new HashMap<Point, Integer>();
+ private Map<Integer, Integer> sspEnergyBins = new HashMap<Integer, Integer>();
+ private Map<Integer, Integer> reconEnergyBins = new HashMap<Integer, Integer>();
+
+ // Track plotting values for cluster matching results.
+ private Map<Point, Integer> failPositionBins = new HashMap<Point, Integer>();
+ private Map<Point, Integer> allHenergyBins = new HashMap<Point, Integer>();
+ private Map<Point, Integer> failHenergyBins = new HashMap<Point, Integer>();
+ private Map<Integer, Integer> allTimeBins = new HashMap<Integer, Integer>();
+ private Map<Integer, Integer> failTimeBins = new HashMap<Integer, Integer>();
+
+ public void addEvent(ClusterMatchEvent event, List<Cluster> reconClusters, List<SSPCluster> sspClusters) {
+ // Update the number of reconstructed and SSP clusters
+ // that have been seen so far.
+ int sspCount = sspClusters == null ? 0 : sspClusters.size();
+ int reconCount = reconClusters == null ? 0 : reconClusters.size();
+ this.sspClusters += sspCount;
+ this.reconClusters += reconCount;
+
+ // Update the pair state information.
+ matches += event.getMatches();
+ failEnergy += event.getEnergyFailures();
+ failHitCount += event.getHitCountFailures();
+ failPosition += event.getPositionFailures();
+
+ // In the special case that there are no SSP clusters, no pairs
+ // will be listed. All possible fails are known to have failed
+ // due to position.
+ if(sspClusters == null || sspClusters.isEmpty()) {
+ failPosition += (reconClusters == null ? 0 : reconClusters.size());
+ }
+
+ // Update the plotting information for reconstructed clusters.
+ for(Cluster cluster : reconClusters) {
+ // Update the hit count bin data.
+ Integer hitCountCount = reconHitCountBins.get(cluster.getCalorimeterHits().size());
+ if(hitCountCount == null) { reconHitCountBins.put(cluster.getCalorimeterHits().size(), 1); }
+ else { reconHitCountBins.put(cluster.getCalorimeterHits().size(), hitCountCount + 1); }
+
+ // Update the position bin data.
+ Point clusterPosition = TriggerDiagnosticUtil.getClusterPosition(cluster);
+ Integer positionCount = reconPositionBins.get(clusterPosition);
+ if(positionCount == null) { reconPositionBins.put(clusterPosition, 1); }
+ else { reconPositionBins.put(clusterPosition, positionCount + 1); }
+
+ // Update the energy bin data.
+ int energyBin = (int) Math.floor(cluster.getEnergy() / ENERGY_BIN);
+ Integer energyCount = reconEnergyBins.get(energyBin);
+ if(energyCount == null) { reconEnergyBins.put(energyBin, 1); }
+ else { reconEnergyBins.put(energyBin, energyCount + 1); }
+ }
+
+ // Update the plotting information for SSP clusters.
+ for(SSPCluster cluster : sspClusters) {
+ // Update the hit count bin data.
+ Integer hitCountCount = sspHitCountBins.get(cluster.getHitCount());
+ if(hitCountCount == null) { sspHitCountBins.put(cluster.getHitCount(), 1); }
+ else { sspHitCountBins.put(cluster.getHitCount(), hitCountCount + 1); }
+
+ // Update the position bin data.
+ Point clusterPosition = TriggerDiagnosticUtil.getClusterPosition(cluster);
+ Integer positionCount = sspPositionBins.get(clusterPosition);
+ if(positionCount == null) { sspPositionBins.put(clusterPosition, 1); }
+ else { sspPositionBins.put(clusterPosition, positionCount + 1); }
+
+ // Update the energy bin data.
+ int energyBin = (int) Math.floor(cluster.getEnergy() / ENERGY_BIN);
+ Integer energyCount = sspEnergyBins.get(energyBin);
+ if(energyCount == null) { sspEnergyBins.put(energyBin, 1); }
+ else { sspEnergyBins.put(energyBin, energyCount + 1); }
+ }
+
+ // Update the plotting information for SSP/reconstructed cluster
+ // pairs.
+ for(ClusterMatchedPair pair : event.getMatchedPairs()) {
+ // If one of the pairs is null, then it is unmatched cluster
+ // and may be skipped.
+ if(pair.getReconstructedCluster() == null || pair.getSSPCluster() == null) {
+ continue;
+ }
+
+ // Populate the bins for the "all" plots.
+ // Update the match time plots.
+ int timeBin = (int) Math.floor(TriggerDiagnosticUtil.getClusterTime(pair.getReconstructedCluster()) / TIME_BIN);
+ Integer timeCount = allTimeBins.get(timeBin);
+ if(timeCount == null) { allTimeBins.put(timeBin, 1); }
+ else { allTimeBins.put(timeBin, timeCount + 1); }
+
+ // Update the energy/hit difference plots.
+ int hitBin = getHitCountDifference(pair.getSSPCluster(), pair.getReconstructedCluster());
+ int energyBin = (int) Math.floor(getEnergyPercentDifference(pair.getSSPCluster(), pair.getReconstructedCluster()) / ENERGY_BIN);
+ Point henergyBin = new Point(hitBin, energyBin);
+ Integer henergyCount = allHenergyBins.get(henergyBin);
+ if(henergyCount == null) { allHenergyBins.put(henergyBin, 1); }
+ else { allHenergyBins.put(henergyBin, henergyCount + 1); }
+
+ // Populate the bins for the "fail" plots.
+ if(!pair.isMatch()) {
+ // Update the failed cluster position bins.
+ Point clusterPosition = TriggerDiagnosticUtil.getClusterPosition(pair.getReconstructedCluster());
+ Integer positionCount = failPositionBins.get(clusterPosition);
+ if(positionCount == null) { failPositionBins.put(clusterPosition, 1); }
+ else { failPositionBins.put(clusterPosition, positionCount + 1); }
+
+ // Update the failed match time plots.
+ timeCount = failTimeBins.get(timeBin);
+ if(timeCount == null) { failTimeBins.put(timeBin, 1); }
+ else { failTimeBins.put(timeBin, timeCount + 1); }
+
+ // Update the failed energy/hit difference plots.
+ henergyCount = failHenergyBins.get(henergyBin);
+ if(henergyCount == null) { failHenergyBins.put(henergyBin, 1); }
+ else { failHenergyBins.put(henergyBin, henergyCount + 1); }
+ }
+ }
+ }
+
+ /**
+ * Clears all statistical information and resets the object ot its
+ * default, empty state.
+ */
+ public void clear() {
+ // Clear statistical data.
+ sspClusters = 0;
+ reconClusters = 0;
+ matches = 0;
+ failEnergy = 0;
+ failPosition = 0;
+ failHitCount = 0;
+
+ // Clear plot collections.
+ sspHitCountBins.clear();
+ reconHitCountBins.clear();
+ sspPositionBins.clear();
+ reconPositionBins.clear();
+ sspEnergyBins.clear();
+ reconEnergyBins.clear();
+ failPositionBins.clear();
+ allHenergyBins.clear();
+ failHenergyBins.clear();
+ allTimeBins.clear();
+ failTimeBins.clear();
+ }
+
+ /**
+ * Gets the number of cluster pairs stored in this event that are
+ * marked with energy fail states.
+ * @return Returns the number of instances of this state as an
+ * <code>int</code> primitive.
+ */
+ public int getEnergyFailures() {
+ return failEnergy;
+ }
+
+ /**
+ * Gets the number of cluster pairs stored in this event that are
+ * marked with hit count fail states.
+ * @return Returns the number of instances of this state as an
+ * <code>int</code> primitive.
+ */
+ public int getHitCountFailures() {
+ return failHitCount;
+ }
+
+ /**
+ * Gets the number of cluster pairs stored in this event that are
+ * marked with position fail states.
+ * @return Returns the number of instances of this state as an
+ * <code>int</code> primitive.
+ */
+ public int getMatches() {
+ return matches;
+ }
+
+ /**
+ * Gets the number of cluster pairs stored in this event that are
+ * marked with position fail states.
+ * @return Returns the number of instances of this state as an
+ * <code>int</code> primitive.
+ */
+ public int getPositionFailures() {
+ return failPosition;
+ }
+
+ /**
+ * Gets the total number of verifiable reconstructed clusters seen.
+ * @return Returns the cluster count as an <code>int</code>
+ * primitive.
+ */
+ public int getReconClusterCount() {
+ return reconClusters;
+ }
+
+ /**
+ * Gets the total number of SSP bank clusters seen.
+ * @return Returns the cluster count as an <code>int</code>
+ * primitive.
+ */
+ public int getSSPClusterCount() {
+ return sspClusters;
+ }
+
+ /**
+ * Gets the difference in hit count between an SSP cluster and a
+ * reconstructed cluster.
+ * @param sspCluster - The SSP cluster.
+ * @param reconCluster - The reconstructed cluster.
+ * @return Returns the difference as an <code>int</code> primitive.
+ */
+ private static final int getHitCountDifference(SSPCluster sspCluster, Cluster reconCluster) {
+ return sspCluster.getHitCount() - TriggerDiagnosticUtil.getHitCount(reconCluster);
+ }
+
+ /**
+ * Solves the equation <code>|E_ssp / E_recon|</code>.
+ * @param sspCluster - The SSP cluster.
+ * @param reconCluster - The reconstructed cluster.
+ * @return Returns the solution to the equation as a <code>double
+ * </code> primitive.
+ */
+ private static final double getEnergyPercentDifference(SSPCluster sspCluster, Cluster reconCluster) {
+ return Math.abs((sspCluster.getEnergy() / reconCluster.getEnergy()));
+ }
+}
Added: java/trunk/users/src/main/java/org/hps/users/kmccarty/DiagSnapshot.java
=============================================================================
--- java/trunk/users/src/main/java/org/hps/users/kmccarty/DiagSnapshot.java (added)
+++ java/trunk/users/src/main/java/org/hps/users/kmccarty/DiagSnapshot.java Tue Mar 3 16:01:55 2015
@@ -0,0 +1,8 @@
+package org.hps.users.kmccarty;
+
+public class DiagSnapshot {
+ // UNDER CONSTRUCTION
+ // This is an empty file for now; it is still being built, but the
+ // table and driver won't work unless this object exists, so the
+ // empty class is included for the time being.
+}
Modified: java/trunk/users/src/main/java/org/hps/users/kmccarty/PairTrigger.java
=============================================================================
--- java/trunk/users/src/main/java/org/hps/users/kmccarty/PairTrigger.java (original)
+++ java/trunk/users/src/main/java/org/hps/users/kmccarty/PairTrigger.java Tue Mar 3 16:01:55 2015
@@ -154,4 +154,13 @@
public void setStateTimeCoincidence(boolean state) {
setCutState(PAIR_TIME_COINCIDENCE, state);
}
+
+ @Override
+ public String toString() {
+ return String.format("EClusterLow: %d; EClusterHigh %d; HitCount: %d; ESumLow: %d, ESumHigh: %d, EDiff: %d, ESlope: %d, Coplanarity: %d",
+ getStateClusterEnergyLow() ? 1 : 0, getStateClusterEnergyHigh() ? 1 : 0,
+ getStateHitCount() ? 1 : 0, getStateEnergySumLow() ? 1 : 0,
+ getStateEnergySumHigh() ? 1 : 0, getStateEnergyDifference() ? 1 : 0,
+ getStateEnergySlope() ? 1 : 0, getStateCoplanarity() ? 1 : 0);
+ }
}
Modified: java/trunk/users/src/main/java/org/hps/users/kmccarty/SinglesTrigger.java
=============================================================================
--- java/trunk/users/src/main/java/org/hps/users/kmccarty/SinglesTrigger.java (original)
+++ java/trunk/users/src/main/java/org/hps/users/kmccarty/SinglesTrigger.java Tue Mar 3 16:01:55 2015
@@ -143,4 +143,11 @@
public void setStateClusterEnergyHigh(boolean state) {
setCutState(CLUSTER_TOTAL_ENERGY_HIGH, state);
}
+
+ @Override
+ public String toString() {
+ return String.format("EClusterLow: %d; EClusterHigh %d; HitCount: %d",
+ getStateClusterEnergyLow() ? 1 : 0, getStateClusterEnergyHigh() ? 1 : 0,
+ getStateHitCount() ? 1 : 0);
+ }
}
Modified: java/trunk/users/src/main/java/org/hps/users/kmccarty/TriggerDiagnosticDriver.java
=============================================================================
--- java/trunk/users/src/main/java/org/hps/users/kmccarty/TriggerDiagnosticDriver.java (original)
+++ java/trunk/users/src/main/java/org/hps/users/kmccarty/TriggerDiagnosticDriver.java Tue Mar 3 16:01:55 2015
@@ -17,6 +17,7 @@
import org.hps.readout.ecal.triggerbank.AbstractIntData;
import org.hps.readout.ecal.triggerbank.SSPCluster;
import org.hps.readout.ecal.triggerbank.SSPData;
+import org.hps.readout.ecal.triggerbank.SSPNumberedTrigger;
import org.hps.readout.ecal.triggerbank.SSPPairTrigger;
import org.hps.readout.ecal.triggerbank.SSPSinglesTrigger;
import org.hps.readout.ecal.triggerbank.SSPTrigger;
@@ -62,16 +63,8 @@
private boolean performPairTriggerVerification = true;
// Efficiency tracking variables.
- private static final int GLOBAL = 0;
- private static final int LOCAL = 1;
- private static final int EVENT = 2;
-
- private int[] clusterMatched = new int[3];
- private int[] clusterSSPCount = new int[3];
- private int[] clusterFailEnergy = new int[3];
- private int[] clusterReconCount = new int[3];
- private int[] clusterFailPosition = new int[3];
- private int[] clusterFailHitCount = new int[3];
+ private ClusterMatchStatus clusterRunStats = new ClusterMatchStatus();
+ private ClusterMatchStatus clusterLocalStats = new ClusterMatchStatus();
private int singlesSSPTriggers = 0;
private int singlesReconMatched = 0;
@@ -127,6 +120,16 @@
private boolean printPairTriggerInternalFail = true;
private StringBuffer outputBuffer = new StringBuffer();
+ // Cut index arrays for trigger verification.
+ private static final int ENERGY_MIN = 0;
+ private static final int ENERGY_MAX = 1;
+ private static final int HIT_COUNT = 2;
+ private static final int ENERGY_SUM = 0;
+ private static final int ENERGY_DIFF = 1;
+ private static final int ENERGY_SLOPE = 2;
+ private static final int COPLANARITY = 3;
+ private static final int TIME = 4;
+
/**
* Define the trigger modules. This should be replaced by parsing
* the DAQ configuration at some point.
@@ -151,12 +154,12 @@
System.out.println("=== Cluster/Trigger Verification Settings ============================");
System.out.println("======================================================================");
- /* Runs 2040+
// Set the FADC settings.
- nsa = 240;
- nsb = 12;
+ nsa = 100;
+ nsb = 20;
windowWidth = 400;
+ /*
// Define the first singles trigger.
singlesTrigger[0] = new TriggerModule();
singlesTrigger[0].setCutValue(TriggerModule.CLUSTER_TOTAL_ENERGY_LOW, 0.010);
@@ -271,14 +274,15 @@
// Print the cluster verification data.
System.out.println("Cluster Verification:");
- System.out.printf("\tRecon Clusters :: %d%n", clusterReconCount[GLOBAL]);
- System.out.printf("\tSSP Clusters :: %d%n", clusterSSPCount[GLOBAL]);
- System.out.printf("\tClusters Matched :: %d%n", clusterMatched[GLOBAL]);
- System.out.printf("\tFailed (Position) :: %d%n", clusterFailPosition[GLOBAL]);
- System.out.printf("\tFailed (Energy) :: %d%n", clusterFailEnergy[GLOBAL]);
- System.out.printf("\tFailed (Hit Count) :: %d%n", clusterFailHitCount[GLOBAL]);
- if(clusterReconCount[GLOBAL] == 0) { System.out.printf("\tCluster Efficiency :: N/A%n"); }
- else { System.out.printf("\tCluster Efficiency :: %7.3f%%%n", 100.0 * clusterMatched[GLOBAL] / clusterReconCount[GLOBAL]); }
+
+ System.out.printf("\tRecon Clusters :: %d%n", clusterRunStats.getReconClusterCount());
+ System.out.printf("\tSSP Clusters :: %d%n", clusterRunStats.getSSPClusterCount());
+ System.out.printf("\tClusters Matched :: %d%n", clusterRunStats.getMatches());
+ System.out.printf("\tFailed (Position) :: %d%n", clusterRunStats.getPositionFailures());
+ System.out.printf("\tFailed (Energy) :: %d%n", clusterRunStats.getEnergyFailures());
+ System.out.printf("\tFailed (Hit Count) :: %d%n", clusterRunStats.getHitCountFailures());
+ if(clusterRunStats.getReconClusterCount() == 0) { System.out.printf("\tCluster Efficiency :: N/A%n"); }
+ else { System.out.printf("\tCluster Efficiency :: %7.3f%%%n", 100.0 * clusterRunStats.getMatches() / clusterRunStats.getReconClusterCount()); }
// Print the singles trigger verification data.
int spaces = getPrintSpaces(singlesSSPTriggers, singlesReconTriggers,
@@ -382,6 +386,16 @@
// ==========================================================
// ==== Initialize the Event ================================
// ==========================================================
+
+ // Print the verification header.
+ println();
+ println();
+ println("======================================================================");
+ println("==== Cluster/Trigger Verification ====================================");
+ println("======================================================================");
+
+ // Increment the total event count.
+ totalEvents++;
// Reset the output buffer and print flags.
outputBuffer = new StringBuffer();
@@ -426,19 +440,86 @@
}
}
*/
+
+
+
+ // ==========================================================
+ // ==== Obtain SSP and TI Banks =============================
+ // ==========================================================
+
+ // Get the SSP clusters.
+ if(event.hasCollection(GenericObject.class, bankCollectionName)) {
+ // Get the bank list.
+ List<GenericObject> bankList = event.get(GenericObject.class, bankCollectionName);
+
+ // Search through the banks and get the SSP and TI banks.
+ for(GenericObject obj : bankList) {
+ // If this is an SSP bank, parse it.
+ if(AbstractIntData.getTag(obj) == SSPData.BANK_TAG) {
+ sspBank = new SSPData(obj);
+ }
+
+ // Otherwise, if this is a TI bank, parse it.
+ else if(AbstractIntData.getTag(obj) == TIData.BANK_TAG) {
+ tiBank = new TIData(obj);
+
+ if(tiBank.isPulserTrigger()) { println("Trigger type :: Pulser"); }
+ else if(tiBank.isSingle0Trigger() || tiBank.isSingle1Trigger()) { println("Trigger type :: Singles"); }
+ else if(tiBank.isPair0Trigger() || tiBank.isPair1Trigger()) { println("Trigger type :: Pair"); }
+ else if(tiBank.isCalibTrigger()) { println("Trigger type :: Cosmic"); }
+ }
+ }
+
+ // If there is an SSP bank, get the list of SSP clusters.
+ if(sspBank != null) {
+ sspClusters = sspBank.getClusters();
+ if(sspClusters.size() == 1) {
+ println("1 SSP cluster found.");
+ } else {
+ printf("%d SSP clusters found.%n", sspClusters.size());
+ }
+ }
+ }
+
+
+
+ // ==========================================================
+ // ==== Establish Event Integrity ===========================
+ // ==========================================================
+
+ // Check that all of the required objects are present.
+ if(sspBank == null) {
+ println("No SSP bank found for this event. No verification will be performed.");
+ if(verbose) { System.out.println(outputBuffer.toString()); }
+ return;
+ } if(tiBank == null) {
+ println("No TI bank found for this event. No verification will be performed.");
+ if(verbose) { System.out.println(outputBuffer.toString()); }
+ return;
+ }
+
+
+
+ // ==========================================================
+ // ==== Check the Noise Level ===============================
+ // ==========================================================
+
+ // Check if there are hits.
+ if(event.hasCollection(CalorimeterHit.class, hitCollectionName)) {
+ // Check if there are more hits than the noise threshold.
+ if(event.get(CalorimeterHit.class, hitCollectionName).size() >= noiseThreshold) {
+ noiseEvents++;
+ println("Noise event detected. Skipping event...");
+ if(verbose) { System.out.println(outputBuffer.toString()); }
+ return;
+ }
+ }
// ==========================================================
// ==== Obtain Reconstructed Clusters =======================
// ==========================================================
-
- // Print the verification header.
- println();
- println();
- println("======================================================================");
- println("==== Cluster/Trigger Verification ====================================");
- println("======================================================================");
// Clear the list of triggers from previous events.
for(int triggerNum = 0; triggerNum < 2; triggerNum++) {
@@ -519,80 +600,6 @@
// ==========================================================
- // ==== Obtain SSP and TI Banks =============================
- // ==========================================================
-
- // Get the SSP clusters.
- if(event.hasCollection(GenericObject.class, bankCollectionName)) {
- // Get the bank list.
- List<GenericObject> bankList = event.get(GenericObject.class, bankCollectionName);
-
- // Search through the banks and get the SSP and TI banks.
- for(GenericObject obj : bankList) {
- // If this is an SSP bank, parse it.
- if(AbstractIntData.getTag(obj) == SSPData.BANK_TAG) {
- sspBank = new SSPData(obj);
- }
-
- // Otherwise, if this is a TI bank, parse it.
- else if(AbstractIntData.getTag(obj) == TIData.BANK_TAG) {
- tiBank = new TIData(obj);
-
- if(tiBank.isPulserTrigger()) { println("Trigger type :: Pulser"); }
- else if(tiBank.isSingle0Trigger() || tiBank.isSingle1Trigger()) { println("Trigger type :: Singles"); }
- else if(tiBank.isPair0Trigger() || tiBank.isPair1Trigger()) { println("Trigger type :: Pair"); }
- else if(tiBank.isCalibTrigger()) { println("Trigger type :: Cosmic"); }
- }
- }
-
- // If there is an SSP bank, get the list of SSP clusters.
- if(sspBank != null) {
- sspClusters = sspBank.getClusters();
- if(sspClusters.size() == 1) {
- println("1 SSP cluster found.");
- } else {
- printf("%d SSP clusters found.%n", sspClusters.size());
- }
- }
- }
-
-
-
- // ==========================================================
- // ==== Establish Event Integrity ===========================
- // ==========================================================
-
- // Check that all of the required objects are present.
- if(sspBank == null) {
- println("No SSP bank found for this event. No verification will be performed.");
- return;
- } if(tiBank == null) {
- println("No TI bank found for this event. No verification will be performed.");
- return;
- }
-
-
-
- // ==========================================================
- // ==== Check the Noise Level ===============================
- // ==========================================================
-
- // Increment the total event count.
- totalEvents++;
-
- // Check if there are hits.
- if(event.hasCollection(CalorimeterHit.class, hitCollectionName)) {
- // Check if there are more hits than the noise threshold.
- if(event.get(CalorimeterHit.class, hitCollectionName).size() >= noiseThreshold) {
- noiseEvents++;
- println("Noise event detected. Skipping event...");
- return;
- }
- }
-
-
-
- // ==========================================================
// ==== Perform Event Verification ==========================
// ==========================================================
@@ -638,13 +645,8 @@
// Write a snapshot of the driver to the event stream.
// TODO: Readout the snapshot!!
- // Reset the local variables to zero.
- clusterMatched[LOCAL] = 0;
- clusterSSPCount[LOCAL] = 0;
- clusterFailEnergy[LOCAL] = 0;
- clusterReconCount[LOCAL] = 0;
- clusterFailPosition[LOCAL] = 0;
- clusterFailHitCount[LOCAL] = 0;
+ // Clear the local statistical data.
+ clusterLocalStats.clear();
}
}
@@ -721,8 +723,6 @@
// Track the number of cluster pairs that were matched and that
// failed by failure type.
- clusterSSPCount[EVENT] = 0;
- clusterReconCount[EVENT] = 0;
ClusterMatchEvent event = new ClusterMatchEvent();
@@ -751,9 +751,6 @@
// Add the cluster to the list.
reconList.add(reconCluster);
-
- // Count the reconstructed clusters.
- clusterReconCount[EVENT]++;
}
// Populate the SSP cluster map.
@@ -770,9 +767,6 @@
// Add the cluster to the list.
sspList.add(sspCluster);
-
- // Count the SSP clusters.
- clusterSSPCount[EVENT]++;
}
@@ -797,18 +791,17 @@
// reason of position. The remainder of the loop may be
// skipped, since there is nothing to check.
if(sspList == null || sspList.isEmpty()) {
- clusterFailPosition[EVENT] += reconList.size();
clusterFail = true;
+ for(Cluster cluster : reconList) {
+ event.pairFailPosition(cluster, null);
+ }
continue positionLoop;
}
// If there are more reconstructed clusters than there are
// SSP clusters, than a number equal to the difference must
// fail by means of positions.
- if(sspList.size() < reconList.size()) {
- clusterFail = true;
- clusterFailPosition[EVENT] += (sspList.size() - reconList.size());
- }
+ if(sspList.size() < reconList.size()) { clusterFail = true; }
// Get all possible permutations of SSP clusters.
List<List<Pair>> permutations = getPermutations(reconList, sspList);
@@ -835,9 +828,6 @@
// Try to match each pair.
pairLoop:
for(Pair pair : pairs) {
- // Track the state of the current pair.
- //int pairState = STATE_CLUSTER_UNDEFINED;
-
// Print the current reconstructed/SSP cluster pair.
printf("\tP%d :: %s --> %s", permIndex,
pair.reconCluster == null ? "None" : clusterToString(pair.reconCluster),
@@ -861,16 +851,13 @@
if(pair.sspCluster.getHitCount() >= pair.reconCluster.getCalorimeterHits().size() - hitAcceptance &&
pair.sspCluster.getHitCount() <= pair.reconCluster.getCalorimeterHits().size() + hitAcceptance) {
// Designate the pair as a match.
- //pairState = STATE_CLUSTER_SUCCESS_MATCH;
perm.pairMatch(pair.reconCluster, pair.sspCluster);
printf(" [ %18s ]%n", "success: matched");
} else {
- //pairState = STATE_CLUSTER_FAIL_HIT_COUNT;
perm.pairFailHitCount(pair.reconCluster, pair.sspCluster);
printf(" [ %18s ]%n", "failure: hit count");
} // End hit count check.
} else {
- //pairState = STATE_CLUSTER_FAIL_ENERGY;
perm.pairFailEnergy(pair.reconCluster, pair.sspCluster);
printf(" [ %18s ]%n", "failure: energy");
} // End energy check.
@@ -900,20 +887,8 @@
} // End Crystal Position Loop
// Add the event results to the global results.
- clusterMatched[GLOBAL] += event.getMatches();
- clusterFailPosition[GLOBAL] += clusterFailPosition[EVENT];
- clusterFailEnergy[GLOBAL] += event.getEnergyFailures();
- clusterFailHitCount[GLOBAL] += event.getHitCountFailures();
- clusterReconCount[GLOBAL] += clusterReconCount[EVENT];
- clusterSSPCount[GLOBAL] += clusterSSPCount[EVENT];
-
- // Add the event results to the local results.
- clusterMatched[LOCAL] += event.getMatches();
- clusterFailPosition[LOCAL] += clusterFailPosition[EVENT];
- clusterFailEnergy[LOCAL] += event.getEnergyFailures();
- clusterFailHitCount[LOCAL] += event.getHitCountFailures();
- clusterReconCount[LOCAL] += clusterReconCount[EVENT];
- clusterSSPCount[LOCAL] += clusterSSPCount[EVENT];
+ clusterRunStats.addEvent(event, reconClusters, sspClusters);
+ clusterLocalStats.addEvent(event, reconClusters, sspClusters);
@@ -954,18 +929,24 @@
}
else { println("\tNone"); }
+ // Get the number of position failures.
+ int failPosition = event.getPositionFailures();
+ if(sspClusters == null || sspClusters.isEmpty()) {
+ failPosition = (reconClusters == null ? 0 : reconClusters.size());
+ }
+
// Print event statistics.
println();
println("Event Statistics:");
printf("\tRecon Clusters :: %d%n", reconClusters.size());
printf("\tClusters Matched :: %d%n", event.getMatches());
- printf("\tFailed (Position) :: %d%n", clusterFailPosition[EVENT]);
+ printf("\tFailed (Position) :: %d%n", failPosition);
printf("\tFailed (Energy) :: %d%n", event.getEnergyFailures());
printf("\tFailed (Hit Count) :: %d%n", event.getHitCountFailures());
printf("\tCluster Efficiency :: %3.0f%%%n", 100.0 * event.getMatches() / reconClusters.size());
// Note whether there was a cluster match failure.
- if(clusterMatched[EVENT] - reconClusters.size() != 0) {
+ if(event.getMatches() - reconClusters.size() != 0) {
clusterFail = true;
}
}
@@ -977,15 +958,66 @@
* simulated on reconstructed clusters to measure trigger efficiency.
*/
private void singlesTriggerVerification() {
- // ==========================================================
- // ==== Initialize Singles Trigger Verification =============
+ // Create lists of generic triggers.
+ List<List<? extends Trigger<?>>> sspTriggerList = new ArrayList<List<? extends Trigger<?>>>(2);
+ List<List<? extends Trigger<?>>> reconTriggerList = new ArrayList<List<? extends Trigger<?>>>(2);
+
+ // Convert the simulated triggers to generic versions and add
+ // them to the generic list.
+ for(int triggerNum = 0; triggerNum < 2; triggerNum++) {
+ // Get the generic trigger list.
+ List<? extends Trigger<?>> sspTriggers = sspSinglesTriggers.get(triggerNum);
+ List<? extends Trigger<?>> reconTriggers = reconSinglesTriggers.get(triggerNum);
+
+ // Add it to the generic list.
+ sspTriggerList.add(sspTriggers);
+ reconTriggerList.add(reconTriggers);
+ }
+
+ // Run generic trigger verification.
+ triggerVerification(sspTriggerList, reconTriggerList, true);
+ }
+
+ /**
+ * Checks triggers simulated on SSP clusters against the SSP bank's
+ * reported triggers to verify that the trigger is correctly applying
+ * cuts to the clusters it sees. Additionally compares triggers
+ * simulated on reconstructed clusters to measure trigger efficiency.
+ */
+ private void pairTriggerVerification() {
+ // Create lists of generic triggers.
+ List<List<? extends Trigger<?>>> sspTriggerList = new ArrayList<List<? extends Trigger<?>>>(2);
+ List<List<? extends Trigger<?>>> reconTriggerList = new ArrayList<List<? extends Trigger<?>>>(2);
+
+ // Convert the simulated triggers to generic versions and add
+ // them to the generic list.
+ for(int triggerNum = 0; triggerNum < 2; triggerNum++) {
+ // Get the generic trigger list.
+ List<? extends Trigger<?>> sspTriggers = sspPairsTriggers.get(triggerNum);
+ List<? extends Trigger<?>> reconTriggers = reconPairsTriggers.get(triggerNum);
+
+ // Add it to the generic list.
+ sspTriggerList.add(sspTriggers);
+ reconTriggerList.add(reconTriggers);
+ }
+
+ // Run generic trigger verification.
+ triggerVerification(sspTriggerList, reconTriggerList, false);
+ }
+
+ private void triggerVerification(List<List<? extends Trigger<?>>> sspTriggerList,
+ List<List<? extends Trigger<?>>> reconTriggerList, boolean isSingles) {
+
+ // ==========================================================
+ // ==== Initialize Trigger Verification =====================
// ==========================================================
// Print the cluster verification header.
println();
println();
println("======================================================================");
- println("=== Singles Trigger Verification =====================================");
+ if(isSingles) { println("=== Singles Trigger Verification ====================================="); }
+ else { println("=== Pair Trigger Verification ========================================"); }
println("======================================================================");
// Track the number of triggers seen and the number found.
@@ -996,10 +1028,7 @@
// Track the number of times a given cut caused a trigger to
// fail to match.
- int[] eventEnergyMin = new int[2];
- int[] eventEnergyMax = new int[2];
- int[] eventHitCount = new int[2];
- int[] eventTime = new int[2];
+ int[][] triggerComp = new int[5][2];
@@ -1008,52 +1037,45 @@
// ==========================================================
// Get the list of triggers reported by the SSP.
- List<SSPSinglesTrigger> sspTriggers = sspBank.getSinglesTriggers();
+ List<? extends SSPNumberedTrigger> sspTriggers;
+ if(isSingles) { sspTriggers = sspBank.getSinglesTriggers(); }
+ else { sspTriggers = sspBank.getPairTriggers(); }
// Output the SSP cluster singles triggers.
println();
- println("SSP Cluster Singles Triggers");
+ println("SSP Cluster " + (isSingles ? "Singles" : "Pair") + " Triggers");
for(int triggerNum = 0; triggerNum < 2; triggerNum++) {
- for(SinglesTrigger<SSPCluster> simTrigger : sspSinglesTriggers.get(triggerNum)) {
- printf("\tTrigger %d :: %s :: EClusterLow: %d; EClusterHigh %d; HitCount: %d%n",
- (triggerNum + 1), clusterPositionString(simTrigger.getTriggerSource()),
- simTrigger.getStateClusterEnergyLow() ? 1 : 0,
- simTrigger.getStateClusterEnergyHigh() ? 1 : 0,
- simTrigger.getStateHitCount() ? 1 : 0);
- }
- }
- if(sspSinglesTriggers.get(0).size() + sspSinglesTriggers.get(1).size() == 0) {
+ for(Trigger<?> simTrigger : sspTriggerList.get(triggerNum)) {
+ printf("\tTrigger %d :: %s :: %s%n",
+ (triggerNum + 1), triggerPositionString(simTrigger),
+ simTrigger.toString());
+ }
+ }
+ if(sspTriggerList.get(0).size() + sspTriggerList.get(1).size() == 0) {
println("\tNone");
}
// Output the reconstructed cluster singles triggers.
- println("Reconstructed Cluster Singles Triggers");
+ println("Reconstructed Cluster " + (isSingles ? "Singles" : "Pair") + " Triggers");
for(int triggerNum = 0; triggerNum < 2; triggerNum++) {
- for(SinglesTrigger<Cluster> simTrigger : reconSinglesTriggers.get(triggerNum)) {
- printf("\tTrigger %d :: %s :: EClusterLow: %d; EClusterHigh %d; HitCount: %d%n",
- (triggerNum + 1), clusterPositionString(simTrigger.getTriggerSource()),
- simTrigger.getStateClusterEnergyLow() ? 1 : 0,
- simTrigger.getStateClusterEnergyHigh() ? 1 : 0,
- simTrigger.getStateHitCount() ? 1 : 0);
- }
- }
- if(reconSinglesTriggers.get(0).size() + reconSinglesTriggers.get(1).size() == 0) {
+ for(Trigger<?> simTrigger : reconTriggerList.get(triggerNum)) {
+ printf("\tTrigger %d :: %s :: %s%n",
+ (triggerNum + 1), triggerPositionString(simTrigger),
+ simTrigger.toString());
+ }
+ }
+ if(reconTriggerList.get(0).size() + reconTriggerList.get(1).size() == 0) {
println("\tNone");
}
// Output the SSP reported triggers.
- println("SSP Reported Singles Triggers");
- for(SSPSinglesTrigger sspTrigger : sspTriggers) {
+ println("SSP Reported " + (isSingles ? "Singles" : "Pair") + " Triggers");
+ for(SSPTrigger sspTrigger : sspTriggers) {
// Increment the number of SSP cluster singles triggers.
sspReportedTriggers++;
- // Get the trigger properties.
- int triggerNum = sspTrigger.isFirstTrigger() ? 1 : 2;
-
// Print the trigger.
- printf("\tTrigger %d :: %3d ns :: EClusterLow: %d; EClusterHigh %d; HitCount: %d%n",
- triggerNum, sspTrigger.getTime(), sspTrigger.passCutEnergyMin() ? 1 : 0,
- sspTrigger.passCutEnergyMax() ? 1 : 0, sspTrigger.passCutHitCount() ? 1 : 0);
+ printf("\t%s%n", sspTrigger.toString());
}
if(sspReportedTriggers == 0) { println("\tNone"); }
@@ -1066,21 +1088,22 @@
// Track which SSP triggers have been matched to avoid matching
// multiple reconstructed SSP cluster triggers to the same SSP
// trigger.
- Set<SSPSinglesTrigger> sspTriggerSet = new HashSet<SSPSinglesTrigger>();
- Set<SinglesTrigger<SSPCluster>> simTriggerSet = new HashSet<SinglesTrigger<SSPCluster>>();
+ Set<SSPNumberedTrigger> sspTriggerSet = new HashSet<SSPNumberedTrigger>();
+ Set<Trigger<?>> simTriggerSet = new HashSet<Trigger<?>>();
// Track the number of SSP reported triggers that are found in
// excess of the SSP simulated triggers.
- int extraTriggers = sspTriggers.size() - (sspSinglesTriggers.get(0).size() + sspSinglesTriggers.get(1).size());
+ int extraTriggers = sspTriggers.size() - (sspTriggerList.get(0).size() + sspTriggerList.get(1).size());
if(extraTriggers > 0) {
sspReportedExtras += extraTriggers;
- singlesInternalFail = true;
+ if(isSingles) { singlesInternalFail = true; }
+ else { pairInternalFail = true; }
}
// Iterate over the triggers.
println();
println("SSP Reported Trigger --> SSP Cluster Trigger Match Status");
- for(SSPSinglesTrigger sspTrigger : sspTriggers) {
+ for(SSPNumberedTrigger sspTrigger : sspTriggers) {
// Get the trigger information.
int triggerNum = sspTrigger.isFirstTrigger() ? 0 : 1;
boolean matchedTrigger = false;
@@ -1088,14 +1111,14 @@
// Iterate over the SSP cluster simulated triggers and
// look for a trigger that matches.
matchLoop:
- for(SinglesTrigger<SSPCluster> simTrigger : sspSinglesTriggers.get(triggerNum)) {
+ for(Trigger<?> simTrigger : sspTriggerList.get(triggerNum)) {
// If the current SSP trigger has already been
// matched, skip it.
if(sspTriggerSet.contains(sspTrigger)) { continue matchLoop; }
// Otherwise, check whether the reconstructed SSP
// cluster trigger matches the SSP trigger.
- if(compareSSPSinglesTriggers(sspTrigger, simTrigger)) {
+ if(compareTriggers(sspTrigger, simTrigger)) {
matchedTrigger = true;
sspTriggerSet.add(sspTrigger);
simTriggerSet.add(simTrigger);
@@ -1103,10 +1126,7 @@
break matchLoop;
}
- printf("\tTrigger %d :: %3d :: EClusterLow: %d; EClusterHigh %d; HitCount: %d :: Matched: %5b%n",
- (triggerNum + 1), sspTrigger.getTime(), sspTrigger.passCutEnergyMin() ? 1 : 0,
- sspTrigger.passCutEnergyMax() ? 1 : 0, sspTrigger.passCutHitCount() ? 1 : 0,
- matchedTrigger);
+ printf("\t%s :: Matched: %5b%n", sspTrigger.toString(), matchedTrigger);
}
}
@@ -1114,23 +1134,25 @@
// unmatched SSP reported trigger that most closely matches it.
simLoop:
for(int triggerNum = 0; triggerNum < 2; triggerNum++) {
- for(SinglesTrigger<SSPCluster> simTrigger : sspSinglesTriggers.get(triggerNum)) {
+ for(Trigger<?> simTrigger : sspTriggerList.get(triggerNum)) {
// Check whether this trigger has already been matched
// or not. If it has been matched, skip it.
if(simTriggerSet.contains(simTrigger)) { continue simLoop; }
+ // Get the trigger time for the simulated trigger.
+ double simTime = getTriggerTime(simTrigger);
+
// Track the match statistics for each reported trigger
// so that the closest match may be found.
int numMatched = -1;
- boolean foundBest = false;
- boolean[] matchedCut = new boolean[3];
+ boolean[] matchedCut = null;
// Iterate over the reported triggers to find a match.
reportedLoop:
- for(SSPSinglesTrigger sspTrigger : sspTriggers) {
+ for(SSPNumberedTrigger sspTrigger : sspTriggers) {
// If the two triggers have different times, this
// trigger should be skipped.
- if(sspTrigger.getTime() != simTrigger.getTriggerSource().getTime()) {
+ if(sspTrigger.getTime() != simTime) {
continue reportedLoop;
}
@@ -1139,10 +1161,7 @@
if(sspTriggerSet.contains(sspTrigger)) { continue reportedLoop; }
// Check each of the cuts.
- boolean[] tempMatchedCut = new boolean[3];
- tempMatchedCut[0] = (simTrigger.getStateClusterEnergyLow() == sspTrigger.passCutEnergyMin());
- tempMatchedCut[1] = (simTrigger.getStateClusterEnergyHigh() == sspTrigger.passCutEnergyMax());
- tempMatchedCut[2] = (simTrigger.getStateHitCount() == sspTrigger.passCutHitCount());
+ boolean[] tempMatchedCut = triggerCutMatch(simTrigger, sspTrigger);
// Check each cut and see if this is a closer match
// than the previous best match.
@@ -1152,7 +1171,6 @@
// If the number of matched cuts exceeds the old
// best result, this becomes the new best result.
if(tempNumMatched > numMatched) {
- foundBest = true;
numMatched = tempNumMatched;
matchedCut = tempMatchedCut;
}
@@ -1160,18 +1178,19 @@
// If some match was found, note what caused it to not
// qualify as a complete match.
- if(foundBest) {
- if(!matchedCut[0]) { eventEnergyMin[triggerNum]++; }
- if(!matchedCut[1]) { eventEnergyMax[triggerNum]++; }
- if(!matchedCut[2]) { eventHitCount[triggerNum]++; }
+ if(matchedCut != null) {
+ for(int cutIndex = 0; cutIndex < matchedCut.length; cutIndex++) {
+ if(!matchedCut[cutIndex]) { triggerComp[cutIndex][triggerNum]++; }
+ }
}
// If there was no match found, it means that there were
// no triggers that were both unmatched and at the same
// time as this simulated trigger.
else {
- eventTime[triggerNum]++;
- singlesInternalFail = true;
+ triggerComp[TIME][triggerNum]++;
+ if(isSingles) { singlesInternalFail = true; }
+ else { pairInternalFail = true; }
}
}
}
@@ -1179,7 +1198,7 @@
// ==========================================================
- // ==== SSP Singles Trigger Efficiency ======================
+ // ==== Trigger Efficiency ==================================
// ==========================================================
// Reset the SSP matched trigger set.
@@ -1189,70 +1208,52 @@
println();
println("Recon Cluster Trigger --> SSP Reported Trigger Match Status");
for(int triggerNum = 0; triggerNum < 2; triggerNum++) {
- for(SinglesTrigger<Cluster> simTrigger : reconSinglesTriggers.get(triggerNum)) {
-
- printf("\tTrigger %d :: %s :: EClusterLow: %d; EClusterHigh %d; HitCount: %d%n",
- (triggerNum + 1), clusterPositionString(simTrigger.getTriggerSource()),
- simTrigger.getStateClusterEnergyLow() ? 1 : 0,
- simTrigger.getStateClusterEnergyHigh() ? 1 : 0,
- simTrigger.getStateHitCount() ? 1 : 0);
- printf("\t\tCluster Energy :: %.3f GeV; Hit Count :: %d%n", simTrigger.getTriggerSource().getEnergy(),
- simTrigger.getTriggerSource().getCalorimeterHits().size());
- printf("\t\tCluster Energy Cut :: [ %.3f GeV, %.3f GeV ]; Hit Count :: [ %.0f, INF )%n",
- singlesTrigger[triggerNum].getCutValue(TriggerModule.CLUSTER_TOTAL_ENERGY_LOW),
- singlesTrigger[triggerNum].getCutValue(TriggerModule.CLUSTER_TOTAL_ENERGY_HIGH),
- singlesTrigger[triggerNum].getCutValue(TriggerModule.CLUSTER_HIT_COUNT_LOW));
+ for(Trigger<?> simTrigger : reconTriggerList.get(triggerNum)) {
+
+ printf("\tTrigger %d :: %s :: %s%n", (triggerNum + 1),
+ triggerPositionString(simTrigger), simTrigger.toString());
// Iterate over the SSP reported triggers and compare
// them to the reconstructed cluster simulated trigger.
matchLoop:
- for(SSPTrigger sspTrigger : sspTriggers) {
- // Only compare singles triggers.
- if(sspTrigger instanceof SSPSinglesTrigger) {
- // Cast the trigger.
- SSPSinglesTrigger sspSingles = (SSPSinglesTrigger) sspTrigger;
-
- printf("\t\t\tTrigger %d :: %3d ns :: EClusterLow: %d; EClusterHigh %d; HitCount: %d",
- sspSingles.isFirstTrigger() ? 1 : 2,
- sspSingles.getTime(),
- sspSingles.passCutEnergyMin() ? 1 : 0,
- sspSingles.passCutEnergyMax() ? 1 : 0,
- sspSingles.passCutHitCount() ? 1 : 0);
-
- // Only compare triggers if they are from the
- // same trigger source.
- if((triggerNum == 0 && sspSingles.isSecondTrigger())
- || (triggerNum == 1 && sspSingles.isFirstTrigger())) {
- print(" [ fail; source ]%n");
+ for(SSPNumberedTrigger sspTrigger : sspTriggers) {
+ printf("\t\t\t%s", sspTrigger.toString());
+
+ // Only compare triggers if they are from the
+ // same trigger source.
+ if((triggerNum == 0 && sspTrigger.isSecondTrigger())
+ || (triggerNum == 1 && sspTrigger.isFirstTrigger())) {
+ print(" [ fail; source ]%n");
+ continue matchLoop;
+ }
+
+ // Only compare the singles trigger if it was
+ // not already matched to another trigger.
+ if(sspTriggerSet.contains(sspTrigger)) {
+ print(" [ fail; matched ]%n");
+ continue matchLoop;
+ }
+
+ // Test each cut.
+ String[][] cutNames = {
+ { "E_min", "E_max", "hit count", "null" },
+ { "E_sum", "E_diff", "E_slope", "coplanar" }
+ };
+ int typeIndex = isSingles ? 0 : 1;
+ boolean[] matchedCuts = triggerCutMatch(simTrigger, sspTrigger);
+ for(int cutIndex = 0; cutIndex < matchedCuts.length; cutIndex++) {
+ if(!matchedCuts[cutIndex]) {
+ printf(" [ fail; %-9s ]%n", cutNames[typeIndex][cutIndex]);
continue matchLoop;
}
-
- // Only compare the singles trigger if it was
- // not already matched to another trigger.
- if(sspTriggerSet.contains(sspSingles)) {
- print(" [ fail; matched ]%n");
- continue matchLoop;
- }
-
- // Test each cut.
- if(sspSingles.passCutEnergyMin() != simTrigger.getStateClusterEnergyLow()) {
- print(" [ fail; E_min ]%n");
- continue matchLoop;
- } if(sspSingles.passCutEnergyMax() != simTrigger.getStateClusterEnergyHigh()) {
- print(" [ fail; E_max ]%n");
- continue matchLoop;
- } if(sspSingles.passCutHitCount() != simTrigger.getStateHitCount()) {
- print(" [ fail; hit count ]%n");
- continue matchLoop;
- }
-
- // If all the trigger flags match, then the
- // triggers are a match.
- reconTriggersMatched++;
- sspTriggerSet.add(sspSingles);
- print(" [ success ]%n");
- break matchLoop;
}
+
+ // If all the trigger flags match, then the
+ // triggers are a match.
+ reconTriggersMatched++;
+ sspTriggerSet.add(sspTrigger);
+ print(" [ success ]%n");
+ break matchLoop;
}
}
}
@@ -1265,8 +1266,9 @@
// Get the number of SSP and reconstructed cluster simulated
// triggers.
- int sspSimTriggers = sspSinglesTriggers.get(0).size() + sspSinglesTriggers.get(1).size();
- int reconSimTriggers = reconSinglesTriggers.get(0).size() + reconSinglesTriggers.get(1).size();
+ int sspSimTriggers = sspTriggerList.get(0).size() + sspTriggerList.get(1).size();
+ int reconSimTriggers = reconTriggerList.get(0).size() + reconTriggerList.get(1).size();
+ int halfSimTriggers = sspSimTriggers / 2;
// Print event statistics.
println();
@@ -1290,402 +1292,85 @@
}
// Print the individual cut performances.
- println();
- int halfSimTriggers = sspSimTriggers / 2;
- for(int triggerNum = 0; triggerNum < 2; triggerNum++) {
- printf("Trigger %d Individual Cut Failure Rate:%n", (triggerNum + 1));
- if(sspSimTriggers == 0) {
- printf("\tCluster Energy Lower Bound :: %d / %d%n", eventEnergyMin[triggerNum], halfSimTriggers);
- printf("\tCluster Energy Upper Bound :: %d / %d%n", eventEnergyMax[triggerNum], halfSimTriggers);
- printf("\tCluster Hit Count :: %d / %d%n", eventHitCount[triggerNum], halfSimTriggers);
- } else {
- printf("\tCluster Energy Lower Bound :: %d / %d (%3.0f%%)%n",
- eventEnergyMin[triggerNum], halfSimTriggers, (100.0 * eventEnergyMin[triggerNum] / halfSimTriggers));
- printf("\tCluster Energy Upper Bound :: %d / %d (%3.0f%%)%n",
- eventEnergyMax[triggerNum], halfSimTriggers, (100.0 * eventEnergyMax[triggerNum] / halfSimTriggers));
- printf("\tCluster Hit Count :: %d / %d (%3.0f%%)%n",
- eventHitCount[triggerNum], halfSimTriggers, (100.0 * eventHitCount[triggerNum] / halfSimTriggers));
- }
- printf("\tExcess Reported Triggers :: %d%n", sspReportedExtras / 2);
- }
-
- // Update the global trigger tracking variables.
- singlesSSPTriggers += sspSimTriggers;
- singlesReconMatched += reconTriggersMatched;
- singlesReconTriggers += reconSimTriggers;
- singlesInternalMatched += sspInternalMatched;
- singlesReportedTriggers += sspReportedTriggers;
- singlesReportedExtras += sspReportedExtras;
-
- for(int triggerNum = 0; triggerNum < 2; triggerNum++) {
- globalEnergyMinCut[triggerNum] += eventEnergyMin[triggerNum];
- globalEnergyMaxCut[triggerNum] += eventEnergyMax[triggerNum];
- globalHitCountCut[triggerNum] += eventHitCount[triggerNum];
- globalSinglesTimeCut[triggerNum] += eventTime[triggerNum];
- }
-
- // Note whether the was a singles trigger match failure.
+ if(isSingles) {
+ println();
+ for(int triggerNum = 0; triggerNum < 2; triggerNum++) {
+ printf("Trigger %d Individual Cut Failure Rate:%n", (triggerNum + 1));
+ if(sspSimTriggers == 0) {
+ printf("\tCluster Energy Lower Bound :: %d / %d%n", triggerComp[ENERGY_MIN][triggerNum], halfSimTriggers);
+ printf("\tCluster Energy Upper Bound :: %d / %d%n", triggerComp[ENERGY_MAX][triggerNum], halfSimTriggers);
+ printf("\tCluster Hit Count :: %d / %d%n", triggerComp[HIT_COUNT][triggerNum], halfSimTriggers);
+ } else {
+ printf("\tCluster Energy Lower Bound :: %d / %d (%3.0f%%)%n",
+ triggerComp[ENERGY_MIN][triggerNum], halfSimTriggers, (100.0 * triggerComp[ENERGY_MIN][triggerNum] / halfSimTriggers));
+ printf("\tCluster Energy Upper Bound :: %d / %d (%3.0f%%)%n",
+ triggerComp[ENERGY_MAX][triggerNum], halfSimTriggers, (100.0 * triggerComp[ENERGY_MAX][triggerNum] / halfSimTriggers));
+ printf("\tCluster Hit Count :: %d / %d (%3.0f%%)%n",
+ triggerComp[HIT_COUNT][triggerNum], halfSimTriggers, (100.0 * triggerComp[HIT_COUNT][triggerNum] / halfSimTriggers));
+ }
+ printf("\tExcess Reported Triggers :: %d%n", sspReportedExtras / 2);
+ }
+
+ // Update the global trigger tracking variables.
+ singlesSSPTriggers += sspSimTriggers;
+ singlesReconMatched += reconTriggersMatched;
+ singlesReconTriggers += reconSimTriggers;
+ singlesInternalMatched += sspInternalMatched;
+ singlesReportedTriggers += sspReportedTriggers;
+ singlesReportedExtras += sspReportedExtras;
+
+ for(int triggerNum = 0; triggerNum < 2; triggerNum++) {
+ globalEnergyMinCut[triggerNum] += triggerComp[ENERGY_MIN][triggerNum];
+ globalEnergyMaxCut[triggerNum] += triggerComp[ENERGY_MAX][triggerNum];
+ globalHitCountCut[triggerNum] += triggerComp[HIT_COUNT][triggerNum];
+ globalSinglesTimeCut[triggerNum] += triggerComp[TIME][triggerNum];
+ }
+ } else {
+ for(int triggerNum = 0; triggerNum < 2; triggerNum++) {
+ println();
+ printf("Trigger %d Individual Cut Failure Rate:%n", (triggerNum + 1));
+ if(sspSimTriggers == 0) {
+ printf("\tPair Energy Sum :: %d / %d%n", triggerComp[ENERGY_SUM][triggerNum], halfSimTriggers);
+ printf("\tPair Energy Difference :: %d / %d%n", triggerComp[ENERGY_DIFF][triggerNum], halfSimTriggers);
+ printf("\tPair Energy Slope :: %d / %d%n", triggerComp[ENERGY_SLOPE][triggerNum], halfSimTriggers);
+ printf("\tPair Coplanarity :: %d / %d%n", triggerComp[COPLANARITY][triggerNum], halfSimTriggers);
+ printf("\tPair Trigger Time :: %d / %d%n", triggerComp[TIME][triggerNum], halfSimTriggers);
+ } else {
+ printf("\tPair Energy Sum :: %d / %d (%3.0f%%)%n",
+ triggerComp[ENERGY_SUM][triggerNum], halfSimTriggers, (100.0 * triggerComp[ENERGY_SUM][triggerNum] / halfSimTriggers));
+ printf("\tPair Energy Difference :: %d / %d (%3.0f%%)%n",
+ triggerComp[ENERGY_DIFF][triggerNum], halfSimTriggers, (100.0 * triggerComp[ENERGY_DIFF][triggerNum] / halfSimTriggers));
+ printf("\tPair Energy Slope :: %d / %d (%3.0f%%)%n",
+ triggerComp[ENERGY_SLOPE][triggerNum], halfSimTriggers, (100.0 * triggerComp[ENERGY_SLOPE][triggerNum] / halfSimTriggers));
+ printf("\tPair Coplanarity :: %d / %d (%3.0f%%)%n",
+ triggerComp[COPLANARITY][triggerNum], halfSimTriggers, (100.0 * triggerComp[COPLANARITY][triggerNum] / halfSimTriggers));
+ printf("\tPair Trigger Time :: %d / %d (%3.0f%%)%n",
+ triggerComp[TIME][triggerNum], halfSimTriggers, (100.0 * triggerComp[TIME][triggerNum] / halfSimTriggers));
+ }
+ printf("\tExcess Reported Triggers :: %d%n", sspReportedExtras / 2);
+ }
+
+ // Update the global trigger tracking variables.
+ pairSSPTriggers += sspSimTriggers;
+ pairReconMatched += reconTriggersMatched;
+ pairReconTriggers += reconSimTriggers;
+ pairInternalMatched += sspInternalMatched;
+ pairReportedTriggers += sspReportedTriggers;
+ pairReportedExtras += sspReportedExtras;
+
+ for(int triggerNum = 0; triggerNum < 2; triggerNum++) {
+ globalEnergySumCut[triggerNum] += triggerComp[ENERGY_SUM][triggerNum];
+ globalEnergyDiffCut[triggerNum] += triggerComp[ENERGY_DIFF][triggerNum];
+ globalEnergySlopeCut[triggerNum] += triggerComp[ENERGY_SLOPE][triggerNum];
+ globalCoplanarityCut[triggerNum] += triggerComp[COPLANARITY][triggerNum];
+ globalPairTimeCut[triggerNum] += triggerComp[TIME][triggerNum];
+ }
+ }
+
+ // Note whether the was a trigger match failure.
if((reconTriggersMatched - reconSimTriggers != 0) || (sspInternalMatched - sspSimTriggers != 0)) {
- singlesEfficiencyFail = true;
- }
- }
-
- /**
- * Checks triggers simulated on SSP clusters against the SSP bank's
- * reported triggers to verify that the trigger is correctly applying
- * cuts to the clusters it sees. Additionally compares triggers
- * simulated on reconstructed clusters to measure trigger efficiency.
- */
- private void pairTriggerVerification() {
- // ==========================================================
- // ==== Initialize Pair Trigger Verification ===============
- // ==========================================================
-
- // Print the cluster verification header.
- println();
- println();
- println("======================================================================");
- println("=== Pair Trigger Verification ========================================");
- println("======================================================================");
-
- // Track the number of triggers seen and the number found.
- int sspReportedTriggers = 0;
- int sspInternalMatched = 0;
- int reconTriggersMatched = 0;
- int sspReportedExtras = 0;
-
- int[] eventEnergySum = new int[2];
- int[] eventEnergyDiff = new int[2];
- int[] eventEnergySlope = new int[2];
- int[] eventCoplanarity = new int[2];
- int[] eventTime = new int[2];
-
-
-
- // ==========================================================
- // ==== Output Event Summary ================================
- // ==========================================================
-
- // Get the list of triggers reported by the SSP.
- List<SSPPairTrigger> sspTriggers = sspBank.getPairTriggers();
-
- // Output the SSP cluster pair triggers.
- println();
- println("SSP Cluster Pair Triggers");
- for(int triggerNum = 0; triggerNum < 2; triggerNum++) {
- for(PairTrigger<SSPCluster[]> simTrigger : sspPairsTriggers.get(triggerNum)) {
- printf("\tTrigger %d :: %s, %s :: EClusterLow: %d; EClusterHigh %d; HitCount: %d; ESumLow: %d, ESumHigh: %d, EDiff: %d, ESlope: %d, Coplanarity: %d%n",
- (triggerNum + 1), clusterPositionString(simTrigger.getTriggerSource()[0]),
- clusterPositionString(simTrigger.getTriggerSource()[1]),
- simTrigger.getStateClusterEnergyLow() ? 1 : 0,
- simTrigger.getStateClusterEnergyHigh() ? 1 : 0,
- simTrigger.getStateHitCount() ? 1 : 0,
- simTrigger.getStateEnergySumLow() ? 1 : 0,
- simTrigger.getStateEnergySumHigh() ? 1 : 0,
- simTrigger.getStateEnergyDifference() ? 1 : 0,
- simTrigger.getStateEnergySlope() ? 1 : 0,
- simTrigger.getStateCoplanarity() ? 1 : 0);
- }
- }
- if(sspPairsTriggers.get(0).size() + sspPairsTriggers.get(1).size() == 0) {
- println("\tNone");
- }
-
- // Output the reconstructed cluster singles triggers.
- println("Reconstructed Cluster Pair Triggers");
- for(int triggerNum = 0; triggerNum < 2; triggerNum++) {
- for(PairTrigger<Cluster[]> simTrigger : reconPairsTriggers.get(triggerNum)) {
- printf("\tTrigger %d :: %s, %s :: EClusterLow: %d; EClusterHigh %d; HitCount: %d; ESumLow: %d, ESumHigh: %d, EDiff: %d, ESlope: %d, Coplanarity: %d%n",
- (triggerNum + 1), clusterPositionString(simTrigger.getTriggerSource()[0]),
- clusterPositionString(simTrigger.getTriggerSource()[1]),
- simTrigger.getStateClusterEnergyLow() ? 1 : 0,
- simTrigger.getStateClusterEnergyHigh() ? 1 : 0,
- simTrigger.getStateHitCount() ? 1 : 0,
- simTrigger.getStateEnergySumLow() ? 1 : 0,
- simTrigger.getStateEnergySumHigh() ? 1 : 0,
- simTrigger.getStateEnergyDifference() ? 1 : 0,
- simTrigger.getStateEnergySlope() ? 1 : 0,
- simTrigger.getStateCoplanarity() ? 1 : 0);
- }
- }
- if(reconPairsTriggers.get(0).size() + reconPairsTriggers.get(1).size() == 0) {
- println("\tNone");
- }
-
- // Output the SSP reported triggers.
- println("SSP Reported Pair Triggers");
- for(SSPPairTrigger sspTrigger : sspTriggers) {
- // Increment the number of SSP cluster singles triggers.
- sspReportedTriggers++;
-
- // Get the trigger properties.
- int triggerNum = sspTrigger.isFirstTrigger() ? 1 : 2;
-
- // Print the trigger.
- printf("\tTrigger %d :: %3d ns :: ESum: %d, EDiff: %d, ESlope: %d, Coplanarity: %d%n",
- triggerNum, sspTrigger.getTime(),
- sspTrigger.passCutEnergySum() ? 1 : 0, sspTrigger.passCutEnergyDifference() ? 1 : 0,
- sspTrigger.passCutEnergySlope() ? 1 : 0, sspTrigger.passCutCoplanarity() ? 1 : 0);
- }
- if(sspReportedTriggers == 0) { println("\tNone"); }
-
-
-
- // ==========================================================
- // ==== SSP Internal Logic Verification =====================
- // ==========================================================
-
- // Track which SSP triggers have been matched to avoid matching
- // multiple reconstructed SSP cluster triggers to the same SSP
- // trigger.
- Set<SSPPairTrigger> sspTriggerSet = new HashSet<SSPPairTrigger>();
- Set<PairTrigger<SSPCluster[]>> simTriggerSet = new HashSet<PairTrigger<SSPCluster[]>>();
-
- // Track the number of SSP reported triggers that are found in
- // excess of the SSP simulated triggers.
- int extraTriggers = sspTriggers.size() - (sspPairsTriggers.get(0).size() + sspPairsTriggers.get(1).size());
- if(extraTriggers > 0) {
- sspReportedExtras += extraTriggers;
- pairInternalFail = true;
- }
-
- // Iterate over the triggers.
- println();
- println("SSP Reported Trigger --> SSP Cluster Trigger Match Status");
- for(SSPPairTrigger sspTrigger : sspTriggers) {
- // Get the trigger information.
- int triggerNum = sspTrigger.isFirstTrigger() ? 0 : 1;
- boolean matchedTrigger = false;
-
- // Iterate over the SSP cluster simulated triggers and
- // look for a trigger that matches.
- matchLoop:
- for(PairTrigger<SSPCluster[]> simTrigger : sspPairsTriggers.get(triggerNum)) {
- // If the current SSP trigger has already been
- // matched, skip it.
- if(sspTriggerSet.contains(sspTrigger)) { continue matchLoop; }
-
- // Otherwise, check whether the reconstructed SSP
- // cluster trigger matches the SSP trigger.
- if(compareSSPPairTriggers(sspTrigger, simTrigger)) {
- matchedTrigger = true;
- sspTriggerSet.add(sspTrigger);
- simTriggerSet.add(simTrigger);
- sspInternalMatched++;
- break matchLoop;
- }
-
- printf("\tTrigger %d :: %3d ns :: ESum: %d, EDiff: %d, ESlope: %d, Coplanarity: %d :: Matched: %5b%n",
- triggerNum, sspTrigger.getTime(), sspTrigger.passCutEnergySum() ? 1 : 0,
- sspTrigger.passCutEnergyDifference() ? 1 : 0, sspTrigger.passCutEnergySlope() ? 1 : 0,
- sspTrigger.passCutCoplanarity() ? 1 : 0, matchedTrigger);
- }
- }
-
- // Iterate over the unmatched simulated triggers again and the
- // unmatched SSP reported trigger that most closely matches it.
- simLoop:
- for(int triggerNum = 0; triggerNum < 2; triggerNum++) {
- for(PairTrigger<SSPCluster[]> simTrigger : sspPairsTriggers.get(triggerNum)) {
- // Check whether this trigger has already been matched
- // or not. If it has been matched, skip it.
- if(simTriggerSet.contains(simTrigger)) { continue simLoop; }
-
- // Get the trigger time.
- int simTime = 0;
- if(simTrigger.getTriggerSource()[0].getYIndex() < 0) {
- simTime = simTrigger.getTriggerSource()[0].getTime();
- } else { simTime = simTrigger.getTriggerSource()[1].getTime(); }
-
- // Track the match statistics for each reported trigger
- // so that the closest match may be found.
- int numMatched = -1;
- boolean foundBest = false;
- boolean[] matchedCut = new boolean[4];
-
- // Iterate over the reported triggers to find a match.
- reportedLoop:
- for(SSPPairTrigger sspTrigger : sspTriggers) {
- // If the two triggers have different times, this
- // trigger should be skipped.
- if(sspTrigger.getTime() != simTime) { continue reportedLoop; }
-
- // If this reported trigger has been matched then
- // it should be skipped.
- if(sspTriggerSet.contains(sspTrigger)) { continue reportedLoop; }
-
- // Check each of the cuts.
- boolean[] tempMatchedCut = new boolean[4];
- tempMatchedCut[0] = (simTrigger.getStateEnergySum() == sspTrigger.passCutEnergySum());
- tempMatchedCut[1] = (simTrigger.getStateEnergyDifference() == sspTrigger.passCutEnergyDifference());
- tempMatchedCut[2] = (simTrigger.getStateEnergySlope() == sspTrigger.passCutEnergySlope());
- tempMatchedCut[3] = (simTrigger.getStateCoplanarity() == sspTrigger.passCutCoplanarity());
-
- // Check each cut and see if this is a closer match
- // than the previous best match.
- int tempNumMatched = 0;
- for(boolean passed : tempMatchedCut) { if(passed) { tempNumMatched++; } }
-
- // If the number of matched cuts exceeds the old
- // best result, this becomes the new best result.
- if(tempNumMatched > numMatched) {
- foundBest = true;
- numMatched = tempNumMatched;
- matchedCut = tempMatchedCut;
- }
- }
-
- // If some match was found, note what caused it to not
- // qualify as a complete match.
- if(foundBest) {
- if(!matchedCut[0]) { eventEnergySum[triggerNum]++; }
- if(!matchedCut[1]) { eventEnergyDiff[triggerNum]++; }
- if(!matchedCut[2]) { eventEnergySlope[triggerNum]++; }
- if(!matchedCut[3]) { eventCoplanarity[triggerNum]++; }
- }
-
- // If there was no match found, it means that there were
- // no triggers that were both unmatched and at the same
- // time as this simulated trigger.
- else {
- eventTime[triggerNum]++;
- pairInternalFail = true;
- }
- }
- }
-
-
-
- // ==========================================================
- // ==== SSP Pair Trigger Efficiency =========================
- // ==========================================================
-
- // Reset the SSP matched trigger set.
- sspTriggerSet.clear();
-
- // Iterate over the reconstructed cluster pair triggers.
- println();
- println("Recon Cluster Trigger --> SSP Reported Trigger Match Status");
- for(int triggerNum = 0; triggerNum < 2; triggerNum++) {
- for(PairTrigger<Cluster[]> simTrigger : reconPairsTriggers.get(triggerNum)) {
- // Track whether the trigger was matched.
- boolean matchedTrigger = false;
-
- // Iterate over the SSP reported triggers and compare
- // them to the reconstructed cluster simulated trigger.
- matchLoop:
- for(SSPTrigger sspTrigger : sspTriggers) {
- // Only compare pair triggers.
- if(sspTrigger instanceof SSPPairTrigger) {
- // Cast the trigger.
- SSPPairTrigger sspPair = (SSPPairTrigger) sspTrigger;
-
- // Only compare the pair trigger if it was
- // not already matched to another trigger.
- if(sspTriggerSet.contains(sspPair)) { continue matchLoop; }
-
- // Compare the triggers.
- if(compareReconPairTriggers(sspPair, simTrigger)) {
- reconTriggersMatched++;
- matchedTrigger = true;
- sspTriggerSet.add(sspPair);
- break matchLoop;
- }
- }
- }
-
- // Print the trigger matching status.
- printf("\tTrigger %d :: %s, %s :: EClusterLow: %d; EClusterHigh %d; HitCount: %d; ESumLow: %d, ESumHigh: %d, EDiff: %d, ESlope: %d, Coplanarity: %d :: Matched: %5b%n",
- (triggerNum + 1), clusterPositionString(simTrigger.getTriggerSource()[0]),
- clusterPositionString(simTrigger.getTriggerSource()[1]),
- simTrigger.getStateClusterEnergyLow() ? 1 : 0,
- simTrigger.getStateClusterEnergyHigh() ? 1 : 0,
- simTrigger.getStateHitCount() ? 1 : 0,
- simTrigger.getStateEnergySumLow() ? 1 : 0,
- simTrigger.getStateEnergySumHigh() ? 1 : 0,
- simTrigger.getStateEnergyDifference() ? 1 : 0,
- simTrigger.getStateEnergySlope() ? 1 : 0,
- simTrigger.getStateCoplanarity() ? 1 : 0, matchedTrigger);
- }
- }
-
-
-
- // ==========================================================
- // ==== Output Event Results ================================
- // ==========================================================
-
- // Get the number of SSP and reconstructed cluster simulated
- // triggers.
- int sspSimTriggers = sspPairsTriggers.get(0).size() + sspPairsTriggers.get(1).size();
- int reconSimTriggers = reconPairsTriggers.get(0).size() + reconPairsTriggers.get(1).size();
- int halfSimTriggers = sspSimTriggers / 2;
-
- // Print event statistics.
- println();
- println("Event Statistics:");
- printf("\tSSP Cluster Sim Triggers :: %d%n", sspSimTriggers);
- printf("\tRecon Cluster Sim Triggers :: %d%n", reconSimTriggers);
- printf("\tSSP Reported Triggers :: %d%n", sspReportedTriggers);
- if(sspSimTriggers == 0) {
- printf("\tInternal Efficiency :: %d / %d (N/A)%n",
- sspInternalMatched, sspSimTriggers);
- } else {
- printf("\tInternal Efficiency :: %d / %d (%3.0f%%)%n",
- sspInternalMatched, sspSimTriggers, (100.0 * sspInternalMatched / sspSimTriggers));
- }
- if(reconSimTriggers == 0) {
- printf("\tTrigger Efficiency :: %d / %d (N/A)%n",
- reconTriggersMatched, reconSimTriggers);
- } else {
- printf("\tTrigger Efficiency :: %d / %d (%3.0f%%)%n",
- reconTriggersMatched, reconSimTriggers, (100.0 * reconTriggersMatched / reconSimTriggers));
- }
-
- // Print the individual cut performances.
- for(int triggerNum = 0; triggerNum < 2; triggerNum++) {
- println();
- printf("Trigger %d Individual Cut Failure Rate:%n", (triggerNum + 1));
- if(sspSimTriggers == 0) {
- printf("\tPair Energy Sum :: %d / %d%n", eventEnergySum[triggerNum], halfSimTriggers);
- printf("\tPair Energy Difference :: %d / %d%n", eventEnergyDiff[triggerNum], halfSimTriggers);
- printf("\tPair Energy Slope :: %d / %d%n", eventEnergySlope[triggerNum], halfSimTriggers);
- printf("\tPair Coplanarity :: %d / %d%n", eventCoplanarity[triggerNum], halfSimTriggers);
- printf("\tPair Trigger Time :: %d / %d%n", eventTime[triggerNum], halfSimTriggers);
- } else {
- printf("\tPair Energy Sum :: %d / %d (%3.0f%%)%n",
- eventEnergySum[triggerNum], halfSimTriggers, (100.0 * eventEnergySum[triggerNum] / halfSimTriggers));
- printf("\tPair Energy Difference :: %d / %d (%3.0f%%)%n",
- eventEnergyDiff[triggerNum], halfSimTriggers, (100.0 * eventEnergyDiff[triggerNum] / halfSimTriggers));
- printf("\tPair Energy Slope :: %d / %d (%3.0f%%)%n",
- eventEnergySlope[triggerNum], halfSimTriggers, (100.0 * eventEnergySlope[triggerNum] / halfSimTriggers));
- printf("\tPair Coplanarity :: %d / %d (%3.0f%%)%n",
- eventCoplanarity[triggerNum], halfSimTriggers, (100.0 * eventCoplanarity[triggerNum] / halfSimTriggers));
- printf("\tPair Trigger Time :: %d / %d (%3.0f%%)%n",
- eventTime[triggerNum], halfSimTriggers, (100.0 * eventTime[triggerNum] / halfSimTriggers));
- }
- printf("\tExcess Reported Triggers :: %d%n", sspReportedExtras / 2);
- }
-
- // Update the global trigger tracking variables.
- pairSSPTriggers += sspSimTriggers;
- pairReconMatched += reconTriggersMatched;
- pairReconTriggers += reconSimTriggers;
- pairInternalMatched += sspInternalMatched;
- pairReportedTriggers += sspReportedTriggers;
- pairReportedExtras += sspReportedExtras;
-
- for(int triggerNum = 0; triggerNum < 2; triggerNum++) {
- globalEnergySumCut[triggerNum] += eventEnergySum[triggerNum];
- globalEnergyDiffCut[triggerNum] += eventEnergyDiff[triggerNum];
- globalEnergySlopeCut[triggerNum] += eventEnergySlope[triggerNum];
- globalCoplanarityCut[triggerNum] += eventCoplanarity[triggerNum];
- globalPairTimeCut[triggerNum] += eventTime[triggerNum];
- }
-
- // Note whether the was a singles trigger match failure.
- if((reconTriggersMatched - reconSimTriggers != 0) || (sspInternalMatched - sspSimTriggers != 0)) {
- pairEfficiencyFail = true;
+ if(isSingles) { singlesEfficiencyFail = true; }
+ else { pairEfficiencyFail = true; }
}
}
@@ -2031,6 +1716,41 @@
}
/**
+ * Compares an SSP trigger with a simulated trigger. Note that only
+ * certain class combinations are supported. Triggers of the type
+ * <code>SSPSinglesTrigger</code> may be compared with triggers of
+ * the type <code>SinglesTrigger<SSPCluster></code> and triggers of
+ * the type <code>SSPPairTrigger</code> may be compared to either
+ * <code>PairTrigger<SSPCluster[]></code> triggers objects.
+ * @param bankTrigger - The SSP bank trigger.
+ * @param simTrigger - The simulated trigger.
+ * @return Returns <code>true</code> if the triggers are valid
+ * matches and <code>false</code> if they are not.
+ * @throws IllegalArgumentException Occurs if the trigger types
+ * are not of a supported type.
+ */
+ @SuppressWarnings("unchecked")
+ private static final boolean compareTriggers(SSPNumberedTrigger bankTrigger, Trigger<?> simTrigger) throws IllegalArgumentException {
+ // Get the classes of the arguments. This is used to check the
+ // generic type of the Trigger<?> object, and means that the
+ // "unchecked" warnings can be safely ignored.
+ Object source = simTrigger.getTriggerSource();
+
+ // If the combination of classes is supported, pass the triggers
+ // to the appropriate handler.
+ if(bankTrigger instanceof SSPSinglesTrigger && simTrigger instanceof SinglesTrigger && source instanceof SSPCluster) {
+ return compareSSPSinglesTriggers((SSPSinglesTrigger) bankTrigger, (SinglesTrigger<SSPCluster>) simTrigger);
+ } else if(bankTrigger instanceof SSPPairTrigger && simTrigger instanceof PairTrigger && source instanceof SSPCluster[]) {
+ return compareSSPPairTriggers((SSPPairTrigger) bankTrigger, (PairTrigger<SSPCluster[]>) simTrigger);
+ }
+
+ // Otherwise, the trigger combination is not supported. Produce
+ // and exception.
+ throw new IllegalArgumentException(String.format("Trigger type \"%s\" can not be compared to trigger type \"%s\" with source type \"%s\".",
+ bankTrigger.getClass().getSimpleName(), simTrigger.getClass().getSimpleName(), source.getClass().getSimpleName()));
+ }
+
+ /**
* Compares a trigger from the SSP bank to a trigger simulated on
* an SSP cluster.
* @param bankTrigger - The trigger from the SSP bank.
@@ -2088,40 +1808,6 @@
// If the time stamp is the same, check that the trigger flags
// are all the same. Start with energy sum.
- if(bankTrigger.passCutEnergySum() != simTrigger.getStateEnergySum()) {
- return false;
- }
-
- // Check pair energy difference.
- if(bankTrigger.passCutEnergyDifference() != simTrigger.getStateEnergyDifference()) {
- return false;
- }
-
- // Check pair energy slope.
- if(bankTrigger.passCutEnergySlope() != simTrigger.getStateEnergySlope()) {
- return false;
- }
-
- // Check pair coplanarity.
- if(bankTrigger.passCutCoplanarity() != simTrigger.getStateCoplanarity()) {
- return false;
- }
-
- // If all of the tests are successful, the triggers match.
- return true;
- }
-
- /**
- * Compares a trigger from the SSP bank to a trigger simulated on
- * an reconstructed cluster.
- * @param bankTrigger - The trigger from the SSP bank.
- * @param simTrigger - The trigger from the simulation.
- * @return Returns <code>true</code> if the triggers match and
- * <code>false</code> if they do not.
- */
- private static final boolean compareReconPairTriggers(SSPPairTrigger bankTrigger, PairTrigger<Cluster[]> simTrigger) {
- // Check that the trigger flags are all the same. Start with
- // energy sum.
if(bankTrigger.passCutEnergySum() != simTrigger.getStateEnergySum()) {
return false;
}
@@ -2301,6 +1987,138 @@
}
/**
+ * Gets the position of the source of a <code>Trigger</code> object
+ * as text. This method only supports trigger sources of the types
+ * <code>SSPCluster</code>, <code>Cluster</code>, and arrays of size
+ * two of either type.
+ * @param trigger - The trigger from which to obtain the source.
+ * @return Returns the source of the trigger as a <code>String</code>
+ * object.
+ * @throws IllegalArgumentException Occurs if the source of the
+ * trigger is not any of the supported types.
+ */
+ private static final String triggerPositionString(Trigger<?> trigger) throws IllegalArgumentException {
+ // Get the trigger source.
+ Object source = trigger.getTriggerSource();
+
+ // Handle valid trigger sources.
+ if(source instanceof SSPCluster) {
+ return clusterPositionString((SSPCluster) source);
+ } else if(source instanceof Cluster) {
+ return clusterPositionString((Cluster) source);
+ } else if(source instanceof SSPCluster[]) {
+ SSPCluster[] sourcePair = (SSPCluster[]) source;
+ if(sourcePair.length == 2) {
+ return String.format("%s, %s", clusterPositionString(sourcePair[0]),
+ clusterPositionString(sourcePair[1]));
+ }
+ } else if(source instanceof Cluster[]) {
+ Cluster[] sourcePair = (Cluster[]) source;
+ if(sourcePair.length == 2) {
+ return String.format("%s, %s", clusterPositionString(sourcePair[0]),
+ clusterPositionString(sourcePair[1]));
+ }
+ }
+
+ // Otherwise, the source type is unrecognized. Throw an error.
+ throw new IllegalArgumentException(String.format("Trigger source type \"%s\" is not supported.",
+ trigger.getTriggerSource().getClass().getSimpleName()));
+ }
+
+ /**
+ * Gets the time of a simulated trigger object. Method supports
+ * triggers with source objects of type <code>SSPCluster</code>,
+ * <code>Cluster</code>, and arrays of size two composed of either
+ * object type.
+ * @param trigger - The trigger.
+ * @return Returns the time at which the trigger occurred.
+ * @throws IllegalArgumentException Occurs if the trigger source
+ * is not a supported type.
+ */
+ private static final double getTriggerTime(Trigger<?> trigger) throws IllegalArgumentException {
+ // Get the trigger source.
+ Object source = trigger.getTriggerSource();
+
+ // Get the trigger time for supported trigger types.
+ if(source instanceof SSPCluster) {
+ return ((SSPCluster) source).getTime();
+ } else if(source instanceof Cluster) {
+ return TriggerDiagnosticUtil.getClusterTime((Cluster) source);
+ } else if(source instanceof SSPCluster[]) {
+ // Get the pair.
+ SSPCluster[] sourcePair = (SSPCluster[]) source;
+
+ // Get the time of the bottom cluster.
+ if(sourcePair.length == 2) {
+ if(sourcePair[0].getYIndex() < 0) { return sourcePair[0].getTime(); }
+ else if(sourcePair[1].getYIndex() < 0) { return sourcePair[1].getTime(); }
+ else { throw new IllegalArgumentException("Cluster pairs must be formed of a top/bottom pair."); }
+ }
+ else { throw new IllegalArgumentException("Cluster pairs must be of size 2."); }
+ } else if(source instanceof Cluster[]) {
+ // Get the pair.
+ Cluster[] sourcePair = (Cluster[]) source;
+ int[] iy = {
+ TriggerDiagnosticUtil.getYIndex(sourcePair[0]),
+ TriggerDiagnosticUtil.getYIndex(sourcePair[1])
+ };
+
+ // Get the time of the bottom cluster.
+ if(sourcePair.length == 2) {
+ if(iy[0] < 0) { return TriggerDiagnosticUtil.getClusterTime(sourcePair[0]); }
+ else if(iy[1] < 0) { return TriggerDiagnosticUtil.getClusterTime(sourcePair[1]); }
+ else { throw new IllegalArgumentException("Cluster pairs must be formed of a top/bottom pair."); }
+ }
+ else { throw new IllegalArgumentException("Cluster pairs must be of size 2."); }
+ }
+
+ // If the source type is unrecognized, throw an exception.
+ throw new IllegalArgumentException(String.format("Trigger source type \"%\" is not supported.",
+ source.getClass().getSimpleName()));
+ }
+
+ private static final boolean[] triggerCutMatch(Trigger<?> simTrigger, SSPTrigger sspTrigger) {
+ // Check that the cuts match for supported trigger types.
+ if(simTrigger instanceof SinglesTrigger && sspTrigger instanceof SSPSinglesTrigger) {
+ // Create an array to store the cut checks.
+ boolean[] cutMatch = new boolean[3];
+
+ // Cast the triggers.
+ SinglesTrigger<?> simSingles = (SinglesTrigger<?>) simTrigger;
+ SSPSinglesTrigger sspSingles = (SSPSinglesTrigger) sspTrigger;
+
+ // Perform the check.
+ cutMatch[ENERGY_MIN] = (simSingles.getStateClusterEnergyLow() == sspSingles.passCutEnergyMin());
+ cutMatch[ENERGY_MAX] = (simSingles.getStateClusterEnergyHigh() == sspSingles.passCutEnergyMax());
+ cutMatch[HIT_COUNT] = (simSingles.getStateHitCount() == sspSingles.passCutHitCount());
+
+ // Return the match array.
+ return cutMatch;
+ } else if(simTrigger instanceof PairTrigger && sspTrigger instanceof SSPPairTrigger) {
+ // Create an array to store the cut checks.
+ boolean[] cutMatch = new boolean[4];
+
+ // Cast the triggers.
+ PairTrigger<?> simPair = (PairTrigger<?>) simTrigger;
+ SSPPairTrigger sspPair = (SSPPairTrigger) sspTrigger;
+
+ // Perform the check.
+ cutMatch[ENERGY_SUM] = (simPair.getStateEnergySum() == sspPair.passCutEnergySum());
+ cutMatch[ENERGY_DIFF] = (simPair.getStateEnergyDifference() == sspPair.passCutEnergyDifference());
+ cutMatch[ENERGY_SLOPE] = (simPair.getStateEnergySlope() == sspPair.passCutEnergySlope());
+ cutMatch[COPLANARITY] = (simPair.getStateCoplanarity() == sspPair.passCutCoplanarity());
+
+ // Return the match array.
+ return cutMatch;
+ }
+
+ // If this point is reached, the triggers are not of a supported
+ // type for cut comparison. Produce an exception.
+ throw new IllegalArgumentException(String.format("Triggers of type \"%s\" can not be cut-matched with triggers of type \"%s\".",
+ simTrigger.getClass().getSimpleName(), sspTrigger.getClass().getSimpleName()));
+ }
+
+ /**
* Class <code>Pair</code> provides a convenient means of putting
* a reconstructed cluster and an SSP cluster in the same object
* for cluster matching.
Added: java/trunk/users/src/main/java/org/hps/users/kmccarty/TriggerDiagnosticGUIDriver.java
=============================================================================
--- java/trunk/users/src/main/java/org/hps/users/kmccarty/TriggerDiagnosticGUIDriver.java (added)
+++ java/trunk/users/src/main/java/org/hps/users/kmccarty/TriggerDiagnosticGUIDriver.java Tue Mar 3 16:01:55 2015
@@ -0,0 +1,43 @@
+package org.hps.users.kmccarty;
+
+import java.util.List;
+
+import javax.swing.JFrame;
+
+import org.hps.users.kmccarty.diagpanel.ClusterTablePanel;
+import org.lcsim.event.EventHeader;
+import org.lcsim.util.Driver;
+
+public class TriggerDiagnosticGUIDriver extends Driver {
+ private JFrame window = new JFrame();
+ private ClusterTablePanel clusterTable = new ClusterTablePanel();
+ private String diagnosticCollectionName = "DiagnosticSnapshot";
+
+ @Override
+ public void startOfData() {
+ window.add(clusterTable);
+ window.setVisible(true);
+ window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+ window.setSize(500, 400);
+ }
+
+ @Override
+ public void process(EventHeader event) {
+ // Updates are only performed if a diagnostic snapshot object
+ // exists. Otherwise, do nothing.
+ if(event.hasCollection(DiagSnapshot.class, diagnosticCollectionName)) {
+ // Get the snapshot collection.
+ List<DiagSnapshot> snapshotList = event.get(DiagSnapshot.class, diagnosticCollectionName);
+
+ // Get the snapshot. There will only ever be one.
+ DiagSnapshot snapshot = snapshotList.get(0);
+
+ // Feed it to the table.
+ clusterTable.updatePanel(snapshot);
+ }
+ }
+
+ public void setDiagnosticCollectionName(String name) {
+ diagnosticCollectionName = name;
+ }
+}
Added: java/trunk/users/src/main/java/org/hps/users/kmccarty/diagpanel/AbstractTablePanel.java
=============================================================================
--- java/trunk/users/src/main/java/org/hps/users/kmccarty/diagpanel/AbstractTablePanel.java (added)
+++ java/trunk/users/src/main/java/org/hps/users/kmccarty/diagpanel/AbstractTablePanel.java Tue Mar 3 16:01:55 2015
@@ -0,0 +1,230 @@
+package org.hps.users.kmccarty.diagpanel;
+
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.Font;
+import java.awt.event.ComponentAdapter;
+import java.awt.event.ComponentEvent;
+
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JTable;
+
+/**
+ * Class <code>AbstractTablePanel</code> displays two <code>JTable</code>
+ * objects side-by-side with headers above them. The left table displays
+ * statistical data for recent events processed with trigger diagnostics
+ * while the right table displays the same, but over the course of the
+ * entire run.<br/>
+ * <br/>
+ * This implements the interface <code>DiagnosticUpdatable</code>.
+ *
+ * @author Kyle McCarty <[log in to unmask]>
+ * @see JPanel
+ * @see DiagnosticUpdatable
+ */
+public abstract class AbstractTablePanel extends JPanel implements DiagnosticUpdatable {
+ // Static variables.
+ private static final long serialVersionUID = 0L;
+
+ // Table models.
+ private final TableTextModel localModel;
+ private final TableTextModel globalModel;
+
+ // Components.
+ private JTable localTable;
+ private JLabel localHeader;
+ private JTable globalTable;
+ private JLabel globalHeader;
+ private Dimension defaultPrefSize = new Dimension(0, 0);
+ private Dimension userPrefSize = null;
+
+ // Table model mappings.
+ private static final int COL_TITLE = 0;
+ private static final int COL_VALUE = 1;
+
+ /**
+ * Instantiates an <code>AbstractTablePanel</code> with a number
+ * of rows equal to the length of the argument array. Note that
+ * the panel requires that there be at least one row.
+ * @param rowNames - An array of <code>String</code> objects that
+ * are to be displayed for the names of the table rows.
+ */
+ public AbstractTablePanel(String[] rowNames) {
+ // Initialize the table models. They should have two columns
+ // (one for values and one for headers) and a number of rows
+ // equal to the number of row names.
+ localModel = new TableTextModel(rowNames.length, 2);
+ globalModel = new TableTextModel(rowNames.length, 2);
+
+ // Initialize the titles.
+ for(int i = 0; i < rowNames.length; i++) {
+ localModel.setValueAt(rowNames[i], i, COL_TITLE);
+ globalModel.setValueAt(rowNames[i], i, COL_TITLE);
+ }
+ updatePanel(null);
+
+ // Define the panel layout.
+ //SpringLayout layout = new SpringLayout();
+ setLayout(null);
+
+ // Create header labels for the tables.
+ localHeader = new JLabel("Local Statistics");
+ localHeader.setHorizontalAlignment(JLabel.CENTER);
+ add(localHeader);
+
+ globalHeader = new JLabel("Run Statistics");
+ globalHeader.setHorizontalAlignment(JLabel.CENTER);
+ add(globalHeader);
+
+ // Create JTable objects to display the data.
+ localTable = new JTable(localModel);
+ localTable.setRowSelectionAllowed(false);
+ localTable.setColumnSelectionAllowed(false);
+ localTable.setCellSelectionEnabled(false);
+ add(localTable);
+
+ globalTable = new JTable(globalModel);
+ globalTable.setRowSelectionAllowed(false);
+ globalTable.setColumnSelectionAllowed(false);
+ globalTable.setCellSelectionEnabled(false);
+ add(globalTable);
+
+ // Track when the component changes size and reposition the
+ // components accordingly.
+ addComponentListener(new ComponentAdapter() {
+ @Override
+ public void componentResized(ComponentEvent e) { positionComponents(); }
+ });
+
+ // Define the component preferred size.
+ defaultPrefSize.width = localTable.getPreferredSize().width +
+ ComponentUtils.hinternal + globalTable.getPreferredSize().width;
+ defaultPrefSize.height = localTable.getPreferredSize().height +
+ ComponentUtils.vinternal + globalTable.getPreferredSize().height;
+ }
+
+ @Override
+ public Dimension getPreferredSize() {
+ // If there is a user-specified preferred size, return that.
+ if(userPrefSize == null) { return defaultPrefSize; }
+
+ // Otherwise, return the default calculated preferred size.
+ else { return userPrefSize; }
+ }
+
+ @Override
+ public void setBackground(Color bg) {
+ // Set the base component background.
+ super.setBackground(bg);
+
+ // If the components have been initialized, pass the background
+ // color change to them as appropriate. Note that the tables
+ // will always retain the same background color.
+ if(localTable != null) {
+ // Set the header backgrounds.
+ localHeader.setBackground(bg);
+ globalHeader.setBackground(bg);
+ }
+ }
+
+ @Override
+ public void setFont(Font font) {
+ // Set the base component font.
+ super.setFont(font);
+
+ // If the components have been initialized, pass the font change
+ // to them as appropriate.
+ if(localTable != null) {
+ // Set the table fonts.
+ localTable.setFont(font);
+ globalTable.setFont(font);
+
+ // Set the header fonts.
+ Font headerFont = font.deriveFont(Font.BOLD, (float) Math.ceil(font.getSize2D() * 1.3));
+ localHeader.setFont(headerFont);
+ globalHeader.setFont(headerFont);
+ }
+ }
+
+ @Override
+ public void setForeground(Color fg) {
+ // Set the base component foreground.
+ super.setForeground(fg);
+
+ // If the components have been initialized, pass the foreground
+ // color change to them as appropriate. Note that the tables
+ // will always retain the same foreground color.
+ if(localTable != null) {
+ // Set the header foregrounds.
+ localHeader.setForeground(fg);
+ globalHeader.setForeground(fg);
+ }
+ }
+
+ @Override
+ public void setPreferredSize(Dimension preferredSize) {
+ userPrefSize = preferredSize;
+ }
+
+ /**
+ * Sets the value of the indicated row for the global statistical
+ * table.
+ * @param rowIndex - The row.
+ * @param value - The new value.
+ */
+ protected void setGlobalRowValue(int rowIndex, String value) {
+ globalModel.setValueAt(value, rowIndex, COL_VALUE);
+ }
+
+ /**
+ * Sets the value of the indicated row for the local statistical
+ * table.
+ * @param rowIndex - The row.
+ * @param value - The new value.
+ */
+ protected void setLocalRowValue(int rowIndex, String value) {
+ localModel.setValueAt(value, rowIndex, COL_VALUE);
+ }
+
+ /**
+ * Repositions the components to the correct places on the parent
+ * <code>JPanel</code>. This should be run whenever the panel
+ * changes size.
+ */
+ private void positionComponents() {
+ // Do not update if the components have not been initialized.
+ if(localHeader == null) { return; }
+
+ // The local components get the left half of the panel and the
+ // global components the right. Find half of the panel width,
+ // accounting for the internal spacing. This is an internal
+ // component, so it does not employ additional spacing between
+ // itself and the parent component's edges.
+ int compWidth = (getWidth() - 10) / 2;
+
+ // If there is any width remaining, it goes to the spacing.
+ int horizontal = ComponentUtils.hinternal + (getWidth() - 10) % 2;
+
+ // Place the header labels. These are given their preferred
+ // height. Note that this means a very small panel may cut off
+ // some of the components. First, get the preferred height of
+ // the label with the larger preferred height. These should be
+ // the same thing, but just in case...
+ int labelHeight = localHeader.getPreferredSize().height;
+ if(labelHeight < globalHeader.getPreferredSize().height) {
+ labelHeight = globalHeader.getPreferredSize().height;
+ }
+
+ // Set the label sizes and positions.
+ localHeader.setBounds(0, 0, compWidth, labelHeight);
+ globalHeader.setLocation(ComponentUtils.getNextX(localHeader, horizontal), 0);
+ globalHeader.setSize(compWidth, labelHeight);
+
+ // The tables go under their respective labels and should fill
+ // the remainder of the label height.
+ int tableY = ComponentUtils.getNextY(localHeader, ComponentUtils.vinternal);
+ localTable.setBounds(0, tableY, compWidth, localTable.getPreferredSize().height);
+ globalTable.setBounds(globalHeader.getX(), tableY, compWidth, globalTable.getPreferredSize().height);
+ }
+}
Added: java/trunk/users/src/main/java/org/hps/users/kmccarty/diagpanel/ClusterTablePanel.java
=============================================================================
--- java/trunk/users/src/main/java/org/hps/users/kmccarty/diagpanel/ClusterTablePanel.java (added)
+++ java/trunk/users/src/main/java/org/hps/users/kmccarty/diagpanel/ClusterTablePanel.java Tue Mar 3 16:01:55 2015
@@ -0,0 +1,111 @@
+package org.hps.users.kmccarty.diagpanel;
+
+import org.hps.users.kmccarty.DiagSnapshot;
+
+/**
+ * Class <code>ClusterTablePanel</code> is an implementation of class
+ * <code>AbstractTablePanel</code> for cluster statistical data.<br/>
+ * <br/>
+ * This implements the interface <code>DiagnosticUpdatable</code>.
+ *
+ * @author Kyle McCarty <[log in to unmask]>
+ * @see AbstractTablePanel
+ */
+public class ClusterTablePanel extends AbstractTablePanel {
+ // Static variables.
+ private static final long serialVersionUID = 0L;
+ private static final String[] TABLE_TITLES = { "Recon Clusters:", "SSP Clusters", "Matched Clusters",
+ "Failed (Position)", "Failed (Energy)", "Failed (Hit Count)" };
+
+ // Table model mappings.
+ private static final int ROW_RECON_COUNT = 0;
+ private static final int ROW_SSP_COUNT = 1;
+ private static final int ROW_MATCHED = 2;
+ private static final int ROW_FAILED_POSITION = 3;
+ private static final int ROW_FAILED_ENERGY = 4;
+ private static final int ROW_FAILED_HIT_COUNT = 5;
+
+ /**
+ * Instantiate a new <code>ClusterTablePanel</code>.
+ */
+ public ClusterTablePanel() { super(TABLE_TITLES); }
+
+ @Override
+ public void updatePanel(DiagSnapshot snapshot) {
+ // If the snapshot is null, all values should be "N/A."
+ if(snapshot == null) {
+ // Output cluster count data.
+ String scalerNullValue = "---";
+ setLocalRowValue(ROW_RECON_COUNT, scalerNullValue);
+ setLocalRowValue(ROW_SSP_COUNT, scalerNullValue);
+ setGlobalRowValue(ROW_RECON_COUNT, scalerNullValue);
+ setGlobalRowValue(ROW_SSP_COUNT, scalerNullValue);
+
+ // Output the tracked statistical data.
+ String percentNullValue = "--- / --- (---%)";
+ setLocalRowValue(ROW_MATCHED, percentNullValue);
+ setLocalRowValue(ROW_FAILED_POSITION, percentNullValue);
+ setLocalRowValue(ROW_FAILED_ENERGY, percentNullValue);
+ setLocalRowValue(ROW_FAILED_HIT_COUNT, percentNullValue);
+ setGlobalRowValue(ROW_MATCHED, percentNullValue);
+ setGlobalRowValue(ROW_FAILED_POSITION, percentNullValue);
+ setGlobalRowValue(ROW_FAILED_ENERGY, percentNullValue);
+ setGlobalRowValue(ROW_FAILED_HIT_COUNT, percentNullValue);
+ }
+
+ // Otherwise, populate the table with the diagnostic data.
+ else {
+ /*
+ * This is disabled until the snapshot object is stable and
+ * is subject to change. It will not work if enabled now.
+ // Get the largest number of digits in any of the values.
+ int mostDigits = 0;
+ for(int valueID = 0; valueID < DiagSnapshot.CL_BANK_SIZE; valueID++) {
+ int localDigits = ComponentUtils.getDigits(snapshot.getClusterValue(LOCAL, valueID));
+ int globalDigits = ComponentUtils.getDigits(snapshot.getClusterValue(GLOBAL, valueID));
+ mostDigits = ComponentUtils.max(mostDigits, localDigits, globalDigits);
+ }
+
+ // Put the number of reconstructed and SSP clusters into
+ // the tables.
+ int[] clusterValue = {
+ snapshot.getClusterValue(LOCAL, DiagSnapshot.CL_VALUE_RECON_CLUSTERS),
+ snapshot.getClusterValue(LOCAL, DiagSnapshot.CL_VALUE_SSP_CLUSTERS),
+ snapshot.getClusterValue(GLOBAL, DiagSnapshot.CL_VALUE_RECON_CLUSTERS),
+ snapshot.getClusterValue(GLOBAL, DiagSnapshot.CL_VALUE_SSP_CLUSTERS)
+ };
+ String countFormat = "%" + mostDigits + "d";
+ setLocalRowValue(ROW_RECON_COUNT, String.format(countFormat, clusterValue[0]));
+ setLocalRowValue(ROW_SSP_COUNT, String.format(countFormat, clusterValue[1]));
+ setGlobalRowValue(ROW_RECON_COUNT, String.format(countFormat, clusterValue[2]));
+ setGlobalRowValue(ROW_SSP_COUNT, String.format(countFormat, clusterValue[3]));
+
+ // Output the tracked statistical data.
+ int total;
+ String percentFormat = "%" + mostDigits + "d / %" + mostDigits + "d (%7.3f)";
+ int[] statValue = {
+ snapshot.getClusterValue(DiagSnapshot.TYPE_LOCAL, DiagSnapshot.CL_VALUE_MATCHED),
+ snapshot.getClusterValue(DiagSnapshot.TYPE_LOCAL, DiagSnapshot.CL_VALUE_FAIL_POSITION),
+ snapshot.getClusterValue(DiagSnapshot.TYPE_LOCAL, DiagSnapshot.CL_VALUE_FAIL_ENERGY),
+ snapshot.getClusterValue(DiagSnapshot.TYPE_LOCAL, DiagSnapshot.CL_VALUE_FAIL_HIT_COUNT),
+ snapshot.getClusterValue(DiagSnapshot.TYPE_GLOBAL, DiagSnapshot.CL_VALUE_MATCHED),
+ snapshot.getClusterValue(DiagSnapshot.TYPE_GLOBAL, DiagSnapshot.CL_VALUE_FAIL_POSITION),
+ snapshot.getClusterValue(DiagSnapshot.TYPE_GLOBAL, DiagSnapshot.CL_VALUE_FAIL_ENERGY),
+ snapshot.getClusterValue(DiagSnapshot.TYPE_GLOBAL, DiagSnapshot.CL_VALUE_FAIL_HIT_COUNT)
+ };
+
+ total = snapshot.getClusterValue(DiagSnapshot.TYPE_LOCAL, DiagSnapshot.CL_VALUE_RECON_CLUSTERS);
+ setLocalRowValue(ROW_MATCHED, String.format(percentFormat, statValue[0], total, 100.0 * statValue[0] / total));
+ setLocalRowValue(ROW_FAILED_POSITION, String.format(percentFormat, statValue[1], total, 100.0 * statValue[1] / total));
+ setLocalRowValue(ROW_FAILED_ENERGY, String.format(percentFormat, statValue[2], total, 100.0 * statValue[2] / total));
+ setLocalRowValue(ROW_FAILED_HIT_COUNT, String.format(percentFormat, statValue[3], total, 100.0 * statValue[3] / total));
+
+ total = snapshot.getClusterValue(DiagSnapshot.TYPE_GLOBAL, DiagSnapshot.CL_VALUE_RECON_CLUSTERS);
+ setGlobalRowValue(ROW_MATCHED, String.format(percentFormat, statValue[4], total, 100.0 * statValue[4] / total));
+ setGlobalRowValue(ROW_FAILED_POSITION, String.format(percentFormat, statValue[5], total, 100.0 * statValue[5] / total));
+ setGlobalRowValue(ROW_FAILED_ENERGY, String.format(percentFormat, statValue[6], total, 100.0 * statValue[6] / total));
+ setGlobalRowValue(ROW_FAILED_HIT_COUNT, String.format(percentFormat, statValue[7], total, 100.0 * statValue[7] / total));
+ */
+ }
+ }
+}
Added: java/trunk/users/src/main/java/org/hps/users/kmccarty/diagpanel/ComponentUtils.java
=============================================================================
--- java/trunk/users/src/main/java/org/hps/users/kmccarty/diagpanel/ComponentUtils.java (added)
+++ java/trunk/users/src/main/java/org/hps/users/kmccarty/diagpanel/ComponentUtils.java Tue Mar 3 16:01:55 2015
@@ -0,0 +1,106 @@
+package org.hps.users.kmccarty.diagpanel;
+
+import java.awt.Component;
+
+import org.hps.users.kmccarty.TriggerDiagnosticUtil;
+
+/**
+ * Class <code>ComponentUtils</code> is a list of utility methods used
+ * by the trigger diagnostic GUI.
+ *
+ * @author Kyle McCarty <[log in to unmask]>
+ */
+class ComponentUtils {
+ /** The default spacing used between a horizontal edge of one
+ * component and the horizontal edge of another. */
+ public static final int hinternal = 10;
+ /** The default spacing used between a vertical edge of one
+ * component and the vertical edge of another. */
+ public static final int vinternal = 10;
+ /** The default spacing used between a horizontal edge of one
+ * component and the edge of its parent component. */
+ public static final int hexternal = 0;
+ /** The default spacing used between a vertical edge of one
+ * component and the edge of its parent component. */
+ public static final int vexternal = 0;
+
+ /**
+ * Gets the number of digits in the base-10 String representation
+ * of an integer primitive. Negative signs are not included in the
+ * digit count.
+ * @param value - The value of which to obtain the length.
+ * @return Returns the number of digits in the String representation
+ * of the argument value.
+ */
+ public static final int getDigits(int value) {
+ return TriggerDiagnosticUtil.getDigits(value);
+ }
+
+ /**
+ * Gets the x-coordinate immediately to the right of the given
+ * component.
+ * @param c - The component of which to find the edge.
+ * @return Returns the x-coordinate as an <code>int</code> value.
+ */
+ static final int getNextX(Component c) {
+ return getNextX(c, 0);
+ }
+
+ /**
+ * Gets the x-coordinate a given distance to the right edge of the
+ * argument component.
+ * @param c - The component of which to find the edge.
+ * @param spacing - The additional spacing past the edge of the
+ * component to add.
+ * @return Returns the x-coordinate as an <code>int</code> value.
+ */
+ static final int getNextX(Component c, int spacing) {
+ return c.getX() + c.getWidth() + spacing;
+ }
+
+ /**
+ * Gets the y-coordinate immediately below the given component.
+ * @param c - The component of which to find the edge.
+ * @return Returns the y-coordinate as an <code>int</code> value.
+ */
+ static final int getNextY(Component c) {
+ return getNextY(c, 0);
+ }
+
+ /**
+ * Gets the y-coordinate a given distance below the bottom edge
+ * of the argument component.
+ * @param c - The component of which to find the edge.
+ * @param spacing - The additional spacing past the edge of the
+ * component to add.
+ * @return Returns the y-coordinate as an <code>int</code> value.
+ */
+ static final int getNextY(Component c, int spacing) {
+ return c.getY() + c.getHeight() + spacing;
+ }
+
+ /**
+ * Gets the maximum value from a list of values.
+ * @param values - The values to compare.
+ * @return Returns the largest of the argument values.
+ * @throws IllegalArgumentException Occurs if no values are given.
+ */
+ public static final int max(int... values) throws IllegalArgumentException {
+ // Throw an error if no arguments are provided.
+ if(values == null || values.length == 0) {
+ throw new IllegalArgumentException("Can not determine maximum value from a list of 0 values.");
+ }
+
+ // If there is only one value, return it.
+ if(values.length == 1) { return values[0]; }
+
+ // Otherwise, get the largest value.
+ int largest = Integer.MIN_VALUE;
+ for(int value : values) {
+ if(value > largest) { largest = value; }
+ }
+
+ // Return the result.
+ return largest;
+ }
+}
Added: java/trunk/users/src/main/java/org/hps/users/kmccarty/diagpanel/DiagnosticUpdatable.java
=============================================================================
--- java/trunk/users/src/main/java/org/hps/users/kmccarty/diagpanel/DiagnosticUpdatable.java (added)
+++ java/trunk/users/src/main/java/org/hps/users/kmccarty/diagpanel/DiagnosticUpdatable.java Tue Mar 3 16:01:55 2015
@@ -0,0 +1,22 @@
+package org.hps.users.kmccarty.diagpanel;
+
+import org.hps.users.kmccarty.DiagSnapshot;
+
+/**
+ * Interface <code>DiagnosticUpdatable</code> defines a class of objects
+ * that can be updated with information from a trigger diagnostic driver.
+ * They can take snapshots of the driver results and use this in order to
+ * alter their displayed or constituent values.
+ *
+ * @author Kyle McCarty <[log in to unmask]>
+ * @see DiagSnapshot
+ */
+public interface DiagnosticUpdatable {
+ /**
+ * Updates the object with information from the trigger diagnostic
+ * snapshot in the argument.
+ * @param snapshot - The snapshot containing information with which
+ * to update the object.
+ */
+ public void updatePanel(DiagSnapshot snapshot);
+}
Added: java/trunk/users/src/main/java/org/hps/users/kmccarty/diagpanel/TableTextModel.java
=============================================================================
--- java/trunk/users/src/main/java/org/hps/users/kmccarty/diagpanel/TableTextModel.java (added)
+++ java/trunk/users/src/main/java/org/hps/users/kmccarty/diagpanel/TableTextModel.java Tue Mar 3 16:01:55 2015
@@ -0,0 +1,103 @@
+package org.hps.users.kmccarty.diagpanel;
+
+import javax.swing.table.AbstractTableModel;
+
+/**
+ * Class <code>TableTextModel</code> is a simple implementation of
+ * <code>AbstractTableModel</code> that supports a definable number
+ * of rows and columns which must be populated with <code>String</code>
+ * data.
+ *
+ * @author Kyle McCarty <[log in to unmask]>
+ */
+public class TableTextModel extends AbstractTableModel {
+ // Serial UID.
+ private static final long serialVersionUID = 0L;
+
+ // Stored values.
+ private final int rows, columns;
+ private final String[][] values;
+
+ /**
+ * Instantiates a new <code>TableTextModel</code> with the indicated
+ * number of rows and columns.
+ * @param rows - The number of rows.
+ * @param columns - The number of columns.
+ */
+ public TableTextModel(int rows, int columns) {
+ // Make sure that the arguments for rows and columns are valid.
+ if(rows < 1) {
+ throw new IllegalArgumentException("TableTextModel must have at least one row.");
+ } else if(columns < 1) {
+ throw new IllegalArgumentException("TableTextModel must have at least one column.");
+ }
+
+ // Define the number of rows and columns.
+ this.rows = rows;
+ this.columns = columns;
+
+ // Instantiate the data storage array.
+ values = new String[rows][columns];
+ }
+
+ @Override
+ public int getRowCount() { return rows; }
+
+ @Override
+ public int getColumnCount() { return columns; }
+
+ @Override
+ public Object getValueAt(int rowIndex, int columnIndex) {
+ // Ensure that the value is within the allowed range.
+ validateIndex(rowIndex, columnIndex);
+
+ // Return the value.
+ return values[rowIndex][columnIndex];
+ }
+
+ @Override
+ public void setValueAt(Object value, int rowIndex, int columnIndex) {
+ // If the object is a string, pass it to the preferred handler.
+ // This can also be performed if the value is null.
+ if(value == null || value instanceof String) {
+ setValueAt((String) value, rowIndex, columnIndex);
+ }
+
+ // Otherwise, cast the object to a string and use that instead.
+ else { setValueAt(value.toString(), rowIndex, columnIndex); }
+ }
+
+ /**
+ * Sets the text for the indicated column and row of the table.
+ * @param value - The new text.
+ * @param rowIndex - The row.
+ * @param columnIndex - The column.
+ * @throws IndexOutOfBoundsException Occurs if the row and column
+ * are not a valid member of table model.
+ */
+ public void setValueAt(String value, int rowIndex, int columnIndex) throws IndexOutOfBoundsException {
+ // Ensure that the value is within the allowed range.
+ validateIndex(rowIndex, columnIndex);
+
+ // Set the value.
+ values[rowIndex][columnIndex] = value;
+ }
+
+ /**
+ * Checks to make sure that a given row/column pointer refers to
+ * an extant position in the data array. In the event that the row
+ * and column values are not valid, an <code>IndexOutOfBounds</code>
+ * exception is thrown.
+ * @param rowIndex - The row index.
+ * @param columnIndex - The column index.
+ * @throws IndexOutOfBoundsException Occurs if the row and column
+ * are not a valid member of the data array.
+ */
+ private void validateIndex(int rowIndex, int columnIndex) throws IndexOutOfBoundsException {
+ if(rowIndex < 0 || rowIndex >= getRowCount()) {
+ throw new IndexOutOfBoundsException(String.format("Row index %d is out of bounds.", rowIndex));
+ } else if(columnIndex < 0 || columnIndex >= getColumnCount()) {
+ throw new IndexOutOfBoundsException(String.format("Column index %d is out of bounds.", columnIndex));
+ }
+ }
+}
|