LISTSERV mailing list manager LISTSERV 16.5

Help for HPS-SVN Archives


HPS-SVN Archives

HPS-SVN Archives


HPS-SVN@LISTSERV.SLAC.STANFORD.EDU


View:

Message:

[

First

|

Previous

|

Next

|

Last

]

By Topic:

[

First

|

Previous

|

Next

|

Last

]

By Author:

[

First

|

Previous

|

Next

|

Last

]

Font:

Proportional Font

LISTSERV Archives

LISTSERV Archives

HPS-SVN Home

HPS-SVN Home

HPS-SVN  February 2015

HPS-SVN February 2015

Subject:

r2123 - in /java/trunk/users/src/main/java/org/hps/users/kmccarty: PairTrigger.java TriggerDiagnosticDriver.java

From:

[log in to unmask]

Reply-To:

Notification of commits to the hps svn repository <[log in to unmask]>

Date:

Thu, 12 Feb 2015 21:00:43 -0000

Content-Type:

text/plain

Parts/Attachments:

Parts/Attachments

text/plain (862 lines)

Author: [log in to unmask]
Date: Thu Feb 12 13:00:39 2015
New Revision: 2123

Log:
PairTrigger now supports the ability to track whether a pair passed the time cut. TriggerDiagnosticDriver now contains a more robust cluster matching algorithm and additional framework toward an implementation of trigger matching.

Modified:
    java/trunk/users/src/main/java/org/hps/users/kmccarty/PairTrigger.java
    java/trunk/users/src/main/java/org/hps/users/kmccarty/TriggerDiagnosticDriver.java

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	Thu Feb 12 13:00:39 2015
@@ -9,6 +9,7 @@
 	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;
