Print

Print


Author: mccaky
Date: Wed Oct 29 22:34:27 2014
New Revision: 1337

Log:
Updated Moller trigger driver with prescaling and proper trigger cut values. Added preliminary hardware diagnostic plots to primary trigger driver.

Modified:
    java/trunk/ecal-readout-sim/src/main/java/org/hps/readout/ecal/FADCPrimaryTriggerDriver.java
    java/trunk/ecal-readout-sim/src/main/java/org/hps/readout/ecal/MollerTriggerDriver.java

Modified: java/trunk/ecal-readout-sim/src/main/java/org/hps/readout/ecal/FADCPrimaryTriggerDriver.java
 =============================================================================
--- java/trunk/ecal-readout-sim/src/main/java/org/hps/readout/ecal/FADCPrimaryTriggerDriver.java	(original)
+++ java/trunk/ecal-readout-sim/src/main/java/org/hps/readout/ecal/FADCPrimaryTriggerDriver.java	Wed Oct 29 22:34:27 2014
@@ -21,7 +21,8 @@
  * The code for generating trigger pairs and handling the coincidence
  * window comes from <code>FADCTriggerDriver</code>.
  * 
- * @author Kyle McCarty
+ * @author Kyle McCarty <[log in to unmask]>
+ * @author Sho Uemura <[log in to unmask]>
  * @see FADCTriggerDriver
  */
 public class FADCPrimaryTriggerDriver extends TriggerDriver {
@@ -46,7 +47,7 @@
     private int pairCoincidence = 2;                              // Maximum allowed time difference between clusters. (4 ns clock-cycles)
     private double energySlopeParamF = 0.005500;                  // A parameter value used for the energy slope calculation.
     private double originX = 1393.0 * Math.tan(0.03052);          // ECal mid-plane, defined by photon beam position (30.52 mrad) at ECal face (z=1393 mm)
-    private int backgroundLevel = -1;                            // Automatically sets the cuts to achieve a predetermined background rate.
+    private int backgroundLevel = -1;                             // Automatically sets the cuts to achieve a predetermined background rate.
     
     // ==================================================================
     // ==== Driver Internal Variables ===================================
@@ -94,7 +95,16 @@
     IHistogram2D clusterDistributionSingle = aida.histogram2D("Trigger Plots :: Cluster Seed Distribution (Passed Single Cuts)", 46, -23, 23, 11, -5.5, 5.5);
     IHistogram2D clusterDistributionAll = aida.histogram2D("Trigger Plots :: Cluster Seed Distribution (Passed All Cuts)", 46, -23, 23, 11, -5.5, 5.5);
     
-    IHistogram1D hotCrystalEnergy = aida.histogram1D("Trigger Plots :: Hot Crystal Energy Distribution", 176, 0.0, 2.2);
+    // ==================================================================
+    // ==== Hardware Diagnostic Variables ===============================
+    // ==================================================================
+    IHistogram2D diagClusters = aida.histogram2D("Diagnostic Plots :: Cluster Seed Distribution", 46, -23, 23, 11, -5.5, 5.5);
+    IHistogram1D diagHitCount = aida.histogram1D("Diagnostic Plots :: Cluster Hit Count Distribution", 9, 1, 10);
+    IHistogram1D diagTotalEnergy = aida.histogram1D("Diagnostic Plots :: Cluster Total Energy Distribution", 176, 0.0, 2.2);
+    // TODO: Implement cluster latency plot.
+    
+    private boolean verbose = false;
+    
     
     /**
      * Prints out the results of the trigger at the end of the run.
@@ -118,6 +128,19 @@
         System.out.printf("%n");
         System.out.printf("\tTrigger Count :: %d%n", numTriggers);
         
+        // Print the trigger cuts.
+        System.out.printf("%nCut Values:%n");
+        System.out.printf("\tSeed Energy Low        :: %.2f%n", seedEnergyLow);
+        System.out.printf("\tSeed Energy High       :: %.2f%n", seedEnergyHigh);
+        System.out.printf("\tCluster Energy Low     :: %.2f%n", clusterEnergyLow);
+        System.out.printf("\tCluster Energy High    :: %.2f%n", clusterEnergyHigh);
+        System.out.printf("\tCluster Hit Count      :: %d%n", minHitCount);
+        System.out.printf("\tPair Energy Sum Low    :: %.2f%n", energySumLow);
+        System.out.printf("\tPair Energy Sum High   :: %.2f%n", energySumHigh);
+        System.out.printf("\tPair Energy Difference :: %.2f%n", energyDifferenceHigh);
+        System.out.printf("\tPair Energy Slope      :: %.2f%n", energySlopeLow);
+        System.out.printf("\tPair Coplanarity       :: %.2f%n", coplanarityHigh);
+        
         // Run the superclass method.
         super.endOfData();
     }
@@ -151,10 +174,9 @@
                 int ix = cluster.getSeedHit().getIdentifierFieldValue("ix");
                 int iy = cluster.getSeedHit().getIdentifierFieldValue("iy");
                 
-                // If the cluster is in the "hot" region, write out its
-                // energy to a special plot.
-                if((iy == 1 || iy == -1) && (ix == -1 || ix == 1 || ix == 2)) {
-                    hotCrystalEnergy.fill(clusterEnergy, 1);
+                // VERBOSE :: Note that a cluster is being processed.
+                if(verbose) {
+                	System.out.printf("%nProcessing cluster at (% 2d, % 2d)%n", ix, iy);
                 }
                 
                 // Correct for "hole" on the x-axis for plotting.
@@ -174,8 +196,18 @@
                     clusterDistribution100.fill(ix, iy, 1);
                 }
                 
+                // Populate the diagnostic plots.
+                diagClusters.fill(ix, iy, 1);
+                diagTotalEnergy.fill(clusterEnergy, 1);
+                diagHitCount.fill(hitCount, 1);
+                
                 // ==== Seed Hit Energy Cut ====================================
                 // =============================================================
+                // VERBOSE :: Print the seed energy comparison check.
+                if(verbose) {
+                	System.out.printf("\tSeed Energy Cut    :: %.3f < %.3f < %.3f --> %b%n", seedEnergyLow, seedEnergy, seedEnergyHigh, clusterSeedEnergyCut(cluster));
+                }
+                
                 // If the cluster fails the cut, skip to the next cluster.
                 if(!clusterSeedEnergyCut(cluster)) { continue clusterLoop; }
                 
@@ -184,6 +216,11 @@
                 
                 // ==== Cluster Hit Count Cut ==================================
                 // =============================================================
+                // VERBOSE :: Print the hit count comparison check.
+                if(verbose) {
+                	System.out.printf("\tHit Count Cut      :: %d >= %d --> %b%n", hitCount, minHitCount, clusterHitCountCut(cluster));
+                }
+                
                 // If the cluster fails the cut, skip to the next cluster.
                 if(!clusterHitCountCut(cluster)) { continue clusterLoop; }
                 
@@ -192,6 +229,11 @@
                 
                 // ==== Cluster Total Energy Cut ===============================
                 // =============================================================
+                // VERBOSE :: Print the cluster energy comparison check.
+                if(verbose) {
+                	System.out.printf("\tCluster Energy Cut :: %.3f < %.3f < %.3f --> %b%n", clusterEnergyLow, clusterEnergy, clusterEnergyHigh, clusterTotalEnergyCut(cluster));
+                }
+                
                 // If the cluster fails the cut, skip to the next cluster.
                 if(!clusterTotalEnergyCut(cluster)) { continue clusterLoop; }
                 
@@ -661,7 +703,7 @@
     
     private void setBackgroundCuts(int backgroundLevel) {
         // Make sure that the background level is valid.
-        if(backgroundLevel < 1 || backgroundLevel > 10) {
+        if(backgroundLevel < 0 || backgroundLevel > 10) {
             throw new RuntimeException(String.format("Trigger cuts are undefined for background level %d.", backgroundLevel));
         }
         
@@ -761,6 +803,17 @@
             energySlopeLow = 0.5;
             coplanarityHigh = 65;
             minHitCount = 2;
+        } else if(backgroundLevel == 0) {
+        	seedEnergyLow = 0.100;
+            seedEnergyHigh = 6.6;
+            clusterEnergyLow = 0.100;
+            clusterEnergyHigh = 1.500;
+            energySumLow = 0.000;
+            energySumHigh = 1.900;
+            energyDifferenceHigh = 2.200;
+            energySlopeLow = 1.10;
+            coplanarityHigh = 35;
+            minHitCount = 1;
         }
     }
     

Modified: java/trunk/ecal-readout-sim/src/main/java/org/hps/readout/ecal/MollerTriggerDriver.java
 =============================================================================
--- java/trunk/ecal-readout-sim/src/main/java/org/hps/readout/ecal/MollerTriggerDriver.java	(original)
+++ java/trunk/ecal-readout-sim/src/main/java/org/hps/readout/ecal/MollerTriggerDriver.java	Wed Oct 29 22:34:27 2014
@@ -30,7 +30,7 @@
  * supports a verbose mode where it will output more details with every
  * event to help with diagnostics.
  * 
- * @author Kyle McCarty
+ * @author Kyle McCarty <[log in to unmask]>
  */
 public class MollerTriggerDriver extends TriggerDriver {
     
@@ -55,7 +55,10 @@
     }
     
     @Override
-    public void process(EventHeader event) { super.process(event); }
+    public void process(EventHeader event) {
+    	// Run the superclass process event.
+    	super.process(event);
+    }
     
     @Override
     public void startOfData() {
@@ -74,20 +77,39 @@
         // Initialize the seed distribution diagnostic plots.
         clusterDistribution = aida.histogram2D("Trigger Plots :: Cluster Seed Distribution", 46, -23, 23, 11, -5.5, 5.5);
         aClusterDistribution = aida.histogram2D("Trigger Plots :: Cluster Seed Distribution (Passed All Cuts)", 46, -23, 23, 11, -5.5, 5.5);
+        clusterDistribution100 = aida.histogram2D("Trigger Plots :: Cluster Seed Distribution (Over 100 MeV)", 46, -23, 23, 11, -5.5, 5.5);
         
         // Initialize the seed percentage of cluster energy.
         seedPercent = aida.histogram1D("Analysis Plots :: Seed Percentage of Total Energy", 400, 0.0, 1.0);
         
+        // Initialize the momentum angle plot.
+        momentumAngle = aida.histogram2D("Trigger Plots :: Particle Momentum Distribution (t = 0)", 500, -0.01, 0.06, 500, -0.04, 0.04);
+        aMomentumAngle = aida.histogram2D("Trigger Plots :: Particle Momentum Distribution (t = 0, Passed All Cuts)", 500, -0.01, 0.06, 500, -0.04, 0.04);
+        
         // Add the allowed seed crystal positions to the seed set.
-        // y = +/- 1, x = -11 -> -15
-        for(int ix = -15; ix <= -11; ix++) {
-            allowedSeedSet.add(new Point(ix, 1));
-            allowedSeedSet.add(new Point(ix, -1));
-        } // y = +/- 2, x = -9 -> -15
-        for(int ix = -15; ix <= -9; ix++) {
-            allowedSeedSet.add(new Point(ix, 2));
-            allowedSeedSet.add(new Point(ix, -2));
-        }
+		if(useVersionOne) {
+	        // Add the allowed seed crystal positions to the seed set.
+	        // y = +/- 1, x = -11 -> -15
+	        for(int ix = -15; ix <= -11; ix++) {
+	            allowedSeedSet.add(new Point(ix, 1));
+	            allowedSeedSet.add(new Point(ix, -1));
+	        } // y = +/- 2, x = -9 -> -15
+	        for(int ix = -15; ix <= -9; ix++) {
+	            allowedSeedSet.add(new Point(ix, 2));
+	            allowedSeedSet.add(new Point(ix, -2));
+	        }
+		}
+		else {
+	        // y = +/- 1, x = -11 -> -13
+	        for(int ix = -13; ix <= -11; ix++) {
+	            allowedSeedSet.add(new Point(ix, 1));
+	            allowedSeedSet.add(new Point(ix, -1));
+	        } // y = +/- 2, x = -10 -> -14
+	        for(int ix = -14; ix <= -10; ix++) {
+	            allowedSeedSet.add(new Point(ix, 2));
+	            allowedSeedSet.add(new Point(ix, -2));
+	        }
+		}
     }
     
     @Override
@@ -139,6 +161,7 @@
             clusterTotalEnergy.fill(cluster.getEnergy());
             clusterSeedEnergy.fill(cluster.getSeedHit().getCorrectedEnergy());
             clusterDistribution.fill(ix > 0 ? ix - 1 : ix, iy, 1);
+            if(cluster.getSeedHit().getCorrectedEnergy() > 0.100) { clusterDistribution100.fill(ix > 0 ? ix - 1 : ix, iy, 1); }
             
             // VERBOSE :: Output the single cluster trigger thresholds.
             if(verbose) {
@@ -178,20 +201,31 @@
             // Require that the cluster pass each of the cuts in
             // order to qualify for a trigger.
             if(totalEnergyCut && seedEnergyCut && hitCountCut && positionCut) {
-                // Add the clusters to the cut histograms.
-                aClusterHitCount.fill(cluster.getCalorimeterHits().size());
-                aClusterTotalEnergy.fill(cluster.getEnergy());
-                aClusterSeedEnergy.fill(cluster.getSeedHit().getCorrectedEnergy());
-                aClusterDistribution.fill(ix > 0 ? ix - 1 : ix, iy, 1);
-                
-                // Increment the trigger count.
-                triggers++;
-                
-                // VERBOSE :: Indicate that a trigger occurred.
-                if(verbose) { System.out.printf("\tTriggered!%n%n"); }
-                
-                // Return a trigger.
-                return true;
+            	// Increment the number of events that have passed
+            	// the cuts.
+            	passedEvents++;
+            	
+            	// If the number of passed events exceeds the prescaling
+            	// threshold, throw a trigger.
+            	if(passedEvents >= prescale) {
+            		// Reset the number of passed events.
+            		passedEvents = 0;
+            		
+	                // Add the clusters to the cut histograms.
+	                aClusterHitCount.fill(cluster.getCalorimeterHits().size());
+	                aClusterTotalEnergy.fill(cluster.getEnergy());
+	                aClusterSeedEnergy.fill(cluster.getSeedHit().getCorrectedEnergy());
+	                aClusterDistribution.fill(ix > 0 ? ix - 1 : ix, iy, 1);
+	                
+	                // Increment the trigger count.
+	                triggers++;
+	                
+	                // VERBOSE :: Indicate that a trigger occurred.
+	                if(verbose) { System.out.printf("\tTriggered!%n%n"); }
+	                
+	                // Return a trigger.
+	                return true;
+            	}
             }
         }
         
@@ -331,6 +365,16 @@
     }
     
     /**
+     * Sets the number of events that must pass the trigger before a
+     * proper trigger flag is thrown.
+     * @param prescale - The number of passing events before a trigger
+     * will be thrown.
+     */
+    public void setPrescale(int prescale) {
+    	this.prescale = prescale;
+    }
+    
+    /**
      * Toggles whether the driver will output its actions to the console
      * during run time or not.
      * @param verbose - <code>true</code> indicates that the console
@@ -339,6 +383,18 @@
     public void setVerbose(boolean verbose) {
         this.verbose = verbose;
     }
+	
+    /**
+     * Toggles whether the more inclusive acceptance region version 1
+     * is used, or the slightly smaller and more exclusive acceptance
+     * region version 2.
+     * @param useVersionOne - <code>true</code> indicates that version
+     * 1 of the acceptance region should be used and <code>false</code>
+     * that version 2 should be used.
+     */
+	public void setUseVersionOne(boolean useVersionOne) {
+		this.useVersionOne = useVersionOne;
+	}
     
     // ==================================================================
     // ==== AIDA Plots ==================================================
