hps-java/src/main/java/org/lcsim/hps/recon/ecal
diff -N HPSFADCSingleTriggerDriver.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ HPSFADCSingleTriggerDriver.java 2 Oct 2012 22:48:17 -0000 1.1
@@ -0,0 +1,242 @@
+package org.lcsim.hps.recon.ecal;
+
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.lcsim.event.Cluster;
+import org.lcsim.event.EventHeader;
+import org.lcsim.hps.evio.TriggerData;
+import org.lcsim.hps.util.ClockSingleton;
+
+/**
+ * Reads clusters and makes trigger decision using opposite quadrant criterion.
+ * Prints triggers to file if file path specified.
+ *
+ * @author Omar Moreno <[log in to unmask]>
+ * @author Sho Uemura <[log in to unmask]>
+ * @author Per Hansson Adrian <[log in to unmask]>
+ * @version $Id: HPSFADCSingleTriggerDriver.java,v 1.1 2012/10/02 22:48:17 phansson Exp $
+ */
+public class HPSFADCSingleTriggerDriver extends HPSTriggerDriver {
+
+ private static final double GeV = 1000;
+ // A list to contain all cluster pairs in an event
+ List<HPSEcalCluster[]> clusterPairs;
+ int nTriggers;
+ int totalEvents;
+ private double clusterEnergyHigh = 1.85 * GeV; // GeV
+ private double clusterEnergyLow = .1 * GeV; // GeV
+ private double energySumThreshold = 2.2 * GeV; // GeV
+ private double energyDifferenceThreshold = 1.5 * GeV; // GeV
+ private double maxCoplanarityAngle = 35; // degrees
+ int allClusters;
+ int clusterEnergyCount;
+ int deadtimelessTriggerCount;
+
+ public HPSFADCSingleTriggerDriver() {
+ clusterPairs = new LinkedList<HPSEcalCluster[]>();
+ }
+
+ @Override
+ public void startOfData() {
+ super.startOfData();
+
+ allClusters = 0;
+ clusterEnergyCount = 0;
+ deadtimelessTriggerCount = 0;
+ }
+
+ @Override
+ public boolean testTrigger(List<HPSEcalCluster> clusters) {
+ boolean trigger = false;
+
+ //--- Apply Trigger Cuts ---//
+
+ // Iterate through all clusters present in the event.
+ //If at least one of the clusters satisfies all of the trigger conditions,
+ // a trigger signal is sent to all other detectors.
+ for (HPSEcalCluster cluster : clusters) {
+
+
+ if (outputStream != null) {
+ outputStream.printf("Event %d: cluster energy %f in quadrant %d (%s)\n",
+ ClockSingleton.getClock(),
+ cluster.getEnergy(), HPSECalUtils.getQuadrant(cluster),cluster.getSeedHit().getPositionVec().toString());
+
+ }
+
+ allClusters++;
+
+
+ // Require the componets of a cluster pair to have an energy in
+ // the range of 100 MeV to 1.85 GeV
+ if (!clusterECut(cluster)) {
+ if (outputStream != null) {
+ outputStream.println("Failed cluster energy cut");
+ }
+ continue;
+ }
+ clusterEnergyCount++;
+
+ // If all cuts are pased, we have a trigger
+ if (outputStream != null) {
+ outputStream.println("Passed all cuts");
+ }
+ trigger = true;
+ }
+ if (trigger) {
+ deadtimelessTriggerCount++;
+ }
+ return trigger;
+ }
+
+ @Override
+ public void endOfData() {
+ if (outputStream != null) {
+ outputStream.printf("%s: Number of clusters: %d\n",this.getClass().getSimpleName(),allClusters);
+ outputStream.printf("%s: Number of cluster pairs after successive trigger conditions:\n",this.getClass().getSimpleName());
+ outputStream.printf("%s: Cluster energy: %d\n",this.getClass().getSimpleName(), clusterEnergyCount);
+ outputStream.printf("%s: Trigger count without dead time: %d\n",this.getClass().getSimpleName(), deadtimelessTriggerCount);
+ outputStream.printf("%s: Trigger count: %d\n",this.getClass().getSimpleName(), numTriggers);
+ outputStream.close();
+ }
+ System.out.printf("%s: Number of pairs: %d\n",this.getClass().getSimpleName(),allClusters);
+ System.out.printf("%s: Number of cluster pairs after successive trigger conditions:\n",this.getClass().getSimpleName());
+ System.out.printf("%s: Cluster energy: %d\n",this.getClass().getSimpleName(), clusterEnergyCount);
+ System.out.printf("%s: Trigger count without dead time: %d\n",this.getClass().getSimpleName(), deadtimelessTriggerCount);
+ System.out.printf("%s: Trigger count: %d\n",this.getClass().getSimpleName(), numTriggers);
+ super.endOfData();
+ }
+
+
+
+ /**
+ * Checks if the ECal clusters making up a cluster pair lie in opposite
+ * quadrants
+ *
+ * @param clusterPair : pair of clusters
+ * @return true if opposite quadrants, false otherwise
+ */
+ public boolean oppositeQuadrantsCut(HPSEcalCluster[] clusterPair) {
+ int quad1 = HPSECalUtils.getQuadrant(clusterPair[0]);
+ int quad2 = HPSECalUtils.getQuadrant(clusterPair[1]);
+
+ //if clusters are in the same quadrant, they're not opposite quadrants
+ if (quad1 == quad2) {
+ return false;
+ } //opposite pairs of quadrants are either both even (2 and 4) or both odd (1 and 3)
+ else {
+ return ((quad1 & 1) == (quad2 & 1));
+ }
+ }
+
+ /**
+ * 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(HPSEcalCluster cluster) {
+ return (cluster.getEnergy() < clusterEnergyHigh && cluster.getEnergy() > clusterEnergyLow);
+ }
+
+ /**
+ * 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();
+ return (clusterESum < energySumThreshold);
+ }
+
+ /**
+ * 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(HPSEcalCluster[] clusterPair) {
+ double clusterEDifference = Math.abs(clusterPair[0].getEnergy()
+ - clusterPair[1].getEnergy());
+
+ return (clusterEDifference < energyDifferenceThreshold);
+ }
+
+ /**
+ * 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 clusterPair : pair of clusters
+ * @return true if pair is found, false otherwise
+ */
+ public boolean energyDistanceCut(HPSEcalCluster[] clusterPair) {
+ HPSEcalCluster lowEnergyCluster;
+
+ // Obtain the lowest energy cluster
+ if (clusterPair[0].getEnergy() < clusterPair[1].getEnergy()) {
+ lowEnergyCluster = clusterPair[0];
+ } else {
+ lowEnergyCluster = clusterPair[1];
+ }
+
+ double lowEClusterPosition[] = lowEnergyCluster.getSeedHit().getPosition();
+ // Calculate its position
+ double lowEClusterDistance = Math.sqrt(Math.pow(lowEClusterPosition[0], 2)
+ + Math.pow(lowEClusterPosition[1], 2));
+
+ double clusterDistvsE = lowEnergyCluster.getEnergy() + lowEClusterDistance * (0.0032 * GeV);
+
+ if (clusterDistvsE > .8 * GeV /*
+ * 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(HPSEcalCluster[] clusterPair) {
+ double cluster1Position[] = clusterPair[0].getSeedHit().getPosition();
+ double cluster2Position[] = clusterPair[1].getSeedHit().getPosition();
+ // Find the distance of both clusters from the origin
+ double cluster1Dist = Math.sqrt(Math.pow(cluster1Position[0], 2)
+ + Math.pow(cluster1Position[1], 2));
+ double cluster2Dist = Math.sqrt(Math.pow(cluster2Position[0], 2)
+ + Math.pow(cluster2Position[1], 2));
+
+ // Calculate the dot product between the distance vectors of
+ // each cluster in the cluster pair
+ double clusterDot = cluster1Position[0] * cluster2Position[0]
+ + cluster1Position[1] * cluster2Position[1];
+
+ // Find the angle between clusters in the pair
+ double cosphi = clusterDot / (cluster1Dist * cluster2Dist);
+ double phi = Math.toDegrees(Math.acos(cosphi));
+
+ return ((180 - phi) < maxCoplanarityAngle);
+ }
+
+ /**
+ * Make a dummy TriggerData
+ */
+ @Override
+ protected void makeTriggerData(EventHeader event, String collectionName) {
+ TriggerData tData = new TriggerData(new int[8]);
+ List<TriggerData> triggerList = new ArrayList<TriggerData>();
+ triggerList.add(tData);
+ event.put(collectionName, triggerList, TriggerData.class, 0);
+ }
+}
\ No newline at end of file