+    private static final String PAIR_TIME_COINCIDENCE = "pairTimeCoincidence";
 	
 	/**
 	 * Instantiates a new <code>PairTrigger</code> with all cut
@@ -27,6 +28,7 @@
 		addValidCut(PAIR_ENERGY_DIFFERENCE_HIGH);
 		addValidCut(PAIR_ENERGY_SLOPE_LOW);
 		addValidCut(PAIR_COPLANARITY_HIGH);
+		addValidCut(PAIR_TIME_COINCIDENCE);
 	}
 	
 	/**
@@ -85,12 +87,21 @@
 	}
 	
 	/**
+	 * Gets whether the time coincidence cut was met.
+	 * @return Returns <code>true</code> if the cut was met and
+	 * <code>false</code> otherwise.
+	 */
+	public boolean getStateTimeCoincidence() {
+		return getCutState(PAIR_TIME_COINCIDENCE);
+	}
+	
+	/**
 	 * 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) {
+	public void setStateEnergySumLow(boolean state) {
 		setCutState(PAIR_ENERGY_SUM_LOW, state);
 	}
 	
@@ -100,7 +111,7 @@
 	 * @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) {
+	public void setStateEnergySumHigh(boolean state) {
 		setCutState(PAIR_ENERGY_SUM_HIGH, state);
 	}
 	
@@ -110,7 +121,7 @@
 	 * @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) {
+	public void setStateEnergyDifference(boolean state) {
 		setCutState(PAIR_ENERGY_DIFFERENCE_HIGH, state);
 	}
 	
@@ -120,7 +131,7 @@
 	 * @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) {
+	public void setStateEnergySlope(boolean state) {
 		setCutState(PAIR_ENERGY_SLOPE_LOW, state);
 	}
 	
@@ -130,7 +141,17 @@
 	 * @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) {
+	public void setStateCoplanarity(boolean state) {
 		setCutState(PAIR_COPLANARITY_HIGH, state);
 	}
+	
+	/**
+	 * Sets whether the conditions for the time coincidence 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 setStateTimeCoincidence(boolean state) {
+		setCutState(PAIR_TIME_COINCIDENCE, state);
+	}
 }

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	Thu Feb 12 13:00:39 2015
@@ -6,12 +6,16 @@
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
+import java.util.logging.Level;
+import java.util.logging.Logger;
 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.SSPSinglesTrigger;
+import org.hps.readout.ecal.triggerbank.SSPTrigger;
 import org.hps.readout.ecal.triggerbank.TIData;
 import org.hps.recon.ecal.CalorimeterHitUtilities;
 import org.lcsim.detector.converter.compact.EcalCrystal;
@@ -21,6 +25,7 @@
 import org.lcsim.event.GenericObject;
 import org.lcsim.geometry.Detector;
 import org.lcsim.util.Driver;
+import org.lcsim.util.log.LogUtil;
 
 public class TriggerDiagnosticDriver extends Driver {
 	// Store the LCIO collection names for the needed objects.
@@ -32,8 +37,8 @@
 	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<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);
 	
@@ -41,12 +46,26 @@
 	private TriggerModule[] singlesTrigger = new TriggerModule[2];
 	private TriggerModule[] pairsTrigger = new TriggerModule[2];
 	
-	// Store internal variables.
-	private double energyAcceptance = 0.05;
+	// Output text logger.
+	private static Level logLevel = Level.FINEST;
+	private static Logger logger = LogUtil.create(TriggerDiagnosticDriver.class);   
+	
+	// Verification settings.
+	private int nsa = 100;
+	private int nsb = 20;
+	private int windowWidth = 200;
+	private int hitAcceptance = 1;
+	private double energyAcceptance = 0.03;
+	private boolean performClusterVerification = true;
+	
+	// Efficiency tracking variables.
+	private int reconClustersFound = 0;
+	private int reconClustersMatched = 0;
 	
 	/*
 	@Override
 	public void detectorChanged(Detector detector) {
+		if(detector == null) { return; }
 		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());
@@ -89,6 +108,7 @@
 		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);
+		pairsTrigger[0].setCutValue(TriggerModule.PAIR_TIME_COINCIDENCE, 8);
 		
 		// Define the second pairs trigger.
 		pairsTrigger[1] = new TriggerModule();
@@ -101,14 +121,32 @@
 		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);
+		pairsTrigger[1].setCutValue(TriggerModule.PAIR_TIME_COINCIDENCE, 8);
 		
 		// Instantiate the triggers lists.
 		for(int triggerNum = 0; triggerNum < 2; triggerNum++) {
-			reconPairsTriggers.add(new ArrayList<PairTrigger<Cluster>>());
-			sspPairsTriggers.add(new ArrayList<PairTrigger<SSPCluster>>());
+			reconPairsTriggers.add(new ArrayList<PairTrigger<Cluster[]>>());
+			sspPairsTriggers.add(new ArrayList<PairTrigger<SSPCluster[]>>());
 			reconSinglesTriggers.add(new ArrayList<SinglesTrigger<Cluster>>());
 			sspSinglesTriggers.add(new ArrayList<SinglesTrigger<SSPCluster>>());
 		}
+		
+		// Set the logger level.
+		logger.setLevel(logLevel);
+		
+		// Print the initial settings.
+		logSettings();
+	}
+	
+	@Override
+	public void endOfData() {
+		System.out.println("\n==== Efficiency Report ===============================================");
+		System.out.println("======================================================================\n");
+		System.out.println("==== Cluster Verification ================");
+		System.out.printf("\tValid Clusters Reconstructed   :: %d%n", reconClustersFound);
+		System.out.printf("\tReconstructed Clusters Matched :: %d%n", reconClustersMatched);
+		System.out.printf("\tClustering Efficiency          :: %3.2f %%%n", (100.0 * reconClustersMatched / reconClustersFound));
+		
 	}
 	
 	/**
@@ -116,10 +154,24 @@
 	 */
 	@Override
 	public void process(EventHeader event) {
+		// ==========================================================
+		// ==== Obtain Reconstructed Clusters =======================
+		// ==========================================================
+		
 		// Get the reconstructed clusters.
 		if(event.hasCollection(Cluster.class, clusterCollectionName)) {
 			reconClusters = event.get(Cluster.class, clusterCollectionName);
-		}
+			logger.fine(String.format("%d reconstructed clusters found.", reconClusters.size()));
+		} else {
+			reconClusters = new ArrayList<Cluster>(0);
+			logger.warning(String.format("No reconstructed clusters were found for collection \"%s\" in this event.", clusterCollectionName));
+		}
+		
+		
+		
+		// ==========================================================
+		// ==== Obtain SSP and TI Banks =============================
+		// ==========================================================
 		
 		// Get the SSP clusters.
 		if(event.hasCollection(GenericObject.class, bankCollectionName)) {
@@ -131,83 +183,139 @@
 				// If this is an SSP bank, parse it.
 				if(AbstractIntData.getTag(obj) == SSPData.BANK_TAG) {
 					sspBank = new SSPData(obj);
+					logger.finer("Read SSP bank.");
 				}
 				
 				// Otherwise, if this is a TI bank, parse it.
 				else if(AbstractIntData.getTag(obj) == TIData.BANK_TAG) {
 					tiBank = new TIData(obj);
+					logger.finer("Read TI bank.");
 				}
 			}
 			
 			// 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;
