Commit in hps-java/src/main/java/org/lcsim/hps/recon/ecal on MAIN
HPSEcalFlashTrigger.java+412added 1.1
Initial Commit

hps-java/src/main/java/org/lcsim/hps/recon/ecal
HPSEcalFlashTrigger.java added at 1.1
diff -N HPSEcalFlashTrigger.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ HPSEcalFlashTrigger.java	7 Oct 2011 20:56:41 -0000	1.1
@@ -0,0 +1,412 @@
+package org.lcsim.hps.recon.ecal;
+                                                                                
+//--- Java ---//
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+//--- org.lcsim ---//
+import org.lcsim.event.Cluster;
+import org.lcsim.event.EventHeader;
+import org.lcsim.util.Driver;
+
+
+//--- hps-java ---//
+import org.lcsim.hps.users.omoreno.HPSTrigger;
+
+/**
+ * Heavy Photon Search ECal Flash Trigger
+ * 
+ * @author Omar Moreno <[log in to unmask]>
+ * @version $Id: HPSEcalFlashTrigger.java,v 1.1 2011/10/07 20:56:41 omoreno Exp $
+ */
+public class HPSEcalFlashTrigger extends Driver
+{
+    // The HPS ECal Clusterer
+    HPSEcal3Clusterer ecalClusterer;
+        
+    String ecalRawHitsCollectionName = "EcalHits";
+    String ecalClusterCollectionName = "EcalClusters";
+    
+    // A list to contain all cluster pairs in an event
+    List<Cluster[]> clusterPairs;
+    
+    int nTriggers;
+    int totalEvents;
+    
+    private double clusterEnergyHigh = 1.85; // GeV
+    private double clusterEnergyLow = .1;    // GeV 
+    private double energySumThreshold = 2;  // GeV
+    private double energyDifferenceThreshold = 1.5; // GeV
+    private double maxCoplanarityAngle = 35; // degrees
+       
+
+    /**
+     * Constructor
+     */
+    public HPSEcalFlashTrigger( )
+    {
+        // Instantiate the HPS Clusterer
+        ecalClusterer = new HPSEcal3Clusterer();
+        ecalClusterer.setClusterCollectionName( ecalClusterCollectionName );
+        ecalClusterer.setEcalCollectionName( ecalRawHitsCollectionName );
+        ecalClusterer.setEcalName( "Ecal" );
+        add( ecalClusterer );
+
+        clusterPairs = new ArrayList<Cluster[]>();
+    }
+
+    @Override
+    public void process(EventHeader event)
+    {
+    
+        super.process(event);
+        totalEvents +=1;
+
+        // Get a list of all clusters found by the clusterer in the event
+        List< Cluster > ecalClusters 
+            = event.get(Cluster.class, ecalClusterCollectionName);
+
+        //--- Apply Trigger Cuts ---//
+    
+        // Require that the event have at least two clusters in opposite
+        // quadrants
+        if ( !getClusterPairs( ecalClusters ) ) return;
+    
+        // Iterate through all cluster pairs present in the event.  If at least 
+        // one of the cluster pairs satisfies all of the trigger conditions, 
+        // a trigger signal is sent to all other detectors.
+        for( Iterator it = clusterPairs.iterator(); it.hasNext(); ){
+        
+            Cluster[] clusterPair = (Cluster[]) it.next();
+            
+            // Require the componets of a cluster pair to have an energy in
+            // the range of 100 MeV to 1.85 GeV
+            if( !clusterECut( clusterPair ) )  continue;
+        
+            // Require the sum of the energies of the components of the 
+            // cluster pair to be less than the 
+            // (Beam Energy)*(Sampling Fraction) ( 2 GeV for the Test Run )
+            if( !energySum( clusterPair ) )  continue;
+            
+            // Require the difference in energy of the components of the
+            // cluster pair to be less than 1.5 GeV
+            if( !energyDifference( clusterPair ) ) continue;
+            
+            // Apply a low energy cluster vs. distance cut of the form
+            // E_low + .0032 GeV/mm < .8 GeV
+            if( !energyDistanceCut( clusterPair ) ) continue; 
+            
+            // Require that the two clusters are coplanar with the beam within 
+            // 35 degrees
+            if( !coplanarityCut( clusterPair ) ) continue;
+           
+            // If all cuts are pased, send a trigger signal
+//            sendTrigger( );
+
+            // Increment number of triggers
+            nTriggers +=1;
+            
+            // Only require that at least one cluster pair passes all the 
+            // trigger cuts
+            break;
+        }
+    }
+    
+    /**
+     * Run before any processes are called
+     */
+    @Override
+    public void startOfData()
+    {
+        nTriggers = 0;
+        totalEvents = 0;
+    }
+    
+    /**
+     * Run after all data has been processed
+     */
+    @Override
+    public void endOfData( ) {
+        
+        System.out.println( "Total Number of Triggers: " + nTriggers );
+        System.out.println( "The Trigger Rate: " 
+            + ( double ) nTriggers/totalEvents +  "%" );
+    }
+
+    /**
+     * Get a list of all unique cluster pairs in the event
+     * 
+     * @param ecalClusters : List of ECal clusters
+     * @return true if there are any cluster pairs 
+     */
+    public boolean getClusterPairs(List<Cluster> ecalClusters)
+    {
+    
+        // Check to see if there are at least two clusters  
+        if (ecalClusters.size() < 2) return false;
+
+        // Create a list which will hold all neighboring cluster to the cluster 
+        // of interest
+        List< Cluster> ecalClusterNeighbors = new ArrayList< Cluster >();
+        for (Cluster ecalCluster : ecalClusters) {
+            ecalClusterNeighbors.add(ecalCluster);
+        }
+        
+        // Clear the list of cluster pairs
+        clusterPairs.clear();
+
+        for ( Cluster ecalCluster : ecalClusters ) { 
+        
+            // Get the quadrant which contains the ECal cluster of interest
+            int ecalClusterQuad = getECalQuadrant(ecalCluster);
+            
+            // Create a list of neighbors to the cluster of interest
+            ecalClusterNeighbors.remove(ecalCluster);
+
+            // Loop over all neigboring clusters and check to see if there is
+            // any which lie in opposing quadrants to the cluster of interest.
+            // If so, add them to the list of cluster pairs
+            for (Cluster ecalClusterNeighbor : ecalClusterNeighbors ){
+        
+                switch (ecalClusterQuad) {
+                    case 1:
+                        if ( getECalQuadrant( ecalClusterNeighbor ) == 3 ){
+                            Cluster[] clusterPair 
+                                = { ecalCluster, ecalClusterNeighbor };
+                            clusterPairs.add( clusterPair );
+                        }
+                        break;
+                    case 2:
+                        if ( getECalQuadrant( ecalClusterNeighbor ) == 4 ){
+                            Cluster[] clusterPair 
+                                = { ecalCluster, ecalClusterNeighbor };
+                            clusterPairs.add( clusterPair );
+                        }
+                        break;
+                    case 3:
+                        if ( getECalQuadrant( ecalClusterNeighbor ) == 1 ) {
+                            Cluster[] clusterPair 
+                                = { ecalCluster, ecalClusterNeighbor };
+                            clusterPairs.add(clusterPair);
+                        }
+                        break;
+                    case 4:
+                        if ( getECalQuadrant( ecalClusterNeighbor ) == 2 ) {
+                            Cluster[] clusterPair 
+                                = { ecalCluster, ecalClusterNeighbor };
+                            clusterPairs.add(clusterPair);
+                        }
+                        break;
+                }
+            }
+        }
+    
+        return !clusterPairs.isEmpty();
+    }
+                                                                                                                                                                                            
+    /**
+     * Checks if the ECal clusters making up a cluster pair lie above the low  
+     * energy threshold and below the high energy threshold
+     * 
+     * @param clusterPair : pair of clusters
+     * @return  true if a pair is found, false otherwise
+     */
+    public boolean clusterECut( Cluster[] clusterPair )
+    {
+        
+        if(           clusterPair[ 0 ].getEnergy( ) < clusterEnergyHigh 
+                && clusterPair[ 1 ].getEnergy( ) < clusterEnergyHigh
+                && clusterPair[ 0 ].getEnergy( ) > clusterEnergyLow 
+                && clusterPair[ 1 ].getEnergy( ) > clusterEnergyLow  )
+            return true;
+        
+        return false;
+    }
+    
+    /**
+     *  Returns the quadrant which contains the ECal cluster
+     * 
+     * @param ecalCluster : ECal cluster
+     * @return Quadrant number
+     */
+    public int getECalQuadrant(Cluster ecalCluster)
+    {
+        double[] clusterPosition = ecalCluster.getPosition();
+        
+        // Quadrant 1
+        if(( clusterPosition[0] > 0.0 ) && ( clusterPosition[1] > 0.0 )) 
+            return 1;
+        //Quadrant 2
+        if(( clusterPosition[0] < 0.0 ) && ( clusterPosition[1] > 0.0 )) 
+            return 2;
+        // Quadrant 3
+        if(( clusterPosition[0] < 0.0 ) && ( clusterPosition[1] < 0.0 )) 
+            return 3;
+        // Quadrant 4
+        return 4;
+    }
+
+    /**
+     * Checks if the sum of the energies of ECal clusters making up a cluster
+     * pair is below an energy sum threshold
+     * 
+     * @param clusterPair : pair of clusters
+     * @return true if a pair is found, false otherwise
+     */
+    public boolean energySum( Cluster[] clusterPair )
+    {
+        double clusterESum = clusterPair[ 0 ].getEnergy() 
+               + clusterPair[ 1 ].getEnergy();
+            if( clusterESum < energySumThreshold  ) return true;
+            
+            return false;
+    }
+    
+    /**
+     * Checks if the energy difference between the ECal clusters making up
+     * a cluster pair is below an energy difference threshold
+     * 
+     * @param clusterPair : pair of clusters
+     * @return  true if pair is found, false otherwise
+     */
+    public boolean energyDifference(  Cluster[] clusterPair )
+    {
+        double clusterEDifference 
+               = Math.abs( clusterPair[ 0 ].getEnergy( ) 
+                    - clusterPair[ 1 ].getEnergy() );
+        
+        if( clusterEDifference <  energyDifferenceThreshold ) 
+            return true;
+        
+        return false;
+        
+    }
+    
+    /**
+     * Require that the distance from the beam of the lowest energy cluster
+     * in a cluster pair satisfies the following
+     * E_low + d_b*.0032 GeV/mm < .8 GeV
+     * 
+     * @param clusterPiar : pair of clusters
+     * @return  true if pair is found, false otherwise
+     */
+    public boolean energyDistanceCut( Cluster[] clusterPair )
+    {          
+        Cluster lowEnergyCluster;
+        
+        // Obtain the lowest energy cluster
+        if( clusterPair[0].getEnergy() < clusterPair[1].getEnergy() )
+            lowEnergyCluster = clusterPair[0];
+       else lowEnergyCluster = clusterPair[1];
+        
+        // Calculate its position
+        double lowEClusterPosition
+           = Math.sqrt( Math.pow( lowEnergyCluster.getPosition()[0], 2) 
+                + Math.pow( lowEnergyCluster.getPosition()[1], 2) ); 
+        
+        double clusterDistvsE 
+                = lowEnergyCluster.getEnergy() + lowEClusterPosition*(0.0032);
+        
+        if( clusterDistvsE > .8  /* GeV */ ) return true;
+        
+        return false;
+    }
+       
+    /**
+     * Checks if a cluster pair is coplanar to the beam within a given
+     * angle
+     * 
+     * @param clusterPair : pair of clusters
+     * @return true if pair is found, false otherwise
+     */
+    public boolean coplanarityCut( Cluster[] clusterPair  )
+    {
+        // Find the distance of both clusters from the origin
+        double cluster1Dist 
+               = Math.sqrt( Math.pow( clusterPair[0].getPosition()[0],2 ) 
+                    + Math.pow( clusterPair[0].getPosition()[1],2) );
+        double cluster2Dist 
+               = Math.sqrt( Math.pow( clusterPair[1].getPosition()[0],2 ) 
+                    + Math.pow( clusterPair[1].getPosition()[1],2) );
+    
+        // Calculate the dot product between the distance vectors of 
+        // each cluster in the cluster pair
+        double clusterDot 
+           = clusterPair[0].getPosition()[0]*clusterPair[1].getPosition()[0]
+              +clusterPair[0].getPosition()[1]*clusterPair[1].getPosition()[1];
+        
+        // Find the angle between clusters in the pair
+        double cosphi = clusterDot/( cluster1Dist*cluster2Dist );
+        double phi = Math.toDegrees( Math.acos( cosphi ) );
+        
+        if( (180 - phi ) < maxCoplanarityAngle ) return true;
+        
+        return false;
+        
+    }
+
+    /**
+     * Sends an ECal trigger signal
+     */
+    public void sendTrigger()
+    {
+        HPSTrigger.addTrigger();
+    }
+    
+    /**
+     * Set the upper energy cluster threshold
+     * 
+     * @param highThreshold : Threshold in GeV
+     */
+    public void setUpperETheshold( double highThreshold )
+    {
+        
+        clusterEnergyHigh = highThreshold;
+    }
+    
+    /**
+     * Set the lower energy cluster threshold
+     * 
+     * @param lowThrehold : Threshold in GeV
+     */
+    public void setLowerEThreshold( double lowThreshold )
+    {
+        
+        clusterEnergyLow = lowThreshold;
+    }
+    
+    /**
+     * Set the threshold on the sum of the two cluster energies
+     * 
+     * @param sumThreshold : Threshold in GeV
+     */
+    public void setESumThreshold( double sumThreshold )
+    {
+        
+        energySumThreshold = sumThreshold;
+    }
+    
+    /**
+     * Set the threshold on the energy difference between two cluster energies
+     * 
+     * @param diffThreshold : Threshold in GeV
+     */
+    public void setEDiffThrehold( double diffThreshold )
+    {
+        
+        energyDifferenceThreshold = diffThreshold;
+    }
+    
+    /**
+     * Set the maximum angle required to achieve coplanarity between the
+     * clusters and the beam
+     * 
+     * @param maxCoplanarity : Maximum angle in degrees
+     */
+    public void setMaxCoplanarityAngle( double maxCoplanarity )
+    {
+        maxCoplanarityAngle = maxCoplanarity;
+    }
+
+}
CVSspam 0.2.8