@@ -351,86 +407,85 @@
     IHistogram1D clusterHitCount;
     IHistogram1D clusterSeedEnergy;
     IHistogram1D clusterTotalEnergy;
-    IHistogram1D pClusterHitCount;
-    IHistogram2D pClusterDistribution;
-    IHistogram1D pClusterSeedEnergy;
-    IHistogram1D pClusterTotalEnergy;
     IHistogram1D seedPercent;
+    IHistogram2D momentumAngle;
+    IHistogram2D aMomentumAngle;
+    IHistogram2D clusterDistribution100;
     
     // ==================================================================
     // ==== Variables ===================================================
     // ==================================================================
     
     /**
-     * <b>aida</b><br/><br/>
-     * <code>private AIDA <b>aida</b></code><br/><br/>
      * Factory for generating histograms.
      */
     private AIDA aida = AIDA.defaultInstance();
     
     /**
-     * <b>allowedSeedSet</b><br/><br/>
-     * <code>private Set<Point> <b>allowedSeedSet</b></code><br/><br/>
      * Contains all allowed seed crystal indices. Seeds outside of this
      * set will be rejected and not produce a trigger.
      */
     private Set<Point> allowedSeedSet = new HashSet<Point>();
     
     /**
-     * <b>clusterCollectionName</b><br/><br/>
-     * <code>private String <b>clusterCollectionName</b></code><br/><br/>
      * The name of the LCIO collection containing <code>HPSEcalCluster
      * </code> objects.
      */
     private String clusterCollectionName = "EcalClusters";
     
     /**
-     * <b>clusterHitCountThreshold</b><br/><br/>
-     * <code>private int <b>clusterHitCountThreshold</b></code><br/><br/>
      * Defines the minimum number of hits required for a cluster to
      * be used in triggering.
      */
