Author: [log in to unmask] Date: Thu Mar 19 10:30:08 2015 New Revision: 2491 Log: Updated trigger diagnostic functionality and fixed a statistics tracking bug. Additionally, added in support for diagnostic trigger plots and their management. Added: java/trunk/analysis/src/main/java/org/hps/analysis/trigger/event/TriggerPlotsModule.java Modified: java/trunk/analysis/src/main/java/org/hps/analysis/trigger/TriggerDiagnosticDriver.java java/trunk/analysis/src/main/java/org/hps/analysis/trigger/event/TriggerMatchEvent.java java/trunk/analysis/src/main/java/org/hps/analysis/trigger/event/TriggerMatchStatus.java java/trunk/analysis/src/main/java/org/hps/analysis/trigger/event/TriggerMatchedPair.java java/trunk/analysis/src/main/java/org/hps/analysis/trigger/event/TriggerStatModule.java Modified: java/trunk/analysis/src/main/java/org/hps/analysis/trigger/TriggerDiagnosticDriver.java ============================================================================= --- java/trunk/analysis/src/main/java/org/hps/analysis/trigger/TriggerDiagnosticDriver.java (original) +++ java/trunk/analysis/src/main/java/org/hps/analysis/trigger/TriggerDiagnosticDriver.java Thu Mar 19 10:30:08 2015 @@ -22,6 +22,7 @@ import org.hps.analysis.trigger.event.TriggerEfficiencyModule; import org.hps.analysis.trigger.event.TriggerMatchEvent; import org.hps.analysis.trigger.event.TriggerMatchStatus; +import org.hps.analysis.trigger.event.TriggerPlotsModule; import org.hps.analysis.trigger.util.OutputLogger; import org.hps.analysis.trigger.util.Pair; import org.hps.analysis.trigger.util.PairTrigger; @@ -125,7 +126,14 @@ private static final int ENERGY_SLOPE = TriggerDiagnosticUtil.PAIR_ENERGY_SLOPE; private static final int COPLANARITY = TriggerDiagnosticUtil.PAIR_COPLANARITY; + // Cut names for logging. + private static final String[][] cutNames = { + { "E_min", "E_max", "hit count", "null" }, + { "E_sum", "E_diff", "E_slope", "coplanar" } + }; + // Temporary AIDA Plots + private TriggerPlotsModule globalTriggerPlots = new TriggerPlotsModule(0, 0); private static final int RECON = 0; private static final int SSP = 1; private static final int ALL = 0; @@ -134,58 +142,57 @@ private AIDA aida = AIDA.defaultInstance(); private IHistogram1D[][] clusterHitPlot = { { - aida.histogram1D("Trigger Diagnostics :: Recon Cluster Hit Count (All)", 9, 0.5, 9.5), - aida.histogram1D("Trigger Diagnostics :: Recon Cluster Hit Count (Matched)", 9, 0.5, 9.5), - aida.histogram1D("Trigger Diagnostics :: Recon Cluster Hit Count (Failed)", 9, 0.5, 9.5) + aida.histogram1D("cluster/Recon Cluster Hit Count (All)", 9, 0.5, 9.5), + aida.histogram1D("cluster/Recon Cluster Hit Count (Matched)", 9, 0.5, 9.5), + aida.histogram1D("cluster/Recon Cluster Hit Count (Failed)", 9, 0.5, 9.5) }, { - aida.histogram1D("Trigger Diagnostics :: SSP Cluster Hit Count (All)", 9, 0.5, 9.5), - aida.histogram1D("Trigger Diagnostics :: SSP Cluster Hit Count (Matched)", 9, 0.5, 9.5), - aida.histogram1D("Trigger Diagnostics :: SSP Cluster Hit Count (Failed)", 9, 0.5, 9.5) + aida.histogram1D("cluster/SSP Cluster Hit Count (All)", 9, 0.5, 9.5), + aida.histogram1D("cluster/SSP Cluster Hit Count (Matched)", 9, 0.5, 9.5), + aida.histogram1D("cluster/SSP Cluster Hit Count (Failed)", 9, 0.5, 9.5) } }; private IHistogram1D[][] clusterEnergyPlot = { { - aida.histogram1D("Trigger Diagnostics :: Recon Cluster Energy (All)", 300, 0.0, 3.0), - aida.histogram1D("Trigger Diagnostics :: Recon Cluster Energy (Matched)", 300, 0.0, 3.0), - aida.histogram1D("Trigger Diagnostics :: Recon Cluster Energy (Failed)", 300, 0.0, 3.0) + aida.histogram1D("cluster/Recon Cluster Energy (All)", 300, 0.0, 3.0), + aida.histogram1D("cluster/Recon Cluster Energy (Matched)", 300, 0.0, 3.0), + aida.histogram1D("cluster/Recon Cluster Energy (Failed)", 300, 0.0, 3.0) }, { - aida.histogram1D("Trigger Diagnostics :: SSP Cluster Energy (All)", 300, 0.0, 3.0), - aida.histogram1D("Trigger Diagnostics :: SSP Cluster Energy (Matched)", 300, 0.0, 3.0), - aida.histogram1D("Trigger Diagnostics :: SSP Cluster Energy (Failed)", 300, 0.0, 3.0) + aida.histogram1D("cluster/SSP Cluster Energy (All)", 300, 0.0, 3.0), + aida.histogram1D("cluster/SSP Cluster Energy (Matched)", 300, 0.0, 3.0), + aida.histogram1D("cluster/SSP Cluster Energy (Failed)", 300, 0.0, 3.0) } }; private IHistogram1D[][] clusterTimePlot = { { - aida.histogram1D("Trigger Diagnostics :: Recon Cluster Time (All)", 115, 0, 460), - aida.histogram1D("Trigger Diagnostics :: Recon Cluster Time (Matched)", 115, 0, 460), - aida.histogram1D("Trigger Diagnostics :: Recon Cluster Time (Failed)", 115, 0, 460) + aida.histogram1D("cluster/Recon Cluster Time (All)", 115, 0, 460), + aida.histogram1D("cluster/Recon Cluster Time (Matched)", 115, 0, 460), + aida.histogram1D("cluster/Recon Cluster Time (Failed)", 115, 0, 460) }, { - aida.histogram1D("Trigger Diagnostics :: SSP Cluster Time (All)", 115, 0, 460), - aida.histogram1D("Trigger Diagnostics :: SSP Cluster Time (Matched)", 115, 0, 460), - aida.histogram1D("Trigger Diagnostics :: SSP Cluster Time (Failed)", 115, 0, 460) + aida.histogram1D("cluster/SSP Cluster Time (All)", 115, 0, 460), + aida.histogram1D("cluster/SSP Cluster Time (Matched)", 115, 0, 460), + aida.histogram1D("cluster/SSP Cluster Time (Failed)", 115, 0, 460) } }; private IHistogram2D[][] clusterPositionPlot = { { - aida.histogram2D("Trigger Diagnostics :: Recon Cluster Position (All)", 47, -23.5, 23.5, 11, -5.5, 5.5), - aida.histogram2D("Trigger Diagnostics :: Recon Cluster Position (Matched)", 47, -23.5, 23.5, 11, -5.5, 5.5), - aida.histogram2D("Trigger Diagnostics :: Recon Cluster Position (Failed)", 47, -23.5, 23.5, 11, -5.5, 5.5) + aida.histogram2D("cluster/Recon Cluster Position (All)", 47, -23.5, 23.5, 11, -5.5, 5.5), + aida.histogram2D("cluster/Recon Cluster Position (Matched)", 47, -23.5, 23.5, 11, -5.5, 5.5), + aida.histogram2D("cluster/Recon Cluster Position (Failed)", 47, -23.5, 23.5, 11, -5.5, 5.5) }, { - aida.histogram2D("Trigger Diagnostics :: SSP Cluster Position (All)", 47, -23.5, 23.5, 11, -5.5, 5.5), - aida.histogram2D("Trigger Diagnostics :: SSP Cluster Position (Matched)", 47, -23.5, 23.5, 11, -5.5, 5.5), - aida.histogram2D("Trigger Diagnostics :: SSP Cluster Position (Failed)", 47, -23.5, 23.5, 11, -5.5, 5.5) + aida.histogram2D("cluster/SSP Cluster Position (All)", 47, -23.5, 23.5, 11, -5.5, 5.5), + aida.histogram2D("cluster/SSP Cluster Position (Matched)", 47, -23.5, 23.5, 11, -5.5, 5.5), + aida.histogram2D("cluster/SSP Cluster Position (Failed)", 47, -23.5, 23.5, 11, -5.5, 5.5) } }; private IHistogram2D[] energyhitDiffPlot = { - aida.histogram2D("Trigger Diagnostics :: Recon-SSP Energy-Hit Difference (All)", 60, -0.060, 0.060, 6, -3, 3), - aida.histogram2D("Trigger Diagnostics :: Recon-SSP Energy-Hit Difference (Matched)", 60, -0.060, 0.060, 6, -3, 3), - aida.histogram2D("Trigger Diagnostics :: Recon-SSP Energy-Hit Difference (Failed)", 60, -0.060, 0.060, 6, -3, 3) + aida.histogram2D("cluster/Recon-SSP Energy-Hit Difference (All)", 21, -0.010, 0.010, 6, -3, 3), + aida.histogram2D("cluster/Recon-SSP Energy-Hit Difference (Matched)", 21, -0.010, 0.010, 6, -3, 3), + aida.histogram2D("cluster/Recon-SSP Energy-Hit Difference (Failed)", 21, -0.010, 0.010, 6, -3, 3) }; - /** * Define the trigger modules. This should be replaced by parsing @@ -218,6 +225,10 @@ public void actionPerformed(ActionEvent e) { // Get the DAQ configuration. DAQConfig daq = ConfigurationManager.getInstance(); + + // Update the plotting energy slope values. + globalTriggerPlots.setEnergySlopeParamF(0, daq.getSSPConfig().getPair1Config().getEnergySlopeCutConfig().getParameterF()); + globalTriggerPlots.setEnergySlopeParamF(1, daq.getSSPConfig().getPair2Config().getEnergySlopeCutConfig().getParameterF()); // Load the DAQ settings from the configuration manager. singlesTrigger[0].loadDAQConfiguration(daq.getSSPConfig().getSingles1Config()); @@ -346,7 +357,33 @@ System.out.printf("\tPair Events Failed :: %d / %d (%7.3f%%)%n", failedPairEvents, totalEvents, (100.0 * failedPairEvents / totalEvents)); + // Print out how many events were triggered by a type along + // with how many were verified. + System.out.println(); + System.out.println("Event Failure Rate:"); + System.out.printf("\tSingles Trigger 1 :: %d / %d", + triggerRunStats[0].getEventsOfTypeSeen(0), triggerRunStats[0].getEventsOfType(0)); + if(triggerRunStats[0].getEventsOfType(0) != 0) { + System.out.printf(" %d / %d (%7.3f%%)%n", (100.0 * triggerRunStats[0].getEventsOfTypeSeen(0) / triggerRunStats[0].getEventsOfTypeSeen(0))); + } else { System.out.println(); } + System.out.printf("\tSingles Trigger 2 :: %d / %d", + triggerRunStats[0].getEventsOfTypeSeen(1), triggerRunStats[0].getEventsOfType(1)); + if(triggerRunStats[0].getEventsOfType(0) != 0) { + System.out.printf(" %d / %d (%7.3f%%)%n", (100.0 * triggerRunStats[0].getEventsOfTypeSeen(1) / triggerRunStats[0].getEventsOfTypeSeen(1))); + } else { System.out.println(); } + System.out.printf("\tPair Trigger 1 :: %d / %d", + triggerRunStats[1].getEventsOfTypeSeen(0), triggerRunStats[0].getEventsOfType(0)); + if(triggerRunStats[1].getEventsOfType(0) != 0) { + System.out.printf(" %d / %d (%7.3f%%)%n", (100.0 * triggerRunStats[1].getEventsOfTypeSeen(0) / triggerRunStats[1].getEventsOfTypeSeen(0))); + } else { System.out.println(); } + System.out.printf("\tPair Trigger 2 :: %d / %d", + triggerRunStats[1].getEventsOfTypeSeen(1), triggerRunStats[0].getEventsOfType(1)); + if(triggerRunStats[1].getEventsOfType(0) != 0) { + System.out.printf(" %d / %d (%7.3f%%)%n", (100.0 * triggerRunStats[1].getEventsOfTypeSeen(1) / triggerRunStats[1].getEventsOfTypeSeen(1))); + } else { System.out.println(); } + // Print the cluster verification data. + System.out.println(); System.out.println("Cluster Verification:"); System.out.printf("\tRecon Clusters :: %d%n", clusterRunStats.getReconClusterCount()); System.out.printf("\tSSP Clusters :: %d%n", clusterRunStats.getSSPClusterCount()); @@ -389,6 +426,7 @@ System.out.println(); System.out.printf("\tTrigger %d Individual Cut Failure Rate:%n", (triggerNum + 1)); if(sspTriggerCount == 0) { + System.out.printf("\t\tUmatched Triggers :: %" + spaces + "d%n", triggerRunStats[0].getUnmatchedTriggers(triggerNum)); System.out.printf("\t\tCluster Energy Lower Bound :: %" + spaces + "d / %" + spaces + "d%n", triggerRunStats[0].getCutFailures(triggerNum, ENERGY_MIN), sspTriggerCount); System.out.printf("\t\tCluster Energy Upper Bound :: %" + spaces + "d / %" + spaces + "d%n", @@ -396,6 +434,7 @@ System.out.printf("\t\tCluster Hit Count :: %" + spaces + "d / %" + spaces + "d%n", triggerRunStats[0].getCutFailures(triggerNum, HIT_COUNT), sspTriggerCount); } else { + System.out.printf("\t\tUmatched Triggers :: %" + spaces + "d%n", triggerRunStats[0].getUnmatchedTriggers(triggerNum)); System.out.printf("\t\tCluster Energy Lower Bound :: %" + spaces + "d / %" + spaces + "d (%7.3f%%)%n", triggerRunStats[0].getCutFailures(triggerNum, ENERGY_MIN), sspTriggerCount, (100.0 * triggerRunStats[0].getCutFailures(triggerNum, ENERGY_MIN) / sspTriggerCount)); @@ -413,6 +452,7 @@ System.out.println(); System.out.printf("\tTrigger %d Individual Cut Failure Rate:%n", (triggerNum + 1)); if(sspTriggerCount == 0) { + System.out.printf("\t\tUmatched Triggers :: %" + spaces + "d%n", triggerRunStats[1].getUnmatchedTriggers(triggerNum)); System.out.printf("\t\tPair Energy Sum :: %" + spaces + "d / %" + spaces + "d%n", triggerRunStats[1].getCutFailures(triggerNum, ENERGY_SUM), sspTriggerCount); System.out.printf("\t\tPair Energy Difference :: %" + spaces + "d / %" + spaces + "d%n", @@ -422,6 +462,7 @@ System.out.printf("\t\tPair Coplanarity :: %" + spaces + "d / %" + spaces + "d%n", triggerRunStats[1].getCutFailures(triggerNum, COPLANARITY), sspTriggerCount); } else { + System.out.printf("\t\tUmatched Triggers :: %" + spaces + "d%n", triggerRunStats[1].getUnmatchedTriggers(triggerNum)); System.out.printf("\t\tPair Energy Sum :: %" + spaces + "d / %" + spaces + "d (%7.3f%%)%n", triggerRunStats[1].getCutFailures(triggerNum, ENERGY_SUM), sspTriggerCount, (100.0 * triggerRunStats[1].getCutFailures(triggerNum, ENERGY_SUM) / sspTriggerCount)); @@ -555,6 +596,9 @@ } else if(tiBank.isCalibTrigger()) { OutputLogger.println("Trigger type :: Cosmic"); activeTrigger = TriggerDiagnosticUtil.TRIGGER_COSMIC; + } else { + System.err.println("TriggerDiagnosticDriver: Skipping event; no TI trigger source found."); + return; } } } @@ -568,6 +612,12 @@ OutputLogger.printf("%d SSP clusters found.%n", sspClusters.size()); } } + } + + // Make sure that both an SSP bank and a TI bank were found. + if(tiBank == null || sspBank == null) { + System.err.println("TriggerDiagnosticDriver :: SEVERE WARNING :: TI bank or SSP bank missing from event!"); + return; } @@ -858,12 +908,6 @@ } } else { OutputLogger.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. OutputLogger.println(); @@ -1372,11 +1416,11 @@ // Iterate over the triggers. OutputLogger.println(); - OutputLogger.println("Matching SSP Reported Triggers to SSP Simulated Trigger:"); + OutputLogger.println("Matching SSP Reported Triggers to SSP Simulated Triggers:"); for(SSPNumberedTrigger sspTrigger : sspTriggers) { // Get the trigger information. int triggerNum = sspTrigger.isFirstTrigger() ? 0 : 1; - OutputLogger.printf("Considering %s%n", sspTrigger.toString()); + OutputLogger.printf("\t%s%n", sspTrigger.toString()); // Iterate over the SSP cluster simulated triggers and // look for a trigger that matches. @@ -1384,7 +1428,7 @@ for(Trigger<?> simTrigger : sspTriggerList.get(triggerNum)) { // VERBOSE :: Output the trigger being considered for // matching. - OutputLogger.printf("\tTrigger %d :: %s :: %3.0f :: %s ", + OutputLogger.printf("\t\tTrigger %d :: %s :: %3.0f :: %s ", (triggerNum + 1), triggerPositionString(simTrigger), getTriggerTime(simTrigger), simTrigger.toString()); @@ -1407,7 +1451,8 @@ boolean[] matchedCuts = triggerCutMatch(simTrigger, sspTrigger); for(int i = 0; i < matchedCuts.length; i++) { if(!matchedCuts[i]) { - OutputLogger.printf("[ %-15s ]%n", String.format("failed; cut %d", i)); + int typeIndex = isSingles ? 0 : 1; + OutputLogger.printf("[ %-15s ]%n", String.format("failed; %s", cutNames[typeIndex][i])); continue matchLoop; } } @@ -1422,14 +1467,34 @@ } } + for(int triggerNum = 0; triggerNum < 2; triggerNum++) { + for(Trigger<?> simTrigger : sspTriggerList.get(triggerNum)) { + globalTriggerPlots.sawTrigger(simTrigger); + if(simTriggerSet.contains(simTrigger)) { + globalTriggerPlots.matchedTrigger(simTrigger); + } else { + globalTriggerPlots.failedTrigger(simTrigger); + } + } + } + // Iterate over the unmatched simulated triggers again and the // unmatched SSP reported trigger that most closely matches it. - simLoop: + OutputLogger.println(); + OutputLogger.println("Matching Failed SSP Reported Triggers to Remaining SSP Simulated Triggers:"); for(int triggerNum = 0; triggerNum < 2; triggerNum++) { + simLoop: for(Trigger<?> simTrigger : sspTriggerList.get(triggerNum)) { + OutputLogger.printf("\tTrigger %d :: %s :: %3.0f :: %s%n", + (triggerNum + 1), triggerPositionString(simTrigger), + getTriggerTime(simTrigger), simTrigger.toString()); + // Check whether this trigger has already been matched // or not. If it has been matched, skip it. - if(simTriggerSet.contains(simTrigger)) { continue simLoop; } + if(simTriggerSet.contains(simTrigger)) { + OutputLogger.println("\t\tSkipping; already matched successfully"); + continue simLoop; + } // Get the trigger time for the simulated trigger. double simTime = getTriggerTime(simTrigger); @@ -1440,18 +1505,27 @@ boolean[] matchedCut = null; SSPNumberedTrigger bestMatch = null; + // Store the readout for the best match. + String bestMatchText = null; + // Iterate over the reported triggers to find a match. reportedLoop: for(SSPNumberedTrigger sspTrigger : sspTriggers) { + OutputLogger.printf("\t\t%s ", sspTrigger.toString()); + // If the two triggers have different times, this // trigger should be skipped. if(sspTrigger.getTime() != simTime) { + OutputLogger.printf("[ %-15s ]%n", "failed; time"); continue reportedLoop; } // If this reported trigger has been matched then // it should be skipped. - if(sspTriggerSet.contains(sspTrigger)) { continue reportedLoop; } + if(sspTriggerSet.contains(sspTrigger)) { + OutputLogger.printf("[ %-15s ]%n", "failed; matched"); + continue reportedLoop; + } // Check each of the cuts. boolean[] tempMatchedCut = triggerCutMatch(simTrigger, sspTrigger); @@ -1460,6 +1534,7 @@ // than the previous best match. int tempNumMatched = 0; for(boolean passed : tempMatchedCut) { if(passed) { tempNumMatched++; } } + OutputLogger.printf("[ %-15s ]%n", String.format("maybe; %d failed", tempNumMatched)); // If the number of matched cuts exceeds the old // best result, this becomes the new best result. @@ -1467,6 +1542,7 @@ numMatched = tempNumMatched; matchedCut = tempMatchedCut; bestMatch = sspTrigger; + bestMatchText = String.format("%s%n", sspTrigger.toString()); } } @@ -1476,8 +1552,17 @@ if(bestMatch == null) { if(isSingles) { singlesInternalFail = true; } else { pairInternalFail = true; } + event.matchedSSPPair(simTrigger, bestMatch, matchedCut); + OutputLogger.printf("\t\tTrigger %d :: %s :: %3.0f :: %s", + (triggerNum + 1), triggerPositionString(simTrigger), + getTriggerTime(simTrigger), simTrigger.toString()); + OutputLogger.println(" --> No Valid Match Found"); } else { event.matchedSSPPair(simTrigger, bestMatch, matchedCut); + OutputLogger.printf("\t\tTrigger %d :: %s :: %3.0f :: %s", + (triggerNum + 1), triggerPositionString(simTrigger), + getTriggerTime(simTrigger), simTrigger.toString()); + OutputLogger.println(" --> " + bestMatchText); } } } @@ -1496,12 +1581,31 @@ OutputLogger.println("Recon Cluster Trigger --> SSP Reported Trigger Match Status"); for(int triggerNum = 0; triggerNum < 2; triggerNum++) { for(Trigger<?> simTrigger : reconTriggerList.get(triggerNum)) { + // If the trigger number and type align with the event + // trigger type, mark that it was seen. + if(triggerNum == 1) { + if(activeTrigger == TriggerDiagnosticUtil.TRIGGER_SINGLES_1 && isSingles) { + event.setSawEventType(true); + } else if(activeTrigger == TriggerDiagnosticUtil.TRIGGER_PAIR_1 && !isSingles) { + event.setSawEventType(true); + } + } else { + if(activeTrigger == TriggerDiagnosticUtil.TRIGGER_SINGLES_2 && isSingles) { + event.setSawEventType(true); + } else if(activeTrigger == TriggerDiagnosticUtil.TRIGGER_PAIR_2 && !isSingles) { + event.setSawEventType(true); + } + } OutputLogger.printf("\tTrigger %d :: %s :: %s%n", (triggerNum + 1), triggerPositionString(simTrigger), simTrigger.toString()); + // TEMP :: Populate the recon ALL pairs plots. + globalTriggerPlots.sawTrigger(simTrigger); + // Iterate over the SSP reported triggers and compare // them to the reconstructed cluster simulated trigger. + boolean matched = false; matchLoop: for(SSPNumberedTrigger sspTrigger : sspTriggers) { OutputLogger.printf("\t\t\t%s", sspTrigger.toString()); @@ -1522,10 +1626,6 @@ } // 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++) { @@ -1540,8 +1640,12 @@ sspTriggerSet.add(sspTrigger); event.matchedReconPair(simTrigger, sspTrigger); OutputLogger.print(" [ success ]%n"); + globalTriggerPlots.matchedTrigger(simTrigger); + matched = true; break matchLoop; } + + if(!matched) { globalTriggerPlots.failedTrigger(simTrigger); } } } @@ -1560,6 +1664,12 @@ // Print event statistics. OutputLogger.println(); OutputLogger.println("Event Statistics:"); + OutputLogger.printf("\tSaw Triggering Event Type :: "); + if(activeTrigger == TriggerDiagnosticUtil.TRIGGER_COSMIC || activeTrigger == TriggerDiagnosticUtil.TRIGGER_PULSER) { + OutputLogger.println("Unsupported for Cosmic/Pulser"); + } else { + OutputLogger.println("" + event.sawEventType()); + } OutputLogger.printf("\tSSP Cluster Sim Triggers :: %d%n", sspSimTriggers); OutputLogger.printf("\tRecon Cluster Sim Triggers :: %d%n", reconSimTriggers); OutputLogger.printf("\tSSP Reported Triggers :: %d%n", sspTriggers.size()); @@ -1602,8 +1712,8 @@ } // Update the global trigger tracking variables. - triggerRunStats[0].addEvent(event, reconTriggerList, sspTriggerList, sspTriggers); - triggerLocalStats[0].addEvent(event, reconTriggerList, sspTriggerList, sspTriggers); + triggerRunStats[0].addEvent(activeTrigger, event, reconTriggerList, sspTriggerList, sspTriggers); + triggerLocalStats[0].addEvent(activeTrigger, event, reconTriggerList, sspTriggerList, sspTriggers); efficiencyRunStats.addSinglesTriggers(activeTrigger, reconTriggerList); efficiencyLocalStats.addSinglesTriggers(activeTrigger, reconTriggerList); efficiencyRunStats.addEvent(activeTrigger, event); @@ -1635,8 +1745,8 @@ } // Update the global trigger tracking variables. - triggerRunStats[1].addEvent(event, reconTriggerList, sspTriggerList, sspTriggers); - triggerLocalStats[1].addEvent(event, reconTriggerList, sspTriggerList, sspTriggers); + triggerRunStats[1].addEvent(activeTrigger, event, reconTriggerList, sspTriggerList, sspTriggers); + triggerLocalStats[1].addEvent(activeTrigger, event, reconTriggerList, sspTriggerList, sspTriggers); efficiencyRunStats.addPairTriggers(activeTrigger, reconTriggerList); efficiencyLocalStats.addSinglesTriggers(activeTrigger, reconTriggerList); efficiencyRunStats.addEvent(activeTrigger, event); Modified: java/trunk/analysis/src/main/java/org/hps/analysis/trigger/event/TriggerMatchEvent.java ============================================================================= --- java/trunk/analysis/src/main/java/org/hps/analysis/trigger/event/TriggerMatchEvent.java (original) +++ java/trunk/analysis/src/main/java/org/hps/analysis/trigger/event/TriggerMatchEvent.java Thu Mar 19 10:30:08 2015 @@ -19,10 +19,14 @@ private int[] sspInternalMatched = new int[2]; private int[] reconTriggersMatched = new int[2]; private int[][] triggerComp = new int[4][2]; + private int[] unmatchedTriggers = new int[2]; // Track the matched trigger pairs. private List<TriggerMatchedPair> sspPairList = new ArrayList<TriggerMatchedPair>(); private List<Pair<Trigger<?>, SSPNumberedTrigger>> reconPairList = new ArrayList<Pair<Trigger<?>, SSPNumberedTrigger>>(); + + // Track whether the event triggering type was seen. + private boolean sawEventType = false; /** * Gets the number of times a cut of the given cut ID failed when @@ -34,7 +38,7 @@ */ public int getCutFailures(int triggerNumber, int cutID) { // Validate the arguments. - if(triggerNumber !=0 && triggerNumber != 1) { + if(triggerNumber != 0 && triggerNumber != 1) { throw new IndexOutOfBoundsException("Trigger number must be 0 or 1."); } if(cutID < 0 || cutID > 3) { throw new IndexOutOfBoundsException(String.format("Cut ID \"%d\" is not valid.", cutID)); @@ -42,6 +46,23 @@ // Return the requested cut value. return triggerComp[cutID][triggerNumber]; + } + + /** + * Gets the number of triggers for this trigger for which there + * were no matches. + * @param triggerNum - The trigger for which to get the value. + * @return Returns the number of triggers that failed to match as + * an <code>int</code>. + */ + public int getUnmatchedTriggers(int triggerNum) { + // Validate the arguments. + if(triggerNum != 0 && triggerNum != 1) { + throw new IndexOutOfBoundsException("Trigger number must be 0 or 1."); + } + + // Return the requested cut value. + return unmatchedTriggers[triggerNum]; } /** @@ -139,7 +160,9 @@ // singles triggers use arrays of size 3. If the array is not // of the appropriate size, resize it. boolean[] cutArray; - if(cutsMatched.length == 4) { + if(cutsMatched == null) { + cutArray = new boolean[] { false, false, false, false }; + } else if(cutsMatched.length == 4) { cutArray = cutsMatched; } else { cutArray = new boolean[] { cutsMatched[0], cutsMatched[1], cutsMatched[2], true }; @@ -149,11 +172,15 @@ TriggerMatchedPair triggerPair = new TriggerMatchedPair(simTrigger, sspTrigger, cutArray); sspPairList.add(triggerPair); + // If the argument cut array was null, then this trigger was + // not actually matched. Track this. + int triggerNum = triggerPair.isFirstTrigger() ? 0 : 1; + if(cutsMatched == null) { unmatchedTriggers[triggerNum]++; } + // Track which cuts have failed. boolean isMatched = true; - int triggerNum = triggerPair.isFirstTrigger() ? 0 : 1; - for(int cutIndex = 0; cutIndex < cutsMatched.length; cutIndex++) { - if(!cutsMatched[cutIndex]) { + for(int cutIndex = 0; cutIndex < cutArray.length; cutIndex++) { + if(!cutArray[cutIndex]) { triggerComp[cutIndex][triggerNum]++; isMatched = false; } @@ -162,4 +189,24 @@ // If all the cuts are true, then the trigger pair is a match. if(isMatched) { sspInternalMatched[triggerNum]++; } } + + /** + * Indicates whether an event of the type that caused the event + * readout was seen. + * @return Returns <code>true</code> if an event was seen and + * <code>false</code> otherwise. + */ + public boolean sawEventType() { + return sawEventType; + } + + /** + * Sets whether a simulated trigger of the type that caused the + * event readout was seen. + * @param state - <code>true</code> indicates that the trigger type + * was seen and <code>false</code> that it was not. + */ + public void setSawEventType(boolean state) { + sawEventType = state; + } } Modified: java/trunk/analysis/src/main/java/org/hps/analysis/trigger/event/TriggerMatchStatus.java ============================================================================= --- java/trunk/analysis/src/main/java/org/hps/analysis/trigger/event/TriggerMatchStatus.java (original) +++ java/trunk/analysis/src/main/java/org/hps/analysis/trigger/event/TriggerMatchStatus.java Thu Mar 19 10:30:08 2015 @@ -3,6 +3,7 @@ import java.util.List; import org.hps.analysis.trigger.util.Trigger; +import org.hps.analysis.trigger.util.TriggerDiagnosticUtil; import org.hps.recon.ecal.triggerbank.SSPNumberedTrigger; /** @@ -23,8 +24,15 @@ * @param sspSimTriggers - A list of simulated SSP cluster triggers. * @param sspBankTriggers - A list of SSP bank triggers. */ - public void addEvent(TriggerMatchEvent event, List<List<? extends Trigger<?>>> reconTriggers, + public void addEvent(int eventType, TriggerMatchEvent event, List<List<? extends Trigger<?>>> reconTriggers, List<List<? extends Trigger<?>>> sspSimTriggers, List<? extends SSPNumberedTrigger> sspBankTriggers) { + // Increment the event type count. + if(eventType == TriggerDiagnosticUtil.TRIGGER_SINGLES_1 || eventType == TriggerDiagnosticUtil.TRIGGER_PAIR_1) { + triggerTypesSeen[0]++; + } else if(eventType == TriggerDiagnosticUtil.TRIGGER_SINGLES_2 || eventType == TriggerDiagnosticUtil.TRIGGER_PAIR_2) { + triggerTypesSeen[1]++; + } + // Check if there are more bank triggers than there are // simulated SSP triggers. int sspTriggerDiff = sspBankTriggers.size() - sspSimTriggers.size(); @@ -46,6 +54,8 @@ // Increment the count for each cut failure type. for(int triggerNum = 0; triggerNum < 2; triggerNum++) { + unmatchedTriggers[triggerNum] += event.getUnmatchedTriggers(triggerNum); + for(int cutIndex = 0; cutIndex < 4; cutIndex++) { triggerComp[cutIndex][triggerNum] += event.getCutFailures(triggerNum, cutIndex); } @@ -55,6 +65,12 @@ for(int triggerNum = 0; triggerNum < 2; triggerNum++) { sspInternalMatched[triggerNum] += event.getMatchedSSPTriggers(triggerNum); reconTriggersMatched[triggerNum] += event.getMatchedReconTriggers(triggerNum); + } + + // Check if a trigger of the right time was found. + // Get the trigger number and type. + if(event.sawEventType()) { + triggerTypesFound[eventType]++; } } Modified: java/trunk/analysis/src/main/java/org/hps/analysis/trigger/event/TriggerMatchedPair.java ============================================================================= --- java/trunk/analysis/src/main/java/org/hps/analysis/trigger/event/TriggerMatchedPair.java (original) +++ java/trunk/analysis/src/main/java/org/hps/analysis/trigger/event/TriggerMatchedPair.java Thu Mar 19 10:30:08 2015 @@ -80,7 +80,11 @@ * object. */ public Class<?> getSimulatedTriggerType() { - return getFirstElement().getTriggerSource().getClass(); + if(getFirstElement() != null) { + return getFirstElement().getTriggerSource().getClass(); + } else { + return null; + } } /** @@ -99,7 +103,11 @@ * first trigger and <code>false</code> otherwise. */ public boolean isFirstTrigger() { - return getSecondElement().isFirstTrigger(); + if(getSecondElement() != null) { + return getSecondElement().isFirstTrigger(); + } else { + return getFirstElement().getTriggerNumber() == 0 ? true : false; + } } /** @@ -108,7 +116,7 @@ * triggers and <code>false</code> otherwise. */ public boolean isPairTrigger() { - if(getFirstElement() instanceof PairTrigger && getSecondElement() instanceof SSPPairTrigger) { + if(getFirstElement() instanceof PairTrigger || getSecondElement() instanceof SSPPairTrigger) { return true; } else { return false; @@ -122,7 +130,7 @@ * second trigger and <code>false</code> otherwise. */ public boolean isSecondTrigger() { - return getSecondElement().isSecondTrigger(); + return !isFirstTrigger(); } /** @@ -131,7 +139,7 @@ * triggers and <code>false</code> otherwise. */ public boolean isSinglesTrigger() { - if(getFirstElement() instanceof SinglesTrigger && getSecondElement() instanceof SSPSinglesTrigger) { + if(getFirstElement() instanceof SinglesTrigger || getSecondElement() instanceof SSPSinglesTrigger) { return true; } else { return false; Added: java/trunk/analysis/src/main/java/org/hps/analysis/trigger/event/TriggerPlotsModule.java ============================================================================= --- java/trunk/analysis/src/main/java/org/hps/analysis/trigger/event/TriggerPlotsModule.java (added) +++ java/trunk/analysis/src/main/java/org/hps/analysis/trigger/event/TriggerPlotsModule.java Thu Mar 19 10:30:08 2015 @@ -0,0 +1,241 @@ +package org.hps.analysis.trigger.event; + +import org.hps.analysis.trigger.util.Trigger; +import org.hps.recon.ecal.triggerbank.SSPCluster; +import org.hps.recon.ecal.triggerbank.TriggerModule; +import org.lcsim.event.Cluster; +import org.lcsim.util.aida.AIDA; + +import hep.aida.IHistogram1D; + +/** + * Class <code>TriggerPlotsModule</code> handles the plotting of singles + * and pair trigger values. + * + * @author Kyle McCarty + */ +public class TriggerPlotsModule { + // Reference variables. + private static final int RECON = 0; + private static final int SSP = 1; + private static final int ALL = 0; + private static final int MATCHED = 1; + private static final int FAILED = 2; + + // Class variables. + private final double[] energySlopeParamF; + + // Plots. + private AIDA aida = AIDA.defaultInstance(); + private IHistogram1D[][][] singlesClusterEnergyPlot = new IHistogram1D[2][2][3]; + private IHistogram1D[][][] singlesHitCountPlot = new IHistogram1D[2][2][3]; + + private IHistogram1D[][][] pairClusterEnergyPlot = new IHistogram1D[2][2][3]; + private IHistogram1D[][][] pairHitCountPlot = new IHistogram1D[2][2][3]; + private IHistogram1D[][][] pairTimePlot = new IHistogram1D[2][2][3]; + private IHistogram1D[][][] pairSumPlot = new IHistogram1D[2][2][3]; + private IHistogram1D[][][] pairDiffPlot = new IHistogram1D[2][2][3]; + private IHistogram1D[][][] pairSlopePlot = new IHistogram1D[2][2][3]; + private IHistogram1D[][][] pairCoplanarityPlot = new IHistogram1D[2][2][3]; + + /** + * Instantiates a new <code>TriggerPlotsModule</code> that will use + * the indicated values for the energy slope conversion factor when + * plotting energy slope values. Plots will be attached to the + * default AIDA instance. + * @param trigger0F - The energy slope conversion factor for the + * first trigger. + * @param trigger1F - The energy slope conversion factor for the + * second trigger. + */ + public TriggerPlotsModule(double trigger0F, double trigger1F) { + // Store the energy slope parameter. + energySlopeParamF = new double[2]; + energySlopeParamF[0] = trigger0F; + energySlopeParamF[1] = trigger1F; + + // Define type string values. + String[] sourceType = { "Recon", "SSP" }; + String[] resultType = { "All", "Matched", "Failed" }; + + // Instantiate the trigger result plots for each trigger. + for(int triggerNum = 0; triggerNum < 2; triggerNum++) { + // Get the directory for the current triggers. + String pairDir = "Pair Trigger " + triggerNum; + String singlesDir = "Singles Trigger " + triggerNum; + + // Instantiate the trigger result plots for each type of + // trigger source object. + for(int source = 0; source < 2; source++) { + // Instantiate the trigger result plots for each type + // of trigger match result. + for(int result = 0; result < 3; result++) { + // Instantiate the singles trigger plots. + singlesClusterEnergyPlot[triggerNum][source][result] = aida.histogram1D(String.format("%s/%s Singles Hit Count (%s)", + singlesDir, sourceType[source], resultType[result]), 9, 0.5, 9.5); + singlesHitCountPlot[triggerNum][source][result] = aida.histogram1D(String.format("%s/%s Singles Cluster Energy (%s)", + singlesDir, sourceType[source], resultType[result]), 300, 0.0, 3.0); + + // Instantiate the pair trigger plots. + pairHitCountPlot[triggerNum][source][result] = aida.histogram1D(String.format("%s/%s Pair Hit Count (%s)", + pairDir, sourceType[source], resultType[result]), 9, 0.5, 9.5); + pairClusterEnergyPlot[triggerNum][source][result] = aida.histogram1D(String.format("%s/%s Pair Cluster Energy (%s)", + pairDir, sourceType[source], resultType[result]), 300, 0.0, 3.0); + pairTimePlot[triggerNum][source][result] = aida.histogram1D(String.format("%s/%s Pair Time Coincidence (%s)", + pairDir, sourceType[source], resultType[result]), 8, 0, 32); + pairSumPlot[triggerNum][source][result] = aida.histogram1D(String.format("%s/%s Pair Energy Sum (%s)", + pairDir, sourceType[source], resultType[result]), 300, 0.0, 3.0); + pairDiffPlot[triggerNum][source][result] = aida.histogram1D(String.format("%s/%s Pair Energy Difference (%s)", + pairDir, sourceType[source], resultType[result]), 300, 0.0, 3.0); + pairSlopePlot[triggerNum][source][result] = aida.histogram1D(String.format("%s/%s Pair Energy Slope (%s)", + pairDir, sourceType[source], resultType[result]), 300, 0.0, 3.0); + pairCoplanarityPlot[triggerNum][source][result] = aida.histogram1D(String.format("%s/%s Pair Coplanarity (%s)", + pairDir, sourceType[source], resultType[result]), 180, 0, 180); + } + } + } + } + + /** + * Populates the "all" plots of the appropriate type with the cut + * results from the argument trigger. + * @param trigger - The trigger from which to populate the plots. + */ + public void sawTrigger(Trigger<?> trigger) { + processTrigger(trigger, ALL); + } + + /** + * Populates the "matched" plots of the appropriate type with the + * cut results from the argument trigger. + * @param trigger - The trigger from which to populate the plots. + */ + public void matchedTrigger(Trigger<?> trigger) { + processTrigger(trigger, MATCHED); + } + + /** + * Populates the "failed" plots of the appropriate type with the + * cut results from the argument trigger. + * @param trigger - The trigger from which to populate the plots. + */ + public void failedTrigger(Trigger<?> trigger) { + processTrigger(trigger, FAILED); + } + + public void setEnergySlopeParamF(int triggerNum, double value) { + // Make sure that the trigger number is valid. + if(triggerNum < 0 || triggerNum > 1) { + throw new IllegalArgumentException(String.format("Trigger number %d is not valid.", triggerNum)); + } + + // Set the parameter. + energySlopeParamF[triggerNum] = value; + } + + /** + * Populates the indicated type of plots of the appropriate type + * for the argument trigger. + * @param trigger - The trigger from which to populate the plots. + * @param plotType - The type of plot to populate. This must be one + * of <code>ALL</code>, <code>MATCHED</code>, or <code>FAILED</code>. + */ + private void processTrigger(Trigger<?> trigger, int plotType) { + // Get the trigger number and source. + Object source = trigger.getTriggerSource(); + int triggerNum = trigger.getTriggerNumber(); + + // Populate the plots using the appropriate method. + if(source instanceof Cluster) { + processSingles(triggerNum, plotType, (Cluster) source); + } + else if(source instanceof SSPCluster) { + processSingles(triggerNum, plotType, (SSPCluster) source); + } + else if(source instanceof Cluster[]) { + processPair(triggerNum, plotType, (Cluster[]) source); + } + else if(source instanceof SSPCluster[]) { + processPair(triggerNum, plotType, (SSPCluster[]) source); + } + + // If the trigger source is unsupported, produce an error. + else { + throw new IllegalArgumentException(String.format("Trigger source \"%s\" is not supported.", source.getClass().getSimpleName())); + } + } + + /** + * Populates the trigger singles plots for the indicated type for + * reconstructed clusters. + * @param triggerNum - The trigger number of the source trigger. + * @param plotType - The type of plot to populate. This must be one + * of <code>ALL</code>, <code>MATCHED</code>, or <code>FAILED</code>. + * @param pair - The triggering cluster. + */ + private void processSingles(int triggerNum, int plotType, Cluster cluster) { + // Fill the cluster singles plots. + singlesHitCountPlot[triggerNum][RECON][plotType].fill(TriggerModule.getValueClusterHitCount(cluster)); + singlesClusterEnergyPlot[triggerNum][RECON][plotType].fill(TriggerModule.getValueClusterTotalEnergy(cluster)); + } + + /** + * Populates the trigger singles plots for the indicated type for SSP + * clusters. + * @param triggerNum - The trigger number of the source trigger. + * @param plotType - The type of plot to populate. This must be one + * of <code>ALL</code>, <code>MATCHED</code>, or <code>FAILED</code>. + * @param pair - The triggering cluster. + */ + private void processSingles(int triggerNum, int plotType, SSPCluster cluster) { + // Fill the cluster singles plots. + singlesHitCountPlot[triggerNum][SSP][plotType].fill(TriggerModule.getValueClusterHitCount(cluster)); + singlesClusterEnergyPlot[triggerNum][SSP][plotType].fill(TriggerModule.getValueClusterTotalEnergy(cluster)); + } + + /** + * Populates the trigger pair plots for the indicated type for + * reconstructed cluster pairs. + * @param triggerNum - The trigger number of the source trigger. + * @param plotType - The type of plot to populate. This must be one + * of <code>ALL</code>, <code>MATCHED</code>, or <code>FAILED</code>. + * @param pair - The triggering pair. + */ + private void processPair(int triggerNum, int plotType, Cluster[] pair) { + // Fill the cluster singles plots. + pairHitCountPlot[triggerNum][RECON][plotType].fill(TriggerModule.getValueClusterHitCount(pair[0])); + pairHitCountPlot[triggerNum][RECON][plotType].fill(TriggerModule.getValueClusterHitCount(pair[1])); + pairClusterEnergyPlot[triggerNum][RECON][plotType].fill(TriggerModule.getValueClusterTotalEnergy(pair[0])); + pairClusterEnergyPlot[triggerNum][RECON][plotType].fill(TriggerModule.getValueClusterTotalEnergy(pair[1])); + + // Fill the cluster pair plots. + pairTimePlot[triggerNum][RECON][plotType].fill(TriggerModule.getValueTimeCoincidence(pair)); + pairSumPlot[triggerNum][RECON][plotType].fill(TriggerModule.getValueEnergySum(pair)); + pairDiffPlot[triggerNum][RECON][plotType].fill(TriggerModule.getValueEnergyDifference(pair)); + pairSlopePlot[triggerNum][RECON][plotType].fill(TriggerModule.getValueEnergySlope(pair, energySlopeParamF[triggerNum])); + pairCoplanarityPlot[triggerNum][RECON][plotType].fill(TriggerModule.getValueCoplanarity(pair)); + } + + /** + * Populates the trigger pair plots for the indicated type for SSP + * cluster pairs. + * @param triggerNum - The trigger number of the source trigger. + * @param plotType - The type of plot to populate. This must be one + * of <code>ALL</code>, <code>MATCHED</code>, or <code>FAILED</code>. + * @param pair - The triggering pair. + */ + private void processPair(int triggerNum, int plotType, SSPCluster[] pair) { + // Fill the cluster singles plots. + pairHitCountPlot[triggerNum][SSP][plotType].fill(TriggerModule.getValueClusterHitCount(pair[0])); + pairHitCountPlot[triggerNum][SSP][plotType].fill(TriggerModule.getValueClusterHitCount(pair[1])); + pairClusterEnergyPlot[triggerNum][SSP][plotType].fill(TriggerModule.getValueClusterTotalEnergy(pair[0])); + pairClusterEnergyPlot[triggerNum][SSP][plotType].fill(TriggerModule.getValueClusterTotalEnergy(pair[1])); + + // Fill the cluster pair plots. + pairTimePlot[triggerNum][SSP][plotType].fill(TriggerModule.getValueTimeCoincidence(pair)); + pairSumPlot[triggerNum][SSP][plotType].fill(TriggerModule.getValueEnergySum(pair)); + pairDiffPlot[triggerNum][SSP][plotType].fill(TriggerModule.getValueEnergyDifference(pair)); + pairSlopePlot[triggerNum][SSP][plotType].fill(TriggerModule.getValueEnergySlope(pair, energySlopeParamF[triggerNum])); + pairCoplanarityPlot[triggerNum][SSP][plotType].fill(TriggerModule.getValueCoplanarity(pair)); + } +} Modified: java/trunk/analysis/src/main/java/org/hps/analysis/trigger/event/TriggerStatModule.java ============================================================================= --- java/trunk/analysis/src/main/java/org/hps/analysis/trigger/event/TriggerStatModule.java (original) +++ java/trunk/analysis/src/main/java/org/hps/analysis/trigger/event/TriggerStatModule.java Thu Mar 19 10:30:08 2015 @@ -15,7 +15,9 @@ protected int[] sspInternalMatched = new int[2]; protected int[] reconTriggersMatched = new int[2]; protected int[][] triggerComp = new int[4][2]; - + protected int[] unmatchedTriggers = new int[2]; + protected int[] triggerTypesSeen = new int[2]; + protected int[] triggerTypesFound = new int[2]; /** * Instantiates a <code>TriggerStatModule</code> with no statistics @@ -40,6 +42,13 @@ for(int i = 0; i < reconTriggersMatched.length; i++) { reconTriggersMatched[i] = base.reconTriggersMatched[i]; } + for(int i = 0; i < triggerTypesSeen.length; i++) { + triggerTypesSeen[i] = base.triggerTypesSeen[i]; + triggerTypesFound[i] = base.triggerTypesFound[i]; + } + for(int i = 0; i < unmatchedTriggers.length; i++) { + unmatchedTriggers[i] = base.unmatchedTriggers[i]; + } for(int i = 0; i < triggerComp.length; i++) { for(int j = 0; j < triggerComp[i].length; j++) { triggerComp[i][j] = base.triggerComp[i][j]; @@ -82,6 +91,40 @@ } /** + * Gets the number of events that were readout due to a trigger + * of the indicated type. + * @param triggerType - The type of trigger. + * @return Returns the number of events readout because of the + * trigger type as an <code>int</code>. + */ + public int getEventsOfType(int triggerNum) { + // Make sure that the trigger type is defined. + if(triggerNum < 0 || triggerNum > 1) { + throw new IndexOutOfBoundsException(String.format("Trigger number \"%d\" is not valid.", triggerNum)); + } + + // Return the number of events that were trigger by this type. + return triggerTypesSeen[triggerNum]; + } + + /** + * Gets the number of events that were readout due to a trigger + * of the indicated type where a reconstructed cluster simulated + * trigger of that type existed. + * @param triggerType - The type of trigger. + * @return Returns the number of events as an <code>int</code>. + */ + public int getEventsOfTypeSeen(int triggerNum) { + // Make sure that the trigger type is defined. + if(triggerNum < 0 || triggerNum > 1) { + throw new IndexOutOfBoundsException(String.format("Trigger number \"%d\" is not valid.", triggerNum)); + } + + // Return the number of events that were trigger by this type. + return triggerTypesFound[triggerNum]; + } + + /** * Gets the number of SSP bank triggers that were reported in excess * of the number of simulated SSP triggers seen. * @return Returns the value as an <code>int</code> primitive. @@ -163,4 +206,21 @@ public int getSSPBankTriggerCount() { return reportedTriggers; } + + /** + * Gets the number of triggers for this trigger for which there + * were no matches. + * @param triggerNum - The trigger for which to get the value. + * @return Returns the number of triggers that failed to match as + * an <code>int</code>. + */ + public int getUnmatchedTriggers(int triggerNum) { + // Validate the arguments. + if(triggerNum != 0 && triggerNum != 1) { + throw new IndexOutOfBoundsException("Trigger number must be 0 or 1."); + } + + // Return the requested cut value. + return unmatchedTriggers[triggerNum]; + } }