+				logger.fine(String.format("%d SSP clusters found.", sspClusters.size()));
+			}
+		}
+		
+		
+		
+		// ==========================================================
+		// ==== Establish Event Integrity ===========================
+		// ==========================================================
+		
+		// Check that all of the required objects are present.
 		if(sspBank == null) {
-			System.out.println("SSP bank not found!");
-			allPresent = false;
+			logger.warning("No SSP bank found for this event. No verification will be performed.");
+			return;
 		} 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; }
+			logger.warning("No TI bank found for this event. No verification will be performed.");
+			return;
+		}
+		
+		
+		
+		// ==========================================================
+		// ==== Perform Detailed Event Logging ======================
+		// ==========================================================
 		
 		// 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:");
+		logger.finest(String.format("Summary for Event %d at time %d", event.getEventNumber(), event.getTimeStamp()));
+		logger.finest("Reconstructed Clusters:");
 		for(Cluster cluster : reconClusters) {
-			System.out.println("\t" + reconClusterToString(cluster));
-		}
-		
-		System.out.println("SSP Clusters:");
+			logger.finest("\t" + reconClusterToString(cluster));
+		}
+		
+		logger.finest("SSP Clusters:");
 		for(SSPCluster cluster : sspClusters) {
-			System.out.println("\t" + sspClusterToString(cluster));
-		}
+			logger.finest("\t" + sspClusterToString(cluster));
+		}
+		
+		
+		
+		// ==========================================================
+		// ==== Perform Event Verification ==========================
+		// ==========================================================
 		
 		// Perform the cluster verification step.
-		verifyClusters();
+		if(performClusterVerification) { verifyClusters(); }
 		
 		// Construct lists of triggers for the SSP clusters and the
 		// reconstructed clusters.
-		constructTriggers();
-		
-		System.out.println("\n\n");
-	}
-	
+		constructSinglesTriggers();
+		constructPairTriggers();
+		verifyTriggers();
+	}
+	
+	/**
+	 * Attempts to match all reconstructed clusters that are safely
+	 * within the integration window with clusters reported by the SSP.
+	 * Method also tracks the ratio of valid reconstructed clusters to
+	 * matches found.<br/>
+	 * <br/>
+	 * Note that unmatched SSP clusters are ignored. Since these may
+	 * or may not correspond to reconstructed clusters that occur in
+	 * the forbidden time region, it is impossible to say whether or
+	 * not these legitimately failed to match or not.
+	 */
 	private void verifyClusters() {
+		// ==========================================================
+		// ==== Cluster Verification Initialization =================
+		// ==========================================================
+		
 		// 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());
 		
+		// Store which clusters were rejected due to the cluster
+		// window size.
+		Set<Cluster> badClusters = new HashSet<Cluster>();
+		
+		
+		
+		// ==========================================================
+		// ==== Cluster Matching ====================================
+		// ==========================================================
+		
 		// Iterate over the reconstructed clusters and check whether
 		// there is a matching SSP cluster or not.
+		reconLoop:
 		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");
 			
+			// Require that the clusters are far enough way
+			// from the edges of the time window to ensure
+			// that they will not have the FADC pulse cut.
+			for(CalorimeterHit hit : reconCluster.getCalorimeterHits()) {
+				if(hit.getTime() <= nsb || hit.getTime() >= (windowWidth - nsa)) {
+					badClusters.add(reconCluster);
+					logger.finer(String.format("Cluster %s is out-of-time due to hit (%3d, %3d) at time %3.0f.",
+							reconClusterPositionString(reconCluster),
+							hit.getIdentifierFieldValue("ix"), hit.getIdentifierFieldValue("iy"),
+							hit.getTime()));
+					continue reconLoop;
+				}
+			}
+			
+			// Increment the number of reconstructed clusters found that
+			// are within the allowed time window.
+			reconClustersFound++;
+			
 			// 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)) {
+						logger.finer(String.format("Cluster %s fails to match SSP cluster %s; SSP cluster already matched.",
+								reconClusterPositionString(reconCluster), sspClusterPositionString(sspCluster)));
 						continue matchLoop;
 					}
 					
@@ -218,45 +326,131 @@
 							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;