-    private int clusterHitCountThreshold = 0;
-    
-    /**
-     * <b>clusterSeedEnergyThresholdLow</b><br/><br/>
-     * <code>private double <b>clusterSeedEnergyThresholdLow</b></code><br/><br/>
+    private int clusterHitCountThreshold = 5;
+    
+    /**
      * Defines the threshold for the cluster seed energy under which
      * a cluster will be rejected.
      */
-    private double clusterSeedEnergyThresholdLow = 0.00;
-    
-    /**
-     * <b>clusterSeedEnergyThresholdHigh</b><br/><br/>
-     * <code>private double <b>clusterSeedEnergyThresholdHigh</b></code><br/><br/>
+    private double clusterSeedEnergyThresholdLow = 0.300;
+    
+    /**
      * Defines the threshold for the cluster seed energy above which
      * a cluster will be rejected.
      */
-    private double clusterSeedEnergyThresholdHigh = Double.MAX_VALUE;
-    
-    /**
-     * <b>clusterTotalEnergyThresholdLow</b><br/><br/>
-     * <code>private double <b>clusterTotalEnergyThreshold</b></code><br/><br/>
+    private double clusterSeedEnergyThresholdHigh = 0.700;
+    
+    /**
      * Defines the threshold for the total cluster energy under which
      * a cluster will be rejected.
      */
