Author: [log in to unmask]
Date: Mon Feb 9 08:42:35 2015
New Revision: 2081
Log:
Added temporary trigger diagnostic classes. These are subject to changes in both name and functionality and should not be used until officially integrated into the build.
Added:
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/Trigger.java
java/trunk/users/src/main/java/org/hps/users/kmccarty/TriggerDiagnosticDriver.java
Added: java/trunk/users/src/main/java/org/hps/users/kmccarty/PairTrigger.java
=============================================================================
--- java/trunk/users/src/main/java/org/hps/users/kmccarty/PairTrigger.java (added)
+++ java/trunk/users/src/main/java/org/hps/users/kmccarty/PairTrigger.java Mon Feb 9 08:42:35 2015
@@ -0,0 +1,136 @@
+package org.hps.users.kmccarty;
+
+import org.hps.readout.ecal.TriggerModule;
+
+public class PairTrigger<E> extends SinglesTrigger<E> {
+ // Define the supported trigger cuts.
+ private static final String PAIR_ENERGY_SUM_LOW = TriggerModule.PAIR_ENERGY_SUM_LOW;
+ private static final String PAIR_ENERGY_SUM_HIGH = TriggerModule.PAIR_ENERGY_SUM_HIGH;
+ private static final String PAIR_ENERGY_DIFFERENCE_HIGH = TriggerModule.PAIR_ENERGY_DIFFERENCE_HIGH;
+ private static final String PAIR_ENERGY_SLOPE_LOW = TriggerModule.PAIR_ENERGY_SLOPE_LOW;
+ private static final String PAIR_COPLANARITY_HIGH = TriggerModule.PAIR_COPLANARITY_HIGH;
+
+ /**
+ * Instantiates a new <code>PairTrigger</code> with all cut
+ * states set to <code>false</code> and with the trigger source
+ * defined according to the specified object.
+ * @param source - The object from which the trigger cut states
+ * are derived.
+ */
+ protected PairTrigger(E source) {
+ // Instantiate the superclass.
+ super(source);
+
+ // Add the supported cuts types.
+ addValidCut(PAIR_ENERGY_SUM_LOW);
+ addValidCut(PAIR_ENERGY_SUM_HIGH);
+ addValidCut(PAIR_ENERGY_DIFFERENCE_HIGH);
+ addValidCut(PAIR_ENERGY_SLOPE_LOW);
+ addValidCut(PAIR_COPLANARITY_HIGH);
+ }
+
+ /**
+ * Gets whether the pair energy sum lower bound cut was met.
+ * @return Returns <code>true</code> if the cut was met and
+ * <code>false</code> otherwise.
+ */
+ public boolean getStateEnergySumLow() {
+ return getCutState(PAIR_ENERGY_SUM_LOW);
+ }
+
+ /**
+ * Gets whether the pair energy sum upper bound cut was met.
+ * @return Returns <code>true</code> if the cut was met and
+ * <code>false</code> otherwise.
+ */
+ public boolean getStateEnergySumHigh() {
+ return getCutState(PAIR_ENERGY_SUM_HIGH);
+ }
+
+ /**
+ * Gets whether both the pair energy sum upper and lower bound cuts
+ * were met.
+ * @return Returns <code>true</code> if the cuts were met and
+ * <code>false</code> otherwise.
+ */
+ public boolean getStateEnergySum() {
+ return getCutState(PAIR_ENERGY_SUM_HIGH);
+ }
+
+ /**
+ * Gets whether the pair energy difference cut was met.
+ * @return Returns <code>true</code> if the cut was met and
+ * <code>false</code> otherwise.
+ */
+ public boolean getStateEnergyDifference() {
+ return getCutState(PAIR_ENERGY_SUM_HIGH);
+ }
+
+ /**
+ * Gets whether the pair energy slope cut was met.
+ * @return Returns <code>true</code> if the cut was met and
+ * <code>false</code> otherwise.
+ */
+ public boolean getStateEnergySlope() {
+ return getCutState(PAIR_ENERGY_SLOPE_LOW);
+ }
+
+ /**
+ * Gets whether the pair coplanarity cut was met.
+ * @return Returns <code>true</code> if the cut was met and
+ * <code>false</code> otherwise.
+ */
+ public boolean getStateCoplanarity() {
+ return getCutState(PAIR_COPLANARITY_HIGH);
+ }
+
+ /**
+ * Sets whether the conditions for the pair energy sum lower bound
+ * cut were met.
+ * @param state - <code>true</code> indicates that the cut conditions
+ * were met and <code>false</code> that they were not.
+ */
+ public void getStateEnergySumLow(boolean state) {
+ setCutState(PAIR_ENERGY_SUM_LOW, state);
+ }
+
+ /**
+ * Sets whether the conditions for the pair energy sum upper bound
+ * cut were met.
+ * @param state - <code>true</code> indicates that the cut conditions
+ * were met and <code>false</code> that they were not.
+ */
+ public void getStateEnergySumHigh(boolean state) {
+ setCutState(PAIR_ENERGY_SUM_HIGH, state);
+ }
+
+ /**
+ * Sets whether the conditions for the pair energy difference cut
+ * were met.
+ * @param state - <code>true</code> indicates that the cut conditions
+ * were met and <code>false</code> that they were not.
+ */
+ public void getStateEnergyDifference(boolean state) {
+ setCutState(PAIR_ENERGY_DIFFERENCE_HIGH, state);
+ }
+
+ /**
+ * Sets whether the conditions for the pair energy slope cut were
+ * met.
+ * @param state - <code>true</code> indicates that the cut conditions
+ * were met and <code>false</code> that they were not.
+ */
+ public void getStateEnergySlope(boolean state) {
+ setCutState(PAIR_ENERGY_SLOPE_LOW, state);
+ }
+
+ /**
+ * Sets whether the conditions for the pair coplanarity cut were
+ * met.
+ * @param state - <code>true</code> indicates that the cut conditions
+ * were met and <code>false</code> that they were not.
+ */
+ public void getStateCoplanarity(boolean state) {
+ setCutState(PAIR_COPLANARITY_HIGH, state);
+ }
+}
Added: java/trunk/users/src/main/java/org/hps/users/kmccarty/SinglesTrigger.java
=============================================================================
--- java/trunk/users/src/main/java/org/hps/users/kmccarty/SinglesTrigger.java (added)
+++ java/trunk/users/src/main/java/org/hps/users/kmccarty/SinglesTrigger.java Mon Feb 9 08:42:35 2015
@@ -0,0 +1,146 @@
+package org.hps.users.kmccarty;
+
+import org.hps.readout.ecal.TriggerModule;
+
+public class SinglesTrigger<E> extends Trigger<E> {
+ // Define the supported trigger cuts.
+ private static final String CLUSTER_HIT_COUNT_LOW = TriggerModule.CLUSTER_HIT_COUNT_LOW;
+ private static final String CLUSTER_SEED_ENERGY_LOW = TriggerModule.CLUSTER_SEED_ENERGY_LOW;
+ private static final String CLUSTER_SEED_ENERGY_HIGH = TriggerModule.CLUSTER_SEED_ENERGY_HIGH;
+ private static final String CLUSTER_TOTAL_ENERGY_LOW = TriggerModule.CLUSTER_TOTAL_ENERGY_LOW;
+ private static final String CLUSTER_TOTAL_ENERGY_HIGH = TriggerModule.CLUSTER_TOTAL_ENERGY_HIGH;
+
+ /**
+ * Instantiates a new <code>SinglesTrigger</code> with all cut
+ * states set to <code>false</code> and with the trigger source
+ * defined according to the specified object.
+ * @param source - The object from which the trigger cut states
+ * are derived.
+ */
+ protected SinglesTrigger(E source) {
+ // Instantiate the superclass.
+ super(source);
+
+ // Add the supported cuts types.
+ addValidCut(CLUSTER_HIT_COUNT_LOW);
+ addValidCut(CLUSTER_SEED_ENERGY_LOW);
+ addValidCut(CLUSTER_SEED_ENERGY_HIGH);
+ addValidCut(CLUSTER_TOTAL_ENERGY_LOW);
+ addValidCut(CLUSTER_TOTAL_ENERGY_HIGH);
+ }
+
+ /**
+ * Gets whether the cluster hit count cut was met.
+ * @return Returns <code>true</code> if the cut was met and
+ * <code>false</code> otherwise.
+ */
+ public boolean getStateHitCount() {
+ return getCutState(CLUSTER_HIT_COUNT_LOW);
+ }
+
+ /**
+ * Gets whether the cluster seed energy lower bound cut was met.
+ * @return Returns <code>true</code> if the cut was met and
+ * <code>false</code> otherwise.
+ */
+ public boolean getStateSeedEnergyLow() {
+ return getCutState(CLUSTER_SEED_ENERGY_LOW);
+ }
+
+ /**
+ * Gets whether the cluster seed energy upper bound cut was met.
+ * @return Returns <code>true</code> if the cut was met and
+ * <code>false</code> otherwise.
+ */
+ public boolean getStateSeedEnergyHigh() {
+ return getCutState(CLUSTER_SEED_ENERGY_HIGH);
+ }
+
+ /**
+ * Gets whether both the cluster seed energy upper and lower bound
+ * cuts were met.
+ * @return Returns <code>true</code> if the cuts were met and
+ * <code>false</code> otherwise.
+ */
+ public boolean getStateSeedEnergy() {
+ return getCutState(CLUSTER_SEED_ENERGY_LOW) && getCutState(CLUSTER_SEED_ENERGY_HIGH);
+ }
+
+ /**
+ * Gets whether the cluster total energy lower bound cut was met.
+ * @return Returns <code>true</code> if the cut was met and
+ * <code>false</code> otherwise.
+ */
+ public boolean getStateClusterEnergyLow() {
+ return getCutState(CLUSTER_TOTAL_ENERGY_LOW);
+ }
+
+ /**
+ * Gets whether the cluster total energy upper bound cut was met.
+ * @return Returns <code>true</code> if the cut was met and
+ * <code>false</code> otherwise.
+ */
+ public boolean getStateClusterEnergyHigh() {
+ return getCutState(CLUSTER_TOTAL_ENERGY_HIGH);
+ }
+
+ /**
+ * Gets whether both the cluster total energy upper and lower bound
+ * cuts were met.
+ * @return Returns <code>true</code> if the cuts were met and
+ * <code>false</code> otherwise.
+ */
+ public boolean getStateClusterEnergy() {
+ return getCutState(CLUSTER_TOTAL_ENERGY_LOW) && getCutState(CLUSTER_TOTAL_ENERGY_HIGH);
+ }
+
+ /**
+ * Sets whether the conditions for the cluster hit count cut were
+ * met.
+ * @param state - <code>true</code> indicates that the cut conditions
+ * were met and <code>false</code> that they were not.
+ */
+ public void setStateHitCount(boolean state) {
+ setCutState(CLUSTER_HIT_COUNT_LOW, state);
+ }
+
+ /**
+ * Sets whether the conditions for the cluster seed energy lower
+ * bound cut were met.
+ * @param state - <code>true</code> indicates that the cut conditions
+ * were met and <code>false</code> that they were not.
+ */
+ public void setStateSeedEnergyLow(boolean state) {
+ setCutState(CLUSTER_SEED_ENERGY_LOW, state);
+ }
+
+ /**
+ * Sets whether the conditions for the cluster seed energy upper
+ * bound cut were met.
+ * @param state - <code>true</code> indicates that the cut conditions
+ * were met and <code>false</code> that they were not.
+ */
+ public void setStateSeedEnergyHigh(boolean state) {
+ setCutState(CLUSTER_SEED_ENERGY_HIGH, state);
+ }
+
+ /**
+ * Sets whether the conditions for the cluster total energy lower
+ * bound cut were met.
+ * @param state - <code>true</code> indicates that the cut conditions
+ * were met and <code>false</code> that they were not.
+ */
+ public void setStateClusterEnergyLow(boolean state) {
+ setCutState(CLUSTER_TOTAL_ENERGY_LOW, state);
+ }
+
+ /**
+ * Sets whether the conditions for the cluster total energy upper
+ * bound cut were met.
+ * @param state - <code>true</code> indicates that the cut conditions
+ * were met and <code>false</code> that they were not.
+ */
+ public void setStateClusterEnergyHigh(boolean state) {
+ setCutState(CLUSTER_TOTAL_ENERGY_HIGH, state);
+ }
+}
Added: java/trunk/users/src/main/java/org/hps/users/kmccarty/Trigger.java
=============================================================================
--- java/trunk/users/src/main/java/org/hps/users/kmccarty/Trigger.java (added)
+++ java/trunk/users/src/main/java/org/hps/users/kmccarty/Trigger.java Mon Feb 9 08:42:35 2015
@@ -0,0 +1,130 @@
+package org.hps.users.kmccarty;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+
+/**
+ * Class <code>Trigger</code> stores a set cut states indicating whether
+ * specific cut conditions associated with a trigger were met or not as
+ * well as the state of the overall trigger. It is the responsibility of
+ * implementing classes to specify the supported cut states and also
+ * to define when the trigger conditions are met.
+ *
+ * @author Kyle McCarty <[log in to unmask]>
+ */
+public abstract class Trigger<E> {
+ // Track whether the trigger conditions were met.
+ private boolean passTrigger = false;
+ // Store the cut condition states.
+ private Map<String, Boolean> passMap = new HashMap<String, Boolean>();
+ // Store the cluster associated with the trigger.
+ private final E source;
+
+ /**
+ * Creates a new <code>Trigger</code> object with the argument
+ * specifying the object from whence the trigger state is derived.
+ * @param source - The trigger source object.
+ */
+ protected Trigger(E source) {
+ this.source = source;
+ }
+
+ /**
+ * Adds a cut to the set of cuts tracked by this trigger.
+ * @param cut - The identifier for the cut.
+ */
+ protected void addValidCut(String cut) {
+ passMap.put(cut, new Boolean(false));
+ }
+
+ /**
+ * Gets the state of the specified cut.
+ * @param cut - The identifier for the cut.
+ * @return Returns <code>true</code> if the conditions for the
+ * specified cut were met and <code>false</code> otherwise.
+ * @throws IllegalArgumentException Occurs if the specified cut
+ * is not supported by the object.
+ */
+ protected boolean getCutState(String cut) throws IllegalArgumentException {
+ if(passMap.containsKey(cut)) {
+ return passMap.get(cut);
+ } else {
+ throw new IllegalArgumentException(String.format("Trigger cut \"%s\" is not a supported trigger cut.", cut));
+ }
+ }
+
+ /**
+ * Gets the object to which the trigger cuts are applied.
+ * @return Returns the trigger source object.
+ */
+ public E getTriggerSource() { return source; }
+
+ /**
+ * Gets whether the conditions for the trigger were met.
+ * @return Returns <code>true</code> if the conditions for the
+ * trigger were met and <code>false</code> if they were not.
+ */
+ public boolean getTriggerState() {
+ return passTrigger;
+ }
+
+ /**
+ * Removes a cut from the set of cuts tracked by the trigger.
+ * @param cut - The identifier for the cut.
+ */
+ protected void removeValidCut(String cut) {
+ passMap.remove(cut);
+ }
+
+ /**
+ * Checks whether the all of the trigger cut conditions were met.
+ * @return Returns <code>true</code> if all of the cut conditions
+ * were met and <code>false</code> otherwise.
+ */
+ private boolean isValidTrigger() {
+ // Iterate over all of the cuts and look for any that have not
+ // been met.
+ for(Entry<String, Boolean> cut : passMap.entrySet()) {
+ if(!cut.getValue()) { return false; }
+ }
+
+ // If there are no cut conditions that have not been met, then
+ // the trigger is valid.
+ return true;
+ }
+
+ /**
+ * Sets whether the conditions for the specified cut were met.
+ * @param cut - The identifier for the cut.
+ * @param state - <code>true</code> indicates that the conditions
+ * for the cut were met and <code>false</code> that they were not.
+ * @throws IllegalArgumentException Occurs if the specified cut
+ * is not supported by the object.
+ */
+ protected void setCutState(String cut, boolean state) throws IllegalArgumentException {
+ if(passMap.containsKey(cut)) {
+ // Set the cut state.
+ passMap.put(cut, state);
+
+ // If the cut state is true, then all cut conditions may have
+ // been met. Check whether this is true and, if so, set the
+ // trigger state accordingly.
+ if(state && isValidTrigger()) { passTrigger = true; }
+ else { passTrigger = false; }
+ } else {
+ throw new IllegalArgumentException(String.format("Trigger cut \"%s\" is not a supported trigger cut.", cut));
+ }
+ }
+
+ /**
+ * Indicates whether the specified cut state is tracked by this
+ * object or not.
+ * @param cut - The identifier for the cut.
+ * @return Returns <code>true</code> if the cut state is tracked
+ * by this object and <code>false</code> otherwise.
+ */
+ protected boolean supportsCut(String cut) {
+ return passMap.containsKey(cut);
+ }
+}
Added: java/trunk/users/src/main/java/org/hps/users/kmccarty/TriggerDiagnosticDriver.java
=============================================================================
--- java/trunk/users/src/main/java/org/hps/users/kmccarty/TriggerDiagnosticDriver.java (added)
+++ java/trunk/users/src/main/java/org/hps/users/kmccarty/TriggerDiagnosticDriver.java Mon Feb 9 08:42:35 2015
@@ -0,0 +1,330 @@
+package org.hps.users.kmccarty;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import org.hps.readout.ecal.TriggerModule;
+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.TIData;
+import org.hps.recon.ecal.CalorimeterHitUtilities;
+import org.lcsim.detector.converter.compact.EcalCrystal;
+import org.lcsim.event.CalorimeterHit;
+import org.lcsim.event.Cluster;
+import org.lcsim.event.EventHeader;
+import org.lcsim.event.GenericObject;
+import org.lcsim.geometry.Detector;
+import org.lcsim.util.Driver;
+
+public class TriggerDiagnosticDriver extends Driver {
+ // Store the LCIO collection names for the needed objects.
+ private String bankCollectionName = "TriggerBank";
+ private String clusterCollectionName = "EcalClusters";
+
+ // Store the lists of parsed objects.
+ private TIData tiBank;
+ private SSPData sspBank;
+ private List<Cluster> reconClusters;
+ private List<SSPCluster> sspClusters;
+ private List<List<PairTrigger<Cluster>>> reconPairsTriggers = new ArrayList<List<PairTrigger<Cluster>>>(2);
+ private List<List<PairTrigger<SSPCluster>>> sspPairsTriggers = new ArrayList<List<PairTrigger<SSPCluster>>>(2);
+ private List<List<SinglesTrigger<Cluster>>> reconSinglesTriggers = new ArrayList<List<SinglesTrigger<Cluster>>>(2);
+ private List<List<SinglesTrigger<SSPCluster>>> sspSinglesTriggers = new ArrayList<List<SinglesTrigger<SSPCluster>>>(2);
+
+ // Trigger modules for performing trigger analysis.
+ private TriggerModule[] singlesTrigger = new TriggerModule[2];
+ private TriggerModule[] pairsTrigger = new TriggerModule[2];
+
+ // Store internal variables.
+ private double energyAcceptance = 0.05;
+
+ /*
+ @Override
+ public void detectorChanged(Detector detector) {
+ for(EcalCrystal crystal : detector.getSubdetector("Ecal").getDetectorElement().findDescendants(EcalCrystal.class)) {
+ System.out.println(crystal.getIdentifier().getValue());
+ CalorimeterHit tempHit = CalorimeterHitUtilities.create(1.000, 10.0, crystal.getIdentifier().getValue());
+
+ int ix = tempHit.getIdentifierFieldValue("ix");
+ int iy = tempHit.getIdentifierFieldValue("iy");
+ double[] xyz = tempHit.getPosition();
+
+ System.out.printf("(%3d, %3d) --> (%.2f, %.2f)%n", ix, iy, xyz[0], xyz[1]);
+ }
+ }
+ */
+
+ /**
+ * Define the trigger modules. This should be replaced by parsing
+ * the DAQ configuration at some point.
+ */
+ @Override
+ public void startOfData() {
+ // Define the first singles trigger.
+ singlesTrigger[0] = new TriggerModule();
+ singlesTrigger[0].setCutValue(TriggerModule.CLUSTER_TOTAL_ENERGY_LOW, 0.500);
+ singlesTrigger[0].setCutValue(TriggerModule.CLUSTER_TOTAL_ENERGY_HIGH, 8.191);
+ singlesTrigger[0].setCutValue(TriggerModule.CLUSTER_HIT_COUNT_LOW, 0);
+
+ // Define the second singles trigger.
+ singlesTrigger[1] = new TriggerModule();
+ singlesTrigger[1].setCutValue(TriggerModule.CLUSTER_TOTAL_ENERGY_LOW, 0.000);
+ singlesTrigger[1].setCutValue(TriggerModule.CLUSTER_TOTAL_ENERGY_HIGH, 8.191);
+ singlesTrigger[1].setCutValue(TriggerModule.CLUSTER_HIT_COUNT_LOW, 0);
+
+ // Define the first pairs trigger.
+ pairsTrigger[0] = new TriggerModule();
+ pairsTrigger[0].setCutValue(TriggerModule.CLUSTER_TOTAL_ENERGY_LOW, 0.000);
+ pairsTrigger[0].setCutValue(TriggerModule.CLUSTER_TOTAL_ENERGY_HIGH, 8.191);
+ pairsTrigger[0].setCutValue(TriggerModule.CLUSTER_HIT_COUNT_LOW, 0);
+ pairsTrigger[0].setCutValue(TriggerModule.PAIR_ENERGY_SUM_LOW, 0.000);
+ pairsTrigger[0].setCutValue(TriggerModule.PAIR_ENERGY_SUM_HIGH, 8.191);
+ pairsTrigger[0].setCutValue(TriggerModule.PAIR_ENERGY_DIFFERENCE_HIGH, 8.191);
+ pairsTrigger[0].setCutValue(TriggerModule.PAIR_ENERGY_SLOPE_LOW, 0.000);
+ pairsTrigger[0].setCutValue(TriggerModule.PAIR_ENERGY_SLOPE_F, 0.001);
+ pairsTrigger[0].setCutValue(TriggerModule.PAIR_COPLANARITY_HIGH, 180);
+
+ // Define the second pairs trigger.
+ pairsTrigger[1] = new TriggerModule();
+ pairsTrigger[1].setCutValue(TriggerModule.CLUSTER_TOTAL_ENERGY_LOW, 0.000);
+ pairsTrigger[1].setCutValue(TriggerModule.CLUSTER_TOTAL_ENERGY_HIGH, 8.191);
+ pairsTrigger[1].setCutValue(TriggerModule.CLUSTER_HIT_COUNT_LOW, 0);
+ pairsTrigger[1].setCutValue(TriggerModule.PAIR_ENERGY_SUM_LOW, 0.000);
+ pairsTrigger[1].setCutValue(TriggerModule.PAIR_ENERGY_SUM_HIGH, 8.191);
+ pairsTrigger[1].setCutValue(TriggerModule.PAIR_ENERGY_DIFFERENCE_HIGH, 8.191);
+ pairsTrigger[1].setCutValue(TriggerModule.PAIR_ENERGY_SLOPE_LOW, 0.000);
+ pairsTrigger[1].setCutValue(TriggerModule.PAIR_ENERGY_SLOPE_F, 0.001);
+ pairsTrigger[1].setCutValue(TriggerModule.PAIR_COPLANARITY_HIGH, 180);
+
+ // Instantiate the triggers lists.
+ for(int triggerNum = 0; triggerNum < 2; triggerNum++) {
+ reconPairsTriggers.add(new ArrayList<PairTrigger<Cluster>>());
+ sspPairsTriggers.add(new ArrayList<PairTrigger<SSPCluster>>());
+ reconSinglesTriggers.add(new ArrayList<SinglesTrigger<Cluster>>());
+ sspSinglesTriggers.add(new ArrayList<SinglesTrigger<SSPCluster>>());
+ }
+ }
+
+ /**
+ * Gets the banks and clusters from the event.
+ */
+ @Override
+ public void process(EventHeader event) {
+ // Get the reconstructed clusters.
+ if(event.hasCollection(Cluster.class, clusterCollectionName)) {
+ reconClusters = event.get(Cluster.class, clusterCollectionName);
+ }
+
+ // 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 there is an SSP bank, get the list of SSP clusters.
+ if(sspBank != null) {
+ sspClusters = sspBank.getClusters();
+ }
+ }
+
+ // Check that all of the collections and objects are present.
+ boolean allPresent = true;
+ if(sspBank == null) {
+ System.out.println("SSP bank not found!");
+ allPresent = false;
+ } if(tiBank == null) {
+ System.out.println("TI bank not found!");
+ allPresent = false;
+ } if(sspClusters == null) {
+ System.out.println("SSP clusters not found!");
+ allPresent = false;
+ } if(reconClusters == null) {
+ System.out.println("Reconstructed clusters not found!");
+ allPresent = false;
+ }
+
+ // Do nothing further if an object is missing.
+ if(!allPresent) { return; }
+
+ // Otherwise, print out the two cluster collections.
+ System.out.printf("Summary for Event %d at time %d%n", event.getEventNumber(), event.getTimeStamp());
+ System.out.println("Reconstructed Clusters:");
+ for(Cluster cluster : reconClusters) {
+ System.out.println("\t" + reconClusterToString(cluster));
+ }
+
+ System.out.println("SSP Clusters:");
+ for(SSPCluster cluster : sspClusters) {
+ System.out.println("\t" + sspClusterToString(cluster));
+ }
+
+ // Perform the cluster verification step.
+ verifyClusters();
+
+ // Construct lists of triggers for the SSP clusters and the
+ // reconstructed clusters.
+ constructTriggers();
+
+ System.out.println("\n\n");
+ }
+
+ private void verifyClusters() {
+ // Track which clusters match and whether a given cluster
+ // has been matched or not.
+ Set<Cluster> reconClusterSet = new HashSet<Cluster>(reconClusters.size());
+ Set<SSPCluster> sspClusterSet = new HashSet<SSPCluster>(sspClusters.size());
+ Map<Cluster, SSPCluster> pairMap = new HashMap<Cluster, SSPCluster>(reconClusters.size());
+
+ // Iterate over the reconstructed clusters and check whether
+ // there is a matching SSP cluster or not.
+ for(Cluster reconCluster : reconClusters) {
+ // Get the cluster's x- and y- indices.
+ int ix = reconCluster.getCalorimeterHits().get(0).getIdentifierFieldValue("ix");
+ int iy = reconCluster.getCalorimeterHits().get(0).getIdentifierFieldValue("iy");
+
+ // Look for an unmatched cluster with the same indices.
+ matchLoop:
+ for(SSPCluster sspCluster : sspClusters) {
+ // TODO: Implement time cut on cluster matching.
+ if(sspCluster.getXIndex() == ix && sspCluster.getYIndex() == iy) {
+ // If this SSP cluster is already matched, it can
+ // not be used again.
+ if(sspClusterSet.contains(sspCluster)) {
+ continue matchLoop;
+ }
+
+ // We also require that the SSP cluster reports an
+ // energy within a certain percentage of the recon
+ // cluster.
+ double[] energy = { sspCluster.getEnergy() * (1 - energyAcceptance),
+ sspCluster.getEnergy() * (1 + energyAcceptance) };
+
+ // If the energies are within range, consider this
+ // a matched cluster pair. They must also have the
+ // same hit count.
+ // TODO: Fix hit inconsistency bug.
+ if(reconCluster.getEnergy() >= energy[0] && reconCluster.getEnergy() <= energy[1]
+ && reconCluster.getCalorimeterHits().size() == sspCluster.getHitCount()) {
+ // Add the two clusters to the matched sets.
+ sspClusterSet.add(sspCluster);
+ reconClusterSet.add(reconCluster);
+
+ // Map the two clusters together.
+ pairMap.put(reconCluster, sspCluster);
+
+ // Skip to the next recon cluster.
+ continue matchLoop;
+ }
+ }
+ }
+ } // End matchLoop
+
+ // Output the cluster matches and note which clusters failed
+ // to be paired. These may suggest an error.
+ System.out.println("Matched Clusters:");
+ for(Entry<Cluster, SSPCluster> pair : pairMap.entrySet()) {
+ System.out.printf("\t%s --> %s%n", reconClusterToString(pair.getKey()), sspClusterToString(pair.getValue()));
+ }
+ System.out.println("Unmatched Clusters:");
+ for(SSPCluster sspCluster : sspClusters){
+ if(!sspClusterSet.contains(sspCluster)) {
+ System.out.printf("\tSSP :: %s%n", sspClusterToString(sspCluster));
+ }
+ }
+ for(Cluster reconCluster : reconClusters){
+ if(!reconClusterSet.contains(reconCluster)) {
+ System.out.printf("\tRecon :: %s%n", reconClusterToString(reconCluster));
+ }
+ }
+ }
+
+ private void constructTriggers() {
+ // Run the SSP clusters through the singles trigger to determine
+ // whether they pass it or not.
+ for(SSPCluster cluster : sspClusters) {
+ for(int triggerNum = 0; triggerNum < 2; triggerNum++) {
+ // For a cluster to have formed it is assumed to have passed
+ // the cluster seed energy cuts. This can not be verified
+ // since the SSP bank does not report individual hit.
+ boolean passSeedLow = true;
+ boolean passSeedHigh = true;
+
+ // The remaining cuts may be acquired from trigger module.
+ boolean passClusterLow = singlesTrigger[triggerNum].clusterTotalEnergyCutLow(cluster);
+ boolean passClusterHigh = singlesTrigger[triggerNum].clusterTotalEnergyCutHigh(cluster);
+ boolean passHitCount = singlesTrigger[triggerNum].clusterHitCountCut(cluster);
+
+ // Make a trigger to store the results.
+ SinglesTrigger<SSPCluster> trigger = new SinglesTrigger<SSPCluster>(cluster);
+ trigger.setStateSeedEnergyLow(passSeedLow);
+ trigger.setStateSeedEnergyHigh(passSeedHigh);
+ trigger.setStateClusterEnergyLow(passClusterLow);
+ trigger.setStateClusterEnergyHigh(passClusterHigh);
+ trigger.setStateHitCount(passHitCount);
+
+ // Store the trigger.
+ sspSinglesTriggers.get(triggerNum).add(trigger);
+ }
+ }
+
+ // Run the reconstructed clusters through the singles trigger
+ // to determine whether they pass it or not.
+ for(Cluster cluster : reconClusters) {
+ for(int triggerNum = 0; triggerNum < 2; triggerNum++) {
+ // For a cluster to have formed it is assumed to have passed
+ // the cluster seed energy cuts. This can not be verified
+ // since the SSP bank does not report individual hit.
+ boolean passSeedLow = true;
+ boolean passSeedHigh = true;
+
+ // The remaining cuts may be acquired from trigger module.
+ boolean passClusterLow = singlesTrigger[triggerNum].clusterTotalEnergyCutLow(cluster);
+ boolean passClusterHigh = singlesTrigger[triggerNum].clusterTotalEnergyCutHigh(cluster);
+ boolean passHitCount = singlesTrigger[triggerNum].clusterHitCountCut(cluster);
+
+ // Make a trigger to store the results.
+ SinglesTrigger<Cluster> trigger = new SinglesTrigger<Cluster>(cluster);
+ trigger.setStateSeedEnergyLow(passSeedLow);
+ trigger.setStateSeedEnergyHigh(passSeedHigh);
+ trigger.setStateClusterEnergyLow(passClusterLow);
+ trigger.setStateClusterEnergyHigh(passClusterHigh);
+ trigger.setStateHitCount(passHitCount);
+
+ // Store the trigger.
+ reconSinglesTriggers.get(triggerNum).add(trigger);
+ }
+ }
+ }
+
+ private static final String reconClusterToString(Cluster cluster) {
+ return String.format("Cluster at (%3d, %3d) with %.3f GeV and %d hits at %4.0f ns.",
+ cluster.getCalorimeterHits().get(0).getIdentifierFieldValue("ix"),
+ cluster.getCalorimeterHits().get(0).getIdentifierFieldValue("iy"),
+ cluster.getEnergy(), cluster.getCalorimeterHits().size(),
+ cluster.getCalorimeterHits().get(0).getTime());
+ }
+
+ private static final String sspClusterToString(SSPCluster cluster) {
+ return String.format("Cluster at (%3d, %3d) with %.3f GeV and %d hits at %4d ns.",
+ cluster.getXIndex(), cluster.getYIndex(), cluster.getEnergy(),
+ cluster.getHitCount(), cluster.getTime());
+ }
+}
|