+					// a matched cluster pair.
+					if(reconCluster.getEnergy() >= energy[0] && reconCluster.getEnergy() <= energy[1]) {
+						// Check that the clusters have the same hit
+						// count. If the allowHitCountVariance setting
+						// is enabled, this may differ by +/- 1 hit.
+						int reconHits = reconCluster.getCalorimeterHits().size();
+						int sspHits = sspCluster.getHitCount();
+						if((reconHits + hitAcceptance >= sspHits) && (reconHits - hitAcceptance <= sspHits)) {
+							// Add the two clusters to the matched sets.
+							sspClusterSet.add(sspCluster);
+							reconClusterSet.add(reconCluster);
+							
+							// Map the two clusters together.
+							pairMap.put(reconCluster, sspCluster);
+							
+							// Log the match.
+							logger.finer(String.format("Cluster %s matches SSP cluster %s",
+									reconClusterPositionString(reconCluster), sspClusterPositionString(sspCluster)));
+							
+							// Increment the number of reconstructed
+							// clusters matched.
+							reconClustersMatched++;
+							
+							// Skip to the next recon cluster.
+							continue matchLoop;
+						} else {
+							logger.finer(String.format("Cluster %s fails to match SSP cluster %s; hits not within threshold.",
+									reconClusterPositionString(reconCluster), sspClusterPositionString(sspCluster)));
+						} // End match hits check
+					} else {
+						logger.finer(String.format("Cluster %s fails to match SSP cluster %s; Energy not within %3.1f%%.",
+								reconClusterPositionString(reconCluster), sspClusterPositionString(sspCluster),
+								(energyAcceptance * 100.0)));
+					} // End match energy check
+				} // End match indices check
+			} // End matchLoop
+		} // End reconLoop
+		
+		
+		
+		// ==========================================================
+		// ==== Event Summary Readout ===============================
+		// ==========================================================
+		
+		// Output the matched clusters.
+		logger.finest("Matched Clusters:");
+		if(!pairMap.isEmpty()) {
+			for(Entry<Cluster, SSPCluster> pair : pairMap.entrySet()) {
+				logger.finest(String.format("\t%s --> %s%n", reconClusterToString(pair.getKey()), sspClusterToString(pair.getValue())));
+			}
+		} else { logger.finest("\tNone"); }
+		
+		// Output unmatched reconstructed clusters and SSP clusters.
+		logger.finest("\nUnmatched Clusters:");
+		if(sspClusterSet.size() != sspClusters.size() || reconClusterSet.size() != reconClusters.size()) {
+			// Output the SSP clusters that were not matched.
+			for(SSPCluster sspCluster : sspClusters) {
+				if(!sspClusterSet.contains(sspCluster)) {
+					logger.finest(String.format("\tSSP   :: %s", sspClusterToString(sspCluster)));
+				}
+			}
+			
+			// Output the recon clusters that were not matched.
+			for(Cluster reconCluster : reconClusters) {
+				if(!reconClusterSet.contains(reconCluster) && !badClusters.contains(reconCluster)) {
+					logger.finest(String.format("\tRecon :: %s", reconClusterToString(reconCluster)));
+				}
+			}
+		} else {  logger.finest("\tNone"); }
+		
+		// Output the reconstructed clusters that were out-of-time.
+		logger.finest("\nOut-of-time Recon Clusters:");
+		if(!badClusters.isEmpty()) {
+			for(Cluster badCluster : badClusters) {
+				logger.finest(String.format("\tRecon :: %s", reconClusterToString(badCluster)));
+			}
+		} else {  logger.finest("\tNone"); }
+		
+		// Output the event efficiency.
+		logger.fine(String.format("Event Efficiency: %.1f", (100.0 * pairMap.size() / (reconClusters.size() - badClusters.size()))));
+	}
+	
+	private void verifyTriggers() {
+		// Get the list of triggers reported by the SSP.
+		List<SSPTrigger> sspTriggers = sspBank.getTriggers();
+		
+		// Iterate over the triggers.
+		System.out.println("SSP Bank Singles Triggers:");
+		for(SSPTrigger sspTrigger : sspTriggers) {
+			// If the trigger is a singles trigger, convert it.
+			if(sspTrigger instanceof SSPSinglesTrigger) {
+				// Cast the trigger to a singles trigger.
+				SSPSinglesTrigger sspSingles = (SSPSinglesTrigger) sspTrigger;
+				int triggerNum = sspSingles.isFirstTrigger() ? 0 : 1;
+				boolean matchedTrigger = false;
+				
+				// Iterate over the SSP cluster simulated triggers and
+				// look for a cluster that matches.
+				matchLoop:
+				for(SinglesTrigger<SSPCluster> simTrigger : sspSinglesTriggers.get(triggerNum)) {
+					if(compareSSPSinglesTriggers(sspSingles, simTrigger)) {
+						matchedTrigger = true;
+						break 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() {
+				
+				System.out.printf("\tTrigger %d :: %3d :: EClusterLow: %d; EClusterHigh %d; HitCount: %d :: Matched: %5b%n",
+						(triggerNum + 1), sspSingles.getTime(),
+						sspSingles.passCutEnergyMin() ? 1 : 0, sspSingles.passCutEnergyMax() ? 1 : 0,
+						sspSingles.passCutHitCount() ? 1 : 0, matchedTrigger);
+			}
+		}
+
+		System.out.println("SSP Clusters:");
+		for(SSPCluster cluster : sspClusters) {
+			System.out.println("\t" + sspClusterToString(cluster));
+		}
+	}
+	
+	/**
+	 * Generates and stores the singles triggers for both reconstructed
+	 * and SSP clusters.
+	 */
+	private void constructSinglesTriggers() {
+		System.out.println("SSP Cluster Singles Triggers:");
 		// Run the SSP clusters through the singles trigger to determine
 		// whether they pass it or not.
 		for(SSPCluster cluster : sspClusters) {
@@ -282,11 +476,16 @@
 				
 				// Store the trigger.
 				sspSinglesTriggers.get(triggerNum).add(trigger);
+				
+				System.out.printf("\tTrigger %d :: %s :: EClusterLow: %d; EClusterHigh %d; HitCount: %d%n",
+						(triggerNum + 1), sspClusterPositionString(cluster), passClusterLow ? 1 : 0,
+						passClusterHigh ? 1 : 0, passHitCount ? 1 : 0);
 			}
 		}
 		
 		// Run the reconstructed clusters through the singles trigger
 		// to determine whether they pass it or not.
+		System.out.println("Recon Cluster Singles Triggers:");
 		for(Cluster cluster : reconClusters) {
 			for(int triggerNum = 0; triggerNum < 2; triggerNum++) {
 				// For a cluster to have formed it is assumed to have passed
@@ -310,7 +509,210 @@
 				
 				// Store the trigger.
 				reconSinglesTriggers.get(triggerNum).add(trigger);
-			}
+				
+				System.out.printf("\tTrigger %d :: %s :: EClusterLow: %d; EClusterHigh %d; HitCount: %d%n",
+						(triggerNum + 1), reconClusterPositionString(cluster), passClusterLow ? 1 : 0,
+						passClusterHigh ? 1 : 0, passHitCount ? 1 : 0);
+			}
+		}
+	}
+	
+	/**
+	 * Generates and stores the pair triggers for both reconstructed
+	 * and SSP clusters.
+	 */
+	private void constructPairTriggers() {
+		// Store cluster pairs.
+		List<Cluster> topReconClusters = new ArrayList<Cluster>();
+		List<Cluster> bottomReconClusters = new ArrayList<Cluster>();
+		List<Cluster[]> reconPairs = new ArrayList<Cluster[]>();
+		List<SSPCluster> topSSPClusters = new ArrayList<SSPCluster>();
+		List<SSPCluster> bottomSSPClusters = new ArrayList<SSPCluster>();
+		List<SSPCluster[]> sspPairs = new ArrayList<SSPCluster[]>();
+		
+		// Split the clusters into lists of top and bottom clusters.
+		for(Cluster reconCluster : reconClusters) {
+			if(reconCluster.getCalorimeterHits().get(0).getIdentifierFieldValue("iy") > 0) {
+				topReconClusters.add(reconCluster);
+			} else {
+				bottomReconClusters.add(reconCluster);
+			}
+		}
+		for(SSPCluster sspCluster : sspClusters) {
+			if(sspCluster.getYIndex() > 0) {
+				topSSPClusters.add(sspCluster);
+			} else {
+				bottomSSPClusters.add(sspCluster);
+			}
+		}
+		
+		// Form all possible top/bottom cluster pairs.
+		for(Cluster topReconCluster : topReconClusters) {
+			for(Cluster bottomReconCluster : bottomReconClusters) {
+				Cluster[] reconPair = new Cluster[2];
+				reconPair[0] = topReconCluster;
+				reconPair[1] = bottomReconCluster;
+				reconPairs.add(reconPair);
+			}
+		}
+		for(SSPCluster topSSPCluster : topSSPClusters) {
+			for(SSPCluster bottomSSPCluster : bottomSSPClusters) {
+				SSPCluster[] sspPair = new SSPCluster[2];
+				sspPair[0] = topSSPCluster;
+				sspPair[1] = bottomSSPCluster;
+				sspPairs.add(sspPair);
+			}
+		}
+		
+		// Simulate the pair triggers and record the results.
+		System.out.println("Recon Cluster Pairs Triggers:");
+		for(Cluster[] reconPair : reconPairs) {
+			for(int triggerIndex = 0; triggerIndex < 2; triggerIndex++) {
+				// 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 = pairsTrigger[triggerIndex].clusterTotalEnergyCutLow(reconPair[0])
+						&& pairsTrigger[triggerIndex].clusterTotalEnergyCutLow(reconPair[1]);
+				boolean passClusterHigh = pairsTrigger[triggerIndex].clusterTotalEnergyCutHigh(reconPair[0])
+						&& pairsTrigger[triggerIndex].clusterTotalEnergyCutHigh(reconPair[1]);
+				boolean passHitCount = pairsTrigger[triggerIndex].clusterHitCountCut(reconPair[0])
+						&& pairsTrigger[triggerIndex].clusterHitCountCut(reconPair[1]);
+				boolean passPairEnergySumLow = pairsTrigger[triggerIndex].pairEnergySumCutLow(reconPair);
+				boolean passPairEnergySumHigh = pairsTrigger[triggerIndex].pairEnergySumCutHigh(reconPair);
+				boolean passPairEnergyDifference = pairsTrigger[triggerIndex].pairEnergyDifferenceCut(reconPair);
+				boolean passPairEnergySlope = pairsTrigger[triggerIndex].pairEnergySlopeCut(reconPair);
+				boolean passPairCoplanarity = pairsTrigger[triggerIndex].pairCoplanarityCut(reconPair);
+				boolean passTimeCoincidence = pairsTrigger[triggerIndex].pairTimeCoincidenceCut(reconPair);
+				
+				// Create a trigger from the results.
+				PairTrigger<Cluster[]> trigger = new PairTrigger<Cluster[]>(reconPair);
+				trigger.setStateSeedEnergyLow(passSeedLow);
+				trigger.setStateSeedEnergyHigh(passSeedHigh);
+				trigger.setStateClusterEnergyLow(passClusterLow);
+				trigger.setStateClusterEnergyHigh(passClusterHigh);
+				trigger.setStateHitCount(passHitCount);
+				trigger.setStateEnergySumLow(passPairEnergySumLow);
+				trigger.setStateEnergySumHigh(passPairEnergySumHigh);
+				trigger.setStateEnergyDifference(passPairEnergyDifference);
+				trigger.setStateEnergySlope(passPairEnergySlope);
+				trigger.setStateCoplanarity(passPairCoplanarity);
+				trigger.setStateTimeCoincidence(passTimeCoincidence);
+				
+				// Add the trigger to the list.
+				reconPairsTriggers.get(triggerIndex).add(trigger);
+				
+				System.out.printf("\tTrigger %d :: %s, %s :: EClusterLow: %d; EClusterHigh %d; HitCount: %d; ESumLow: %d, ESumHigh: %d, EDiff: %d, ESlope: %d, Coplanarity: %d, TimeDiff: %d%n",
+						(triggerIndex + 1), reconClusterPositionString(reconPair[0]),
+						reconClusterPositionString(reconPair[1]), passClusterLow ? 1 : 0,
+						passClusterHigh ? 1 : 0, passHitCount ? 1 : 0, passPairEnergySumLow ? 1 : 0,
+						passPairEnergySumHigh ? 1 : 0, passPairEnergyDifference ? 1 : 0,
+						passPairEnergySlope ? 1 : 0, passPairCoplanarity ? 1 : 0,
+						passTimeCoincidence ? 1 : 0);
+			}
+		}
+		
+		for(SSPCluster[] sspPair : sspPairs) {
+			for(int triggerIndex = 0; triggerIndex < 2; triggerIndex++) {
+				// 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 = pairsTrigger[triggerIndex].clusterTotalEnergyCutLow(sspPair[0])
+						&& pairsTrigger[triggerIndex].clusterTotalEnergyCutLow(sspPair[1]);
+				boolean passClusterHigh = pairsTrigger[triggerIndex].clusterTotalEnergyCutHigh(sspPair[0])
+						&& pairsTrigger[triggerIndex].clusterTotalEnergyCutHigh(sspPair[1]);
+				boolean passHitCount = pairsTrigger[triggerIndex].clusterHitCountCut(sspPair[0])
+						&& pairsTrigger[triggerIndex].clusterHitCountCut(sspPair[1]);
+				boolean passPairEnergySumLow = pairsTrigger[triggerIndex].pairEnergySumCutLow(sspPair);
+				boolean passPairEnergySumHigh = pairsTrigger[triggerIndex].pairEnergySumCutHigh(sspPair);
+				boolean passPairEnergyDifference = pairsTrigger[triggerIndex].pairEnergyDifferenceCut(sspPair);
+				
+				// TODO: Implement the pair energy slope cut and the and
+				//       pair coplanarity cut once they are supported by
+				//       TriggerModule.
+				boolean passPairEnergySlope = false;
+				boolean passPairCoplanarity = false;
+				
+				boolean passTimeCoincidence = pairsTrigger[triggerIndex].pairTimeCoincidenceCut(sspPair);
+				
+				// Create a trigger from the results.
+				PairTrigger<SSPCluster[]> trigger = new PairTrigger<SSPCluster[]>(sspPair);
+				trigger.setStateSeedEnergyLow(passSeedLow);
+				trigger.setStateSeedEnergyHigh(passSeedHigh);
+				trigger.setStateClusterEnergyLow(passClusterLow);
+				trigger.setStateClusterEnergyHigh(passClusterHigh);
+				trigger.setStateHitCount(passHitCount);
+				trigger.setStateEnergySumLow(passPairEnergySumLow);
+				trigger.setStateEnergySumHigh(passPairEnergySumHigh);
+				trigger.setStateEnergyDifference(passPairEnergyDifference);
+				trigger.setStateEnergySlope(passPairEnergySlope);
+				trigger.setStateCoplanarity(passPairCoplanarity);
+				trigger.setStateTimeCoincidence(passTimeCoincidence);
+				
+				// Add the trigger to the list.
+				//sspPairsTriggers.get(triggerIndex).add(trigger);
+			}
+		}
+	}
+	
+	/**
+	 * Outputs all of the verification parameters currently in use by
+	 * the software. A warning will be issued if the values for NSA and
+	 * NSB, along with the FADC window, preclude clusters from being
+	 * verified.
+	 */
+	private void logSettings() {
+		// Output general settings.
+		logger.config("Cluster Verification Settings");
+		logger.config(String.format("\tEnergy Threshold       :: %1.2f", energyAcceptance));
+		logger.config(String.format("\tHit Threshold          :: %1d", hitAcceptance));
+		
+		// Output window settings.
+		logger.config("FADC Timing Window Settings");
+		logger.config(String.format("\tNSB                    :: %3d ns", nsb));
+		logger.config(String.format("\tNSA                    :: %3d ns", nsa));
+		logger.config(String.format("\tFADC Window            :: %3d ns", windowWidth));
+		
+		// Calculate the valid clustering window.
+		int start = nsb;
+		int end = windowWidth - nsa;
+		if(start < end) {
+			logger.config(String.format("\tValid Cluster Window   :: [ %3d ns, %3d ns ]", start, end));
+			performClusterVerification = true;
+		} else {
+			logger.warning("\tNSB, NSA, and FADC window preclude a valid cluster verification window.");
+			logger.warning("\tCluster verification will not be performed!");
+			performClusterVerification = false;
+		}
+		
+		// Output the singles trigger settings.
+		for(int i = 0; i < 2; i++) {
+			logger.config(String.format("Singles Trigger %d Settings", (i + 1)));
+			logger.config(String.format("\tCluster Energy Low     :: %.3f GeV", singlesTrigger[i].getCutValue(TriggerModule.CLUSTER_TOTAL_ENERGY_LOW)));
+			logger.config(String.format("\tCluster Energy High    :: %.3f GeV", singlesTrigger[i].getCutValue(TriggerModule.CLUSTER_TOTAL_ENERGY_HIGH)));
+			logger.config(String.format("\tCluster Hit Count      :: %.0f hits", singlesTrigger[i].getCutValue(TriggerModule.CLUSTER_HIT_COUNT_LOW)));
+		}
+		
+		// Output the pair trigger settings.
+		for(int i = 0; i < 2; i++) {
+			logger.config(String.format("Pairs Trigger %d Settings", (i + 1)));
+			logger.config(String.format("\tCluster Energy Low     :: %.3f GeV", pairsTrigger[i].getCutValue(TriggerModule.CLUSTER_TOTAL_ENERGY_LOW)));
+			logger.config(String.format("\tCluster Energy High    :: %.3f Gen", pairsTrigger[i].getCutValue(TriggerModule.CLUSTER_TOTAL_ENERGY_HIGH)));
+			logger.config(String.format("\tCluster Hit Count      :: %.0f hits", pairsTrigger[i].getCutValue(TriggerModule.CLUSTER_HIT_COUNT_LOW)));
+			logger.config(String.format("\tPair Energy Sum Low    :: %.3f GeV", pairsTrigger[i].getCutValue(TriggerModule.PAIR_ENERGY_SUM_LOW)));
+			logger.config(String.format("\tPair Energy Sum Low    :: %.3f GeV", pairsTrigger[i].getCutValue(TriggerModule.PAIR_ENERGY_SUM_HIGH)));
+			logger.config(String.format("\tPair Energy Difference :: %.3f GeV", pairsTrigger[i].getCutValue(TriggerModule.PAIR_ENERGY_DIFFERENCE_HIGH)));
+			logger.config(String.format("\tPair Energy Slope      :: %.3f GeV", pairsTrigger[i].getCutValue(TriggerModule.PAIR_ENERGY_SLOPE_LOW)));
+			logger.config(String.format("\tPair Energy Slope F    :: %.3f GeV / mm", pairsTrigger[i].getCutValue(TriggerModule.PAIR_ENERGY_SLOPE_F)));
+			logger.config(String.format("\tPair Coplanarity       :: %.0f Degrees", pairsTrigger[i].getCutValue(TriggerModule.PAIR_COPLANARITY_HIGH)));
+			logger.config(String.format("\tPair Time Coincidence  :: %.0f ns", pairsTrigger[i].getCutValue(TriggerModule.PAIR_TIME_COINCIDENCE)));
 		}
 	}
 	
@@ -327,4 +729,49 @@
 				cluster.getXIndex(), cluster.getYIndex(), cluster.getEnergy(),
 				cluster.getHitCount(), cluster.getTime());
 	}