-    private double clusterTotalEnergyThresholdLow = 0.0;
-    
-    /**
-     * <b>clusterTotalEnergyThresholdHigh</b><br/><br/>
-     * <code>private double <b>clusterTotalEnergyThresholdHigh</b></code><br/><br/>
+    private double clusterTotalEnergyThresholdLow = 0.600;
+    
+    /**
      * Defines the threshold for the total cluster energy above which
      * a cluster will be rejected.
      */
-    private double clusterTotalEnergyThresholdHigh = Double.MAX_VALUE;
-    
-    /**
-     * <b>verbose</b><br/><br/>
-     * <code>private boolean <b>verbose</b></code><br/><br/>
+    private double clusterTotalEnergyThresholdHigh = 0.775;
+    
+    /**
+     * The number of events that have passed the trigger cuts. This is
+     * used to determine when a trigger should be thrown for prescaling.
+     */
+    private int passedEvents = 0;
+    
+    /**
+     * Indicates how many events must pass the trigger cuts before a
+     * trigger is thrown.
+     */
+    private int prescale = 100;
+    
+    /**
      * Sets whether the driver outputs its clustering decisions to the
      * console or not.
      */
     private boolean verbose = false;
+    
+    /**
+     * Indicates whether trigger region version 1 or version 2 should
+     * be used.
+     */
+    private boolean useVersionOne = false;
     
     private int triggers = 0;                                      // Track the number of triggers.
     private int allClusters = 0;                                   // Track the number of clusters processed.