+	
+	private static final String reconClusterPositionString(Cluster cluster) {
+		return String.format("(%3d, %3d)",
+				cluster.getCalorimeterHits().get(0).getIdentifierFieldValue("ix"),
+				cluster.getCalorimeterHits().get(0).getIdentifierFieldValue("iy"));
+	}
+	
+	private static final String sspClusterPositionString(SSPCluster cluster) {
+		return String.format("(%3d, %3d)", cluster.getXIndex(), cluster.getYIndex());
+	}
+	
+	/**
+	 * Compares a trigger from the SSP bank to a trigger simulated on
+	 * an SSP 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 compareSSPSinglesTriggers(SSPSinglesTrigger bankTrigger, SinglesTrigger<SSPCluster> simTrigger) {
+		// The bank trigger and simulated trigger must have the same
+		// time. This is equivalent to the time of the triggering cluster.
+		if(bankTrigger.getTime() != simTrigger.getTriggerSource().getTime()) {
+			return false;
+		}
+		
+		// If the time stamp is the same, check that the trigger flags
+		// are all the same. Start with cluster energy low.
+		if(bankTrigger.passCutEnergyMin() != simTrigger.getStateClusterEnergyLow()) {
+			return false;
+		}
+		
+		// Check cluster energy high.
+		if(bankTrigger.passCutEnergyMax() != simTrigger.getStateClusterEnergyHigh()) {
+			return false;
+		}
+		
+		// Check cluster hit count.
+		if(bankTrigger.passCutHitCount() != simTrigger.getStateHitCount()) {
+			return false;
+		}
+		
+		// If all of the tests are successful, the triggers match.
+		return true;
+	}
 }

Top of Message | Previous Page | Permalink

Advanced Options


Options

Log In

Log In

Get Password

Get Password


Search Archives

Search Archives


Subscribe or Unsubscribe

Subscribe or Unsubscribe


Archives

November 2017
August 2017
July 2017
January 2017
December 2016
November 2016
October 2016
September 2016
August 2016
July 2016
June 2016
May 2016
April 2016
March 2016
February 2016
January 2016
December 2015
November 2015
October 2015
September 2015
August 2015
July 2015
June 2015
May 2015
April 2015
March 2015
February 2015
January 2015
December 2014
November 2014
October 2014
September 2014
August 2014
July 2014
June 2014
May 2014
April 2014
March 2014
February 2014
January 2014
December 2013
November 2013

ATOM RSS1 RSS2



LISTSERV.SLAC.STANFORD.EDU

Secured by F-Secure Anti-Virus CataList Email List Search Powered by the LISTSERV Email List Manager

Privacy Notice, Security Notice and Terms of Use