Commit in hps-java/src/main/java/org/lcsim/hps on MAIN
recon/ecal/HPSFADCCalorimeterHit.java+49added 1.1
          /HPSFADCClusterer.java+191added 1.1
          /HPSEcalConverter.java+48added 1.1
          /HPSEcalConverterDriver.java+78added 1.1
          /HPSEcalFADCReadoutDriver.java+126added 1.1
          /HPSEcalDiscriminatorReadoutDriver.java+95-941.3 -> 1.4
          /HPSEcalWindowDiscriminatorReadoutDriver.java+2-21.1 -> 1.2
          /HPSEcalTimeEvolutionReadoutDriver.java+4-31.9 -> 1.10
          /HPSEcalReadoutDriver.java+6-51.13 -> 1.14
          /HPSEcalSimpleReadoutDriver.java+7-41.7 -> 1.8
analysis/ecal/HPSEcalFADCPlotsDriver.java+82added 1.1
+688-108
6 added + 5 modified, total 11 files
added FADC readout and clusterer

hps-java/src/main/java/org/lcsim/hps/recon/ecal
HPSFADCCalorimeterHit.java added at 1.1
diff -N HPSFADCCalorimeterHit.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ HPSFADCCalorimeterHit.java	4 Nov 2011 00:51:18 -0000	1.1
@@ -0,0 +1,49 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package org.lcsim.hps.recon.ecal;
+
+import org.lcsim.event.CalorimeterHit;
+import org.lcsim.event.RawCalorimeterHit;
+
+/**
+ *
+ * @author Sho Uemura <[log in to unmask]>
+ * @version $Id: HPSFADCCalorimeterHit.java,v 1.1 2011/11/04 00:51:18 meeg Exp $
+ */
+public class HPSFADCCalorimeterHit implements RawCalorimeterHit {
+
+	long cellID;
+	int amplitude;
+	int timestamp;
+	CalorimeterHit analogHit = null;
+
+	public HPSFADCCalorimeterHit(long cellID, int amplitude, int timestamp) {
+		this.cellID = cellID;
+		this.amplitude = amplitude;
+		this.timestamp = timestamp;
+	}
+
+	public long getCellID() {
+		return cellID;
+	}
+
+	public int getAmplitude() {
+		return amplitude;
+	}
+
+	public int getTimeStamp() {
+		return timestamp;
+	}
+
+	public CalorimeterHit getAnalogHit() {
+		return analogHit;
+	}
+
+	public void setAnalogHit(CalorimeterHit analogHit) {
+		this.analogHit = analogHit;
+	}
+
+
+}
\ No newline at end of file

hps-java/src/main/java/org/lcsim/hps/recon/ecal
HPSFADCClusterer.java added at 1.1
diff -N HPSFADCClusterer.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ HPSFADCClusterer.java	4 Nov 2011 00:51:19 -0000	1.1
@@ -0,0 +1,191 @@
+package org.lcsim.hps.recon.ecal;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.lcsim.event.CalorimeterHit;
+import org.lcsim.event.Cluster;
+import org.lcsim.event.EventHeader;
+import org.lcsim.event.RawCalorimeterHit;
+import org.lcsim.geometry.Detector;
+import org.lcsim.geometry.subdetector.HPSEcal3.NeighborMap;
+import org.lcsim.geometry.subdetector.HPSEcal3;
+import org.lcsim.util.Driver;
+import org.lcsim.util.lcio.LCIOConstants;
+
+/**
+ * This Driver creates clusters from the CalorimeterHits of an
+ * {@link org.lcsim.geometry.subdetectur.HPSEcal3} detector.
+ *
+ * The clustering algorithm is from pages 83 and 84 of the HPS Proposal.
+ *
+ * @author Sho Uemura <[log in to unmask]>
+ *
+ * @version $Id: HPSFADCClusterer.java,v 1.1 2011/11/04 00:51:19 meeg Exp $
+ */
+public class HPSFADCClusterer extends Driver {
+
+	HPSEcal3 ecal;
+	HPSEcalConverter converter = null;
+	String ecalCollectionName;
+	String ecalName;
+	String clusterCollectionName = "EcalClusters";
+	// Minimum E for cluster seed.
+	double seedEMin = .05;
+	// Minimum E to add hit to cluster.
+	double addEMin = .03;
+	// Odd or even number of crystals in X.
+	boolean oddX;
+	// Map of crystals to their neighbors.
+	NeighborMap neighborMap = null;
+	int coincidenceWindow = 2;
+	LinkedList<RawCalorimeterHit> buffer = new LinkedList<RawCalorimeterHit>();
+	int currentTime;
+
+	public HPSFADCClusterer() {
+	}
+
+	public void setClusterCollectionName(String clusterCollectionName) {
+		this.clusterCollectionName = clusterCollectionName;
+	}
+
+	public void setSeedEMin(double seedEMin) {
+		this.seedEMin = seedEMin;
+	}
+
+	public void setAddEMin(double addEMin) {
+		this.addEMin = addEMin;
+	}
+
+	public void setCoincidenceWindow(int coincidenceWindow) {
+		this.coincidenceWindow = coincidenceWindow;
+	}
+
+	public void setEcalCollectionName(String ecalCollectionName) {
+		this.ecalCollectionName = ecalCollectionName;
+	}
+
+	public void setEcalName(String ecalName) {
+		this.ecalName = ecalName;
+	}
+
+	public void startOfData() {
+		if (ecalCollectionName == null)
+			throw new RuntimeException("The parameter ecalCollectionName was not set!");
+
+		if (ecalName == null)
+			throw new RuntimeException("The parameter ecalName was not set!");
+	}
+
+	public void detectorChanged(Detector detector) {
+		// Get the Subdetector.
+		ecal = (HPSEcal3) detector.getSubdetector(ecalName);
+
+		// Cache ref to neighbor map.
+		neighborMap = ecal.getNeighborMap();
+
+		converter = new HPSEcalConverter(ecal.getIDDecoder());
+
+		//System.out.println(ecal.getName());
+		//System.out.println("  nx="+ecal.nx());
+		//System.out.println("  ny="+ecal.ny());
+		//System.out.println("  beamgap="+ecal.beamGap());
+		//System.out.println("  dface="+ecal.distanceToFace());
+
+		//System.out.println(neighborMap.toString());
+	}
+
+	public void process(EventHeader event) {
+		//System.out.println(this.getClass().getCanonicalName() + " - process");
+
+		// Get the list of raw ECal hits.
+		List<HPSFADCCalorimeterHit> hits = event.get(HPSFADCCalorimeterHit.class, ecalCollectionName);
+		if (hits == null)
+			throw new RuntimeException("Event is missing ECal raw hits collection!");
+
+		// Put Cluster collection into event.
+		int flag = 1 << LCIOConstants.CLBIT_HITS;
+		event.put(clusterCollectionName, createClusters(hits), Cluster.class, flag);
+	}
+
+	public List<Cluster> createClusters(List<HPSFADCCalorimeterHit> hits) {
+		buffer.addAll(hits);
+		// Make a hit map for quick lookup by ID.
+		Map<Long, CalorimeterHit> hitMap = new HashMap<Long, CalorimeterHit>();
+		if (!hits.isEmpty()) {
+			currentTime = hits.get(0).getTimeStamp();
+
+			while (buffer.peek().getTimeStamp() <= currentTime - coincidenceWindow) {
+				buffer.remove();
+			}
+
+			for (HPSFADCCalorimeterHit hit : hits) {
+				hitMap.put(hit.getCellID(), converter.HitDtoA(hit));
+			}
+		}
+
+		return createClusters(hitMap);
+	}
+
+	public List<Cluster> createClusters(Map<Long, CalorimeterHit> map) {
+
+		// New Cluster list to be added to event.
+		List<Cluster> clusters = new ArrayList<Cluster>();
+
+		Collection<CalorimeterHit> hits = map.values();
+
+		// Loop over ECal hits to find cluster seeds.
+		for (CalorimeterHit hit : hits) {
+			// Cut on min seed E.
+			if (hit.getRawEnergy() < seedEMin)
+				continue;
+
+			// Get neighbor crystal IDs.
+			Set<Long> neighbors = neighborMap.get(hit.getCellID());
+
+			if (neighbors == null)
+				throw new RuntimeException("Oops!  Set of neighbors is null!");
+
+			// List for neighboring hits.
+			List<CalorimeterHit> neighborHits = new ArrayList<CalorimeterHit>();
+
+			// Loop over neighbors to make hit list for cluster.
+			boolean isSeed = true;
+			for (Long neighborId : neighbors) {
+				// Find the neighbor hit in the event if it exists.
+				CalorimeterHit neighborHit = map.get(neighborId);
+
+				// Was this neighbor cell hit?
+				if (neighborHit != null) {
+					// Check if neighbor cell has more energy.
+					if (neighborHit.getRawEnergy() > hit.getRawEnergy()) {
+						// Neighbor has more energy, so cell is not a seed.
+						isSeed = false;
+						break;
+					}
+
+					// Add to cluster if above min E.
+					if (neighborHit.getRawEnergy() >= addEMin) {
+						neighborHits.add(neighborHit);
+					}
+				}
+			}
+
+			// Did we find a seed?
+			if (isSeed) {
+				// Make a cluster from the hit list.
+				HPSEcalCluster cluster = new HPSEcalCluster(hit);
+				for (CalorimeterHit clusHit : neighborHits) {
+					cluster.addHit(clusHit);
+				}
+				clusters.add(cluster);
+			}
+		}
+		return clusters;
+	}
+}
\ No newline at end of file

hps-java/src/main/java/org/lcsim/hps/recon/ecal
HPSEcalConverter.java added at 1.1
diff -N HPSEcalConverter.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ HPSEcalConverter.java	4 Nov 2011 00:51:19 -0000	1.1
@@ -0,0 +1,48 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package org.lcsim.hps.recon.ecal;
+
+import org.lcsim.event.CalorimeterHit;
+import org.lcsim.event.RawCalorimeterHit;
+import org.lcsim.geometry.IDDecoder;
+
+/**
+ *
+ * @author Sho Uemura <[log in to unmask]>
+ * @version $Id: HPSEcalConverter.java,v 1.1 2011/11/04 00:51:19 meeg Exp $
+ */
+public class HPSEcalConverter {
+
+	double scale = 0.01;
+	double pedestal = 0.0;
+	double period = 4.0;
+	double dt = 0.0;
+	IDDecoder dec;
+
+	public HPSEcalConverter(IDDecoder dec) {
+		this.dec = dec;
+	}
+
+	public int AtoD(double amplitude, long cellID) {
+		return (int) Math.floor((amplitude + pedestal) / scale);
+	}
+
+	public double DtoA(int amplitude, long cellID) {
+		return scale * (amplitude + 0.5) + pedestal;
+	}
+
+	public CalorimeterHit HitDtoA(HPSFADCCalorimeterHit hit) {
+		dec.setID(hit.getCellID());
+		if (hit.getAnalogHit() == null) {
+			hit.setAnalogHit(new HPSRawCalorimeterHit(DtoA(hit.getAmplitude(), hit.getCellID()), dec.getPosition(), period * hit.getTimeStamp() + dt, hit.getCellID(), 0));
+		}
+		return hit.getAnalogHit();
+	}
+
+	public RawCalorimeterHit HitAtoD(CalorimeterHit hit) {
+		dec.setID(hit.getCellID());
+		return new HPSFADCCalorimeterHit(hit.getCellID(), AtoD(hit.getRawEnergy(), hit.getCellID()), (int) Math.round(hit.getTime() / period));
+	}
+}

hps-java/src/main/java/org/lcsim/hps/recon/ecal
HPSEcalConverterDriver.java added at 1.1
diff -N HPSEcalConverterDriver.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ HPSEcalConverterDriver.java	4 Nov 2011 00:51:19 -0000	1.1
@@ -0,0 +1,78 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package org.lcsim.hps.recon.ecal;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.lcsim.event.CalorimeterHit;
+import org.lcsim.event.EventHeader;
+import org.lcsim.event.RawCalorimeterHit;
+import org.lcsim.geometry.Detector;
+import org.lcsim.geometry.Subdetector;
+import org.lcsim.util.Driver;
+import org.lcsim.util.lcio.LCIOConstants;
+
+/**
+ *
+ * @author Sho Uemura <[log in to unmask]>
+ * @version $Id: HPSEcalConverterDriver.java,v 1.1 2011/11/04 00:51:19 meeg Exp $
+ */
+public class HPSEcalConverterDriver extends Driver {
+
+	HPSEcalConverter converter = null;
+	Subdetector ecal;
+	String rawCollectionName;
+	String ecalName;
+	String ecalReadoutName = "EcalHits";
+	String ecalCollectionName = "EcalCorrectedHits";
+	int flags;
+
+	public HPSEcalConverterDriver() {
+		flags = 0;
+		flags += 1 << LCIOConstants.CHBIT_LONG; //store position
+		flags += 1 << LCIOConstants.RCHBIT_ID1; //store cell ID
+	}
+
+	public void setEcalCollectionName(String ecalCollectionName) {
+		this.ecalCollectionName = ecalCollectionName;
+	}
+
+	public void setEcalName(String ecalName) {
+		this.ecalName = ecalName;
+	}
+
+	public void setRawCollectionName(String rawCollectionName) {
+		this.rawCollectionName = rawCollectionName;
+	}
+
+	public void startOfData() {
+		if (ecalCollectionName == null)
+			throw new RuntimeException("The parameter ecalCollectionName was not set!");
+
+		if (ecalName == null)
+			throw new RuntimeException("The parameter ecalName was not set!");
+	}
+
+	public void detectorChanged(Detector detector) {
+		// Get the Subdetector.
+		ecal = (Subdetector) detector.getSubdetector(ecalName);
+		converter = new HPSEcalConverter(ecal.getIDDecoder());
+	}
+
+	public void process(EventHeader event) {
+		// Get the list of ECal hits.
+		List<HPSFADCCalorimeterHit> hits = event.get(HPSFADCCalorimeterHit.class, rawCollectionName);
+		if (hits == null)
+			throw new RuntimeException("Event is missing ECal hits collection!");
+
+		ArrayList<CalorimeterHit> newHits = new ArrayList<CalorimeterHit>();
+
+		for (HPSFADCCalorimeterHit hit : hits) {
+			newHits.add(converter.HitDtoA(hit));
+		}
+
+		event.put(ecalCollectionName, newHits, CalorimeterHit.class, flags, ecalReadoutName);
+	}
+}

hps-java/src/main/java/org/lcsim/hps/recon/ecal
HPSEcalFADCReadoutDriver.java added at 1.1
diff -N HPSEcalFADCReadoutDriver.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ HPSEcalFADCReadoutDriver.java	4 Nov 2011 00:51:19 -0000	1.1
@@ -0,0 +1,126 @@
+package org.lcsim.hps.recon.ecal;
+
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import java.util.PriorityQueue;
+import org.lcsim.event.CalorimeterHit;
+import org.lcsim.event.RawCalorimeterHit;
+import org.lcsim.hps.util.ClockSingleton;
+import org.lcsim.hps.util.RingBuffer;
+import org.lcsim.util.lcio.LCIOConstants;
+
+/**
+ * Performs readout of ECal hits.
+ * Simulates time evolution of preamp output pulse.
+ *
+ * @author Sho Uemura <[log in to unmask]>
+ * @version $Id: HPSEcalFADCReadoutDriver.java,v 1.1 2011/11/04 00:51:19 meeg Exp $
+ */
+public class HPSEcalFADCReadoutDriver extends HPSEcalReadoutDriver<RawCalorimeterHit> {
+	//buffer for deposited energy
+
+	Map<Long, RingBuffer> eDepMap = null;
+	//buffer for window sums
+	Map<Long, Double> sumMap = null;
+	//buffer for timestamps
+	Map<Long, Integer> timeMap = null;
+	//queue for hits to be output to clusterer
+	PriorityQueue<HPSFADCCalorimeterHit> outputQueue = null;
+	//length of ring buffer (in readout cycles)
+	int bufferLength = 100;
+	//shaper time constant in ns; negative values generate square pulses of the given width
+	double t0 = 18.0;
+	//delay (number of readout periods) between start of summing window and output of hit to clusterer
+	int delay0 = 32;
+	HPSEcalConverter converter = null;
+	double pulseIntegral;
+
+	public HPSEcalFADCReadoutDriver() {
+		flags = 0;
+		flags += 1 << LCIOConstants.RCHBIT_TIME; //store cell ID
+		hitClass = HPSFADCCalorimeterHit.class;
+		converter = new HPSEcalConverter(null);
+	}
+
+	public void setT0(double t0) {
+		this.t0 = t0;
+	}
+
+	public void setBufferLength(int bufferLength) {
+		this.bufferLength = bufferLength;
+		eDepMap = new HashMap<Long, RingBuffer>();
+	}
+
+	protected void readHits(List<RawCalorimeterHit> hits) {
+		for (Long cellID : eDepMap.keySet()) {
+			RingBuffer eDepBuffer = eDepMap.get(cellID);
+			Double sum = sumMap.get(cellID);
+			if (sum == null && eDepBuffer.currentValue() > threshold) {
+				timeMap.put(cellID, readoutCounter);
+				sumMap.put(cellID, eDepBuffer.currentValue());
+			}
+			if (sum != null) {
+				if (eDepBuffer.currentValue() < threshold || timeMap.get(cellID) + delay0 == readoutCounter) {
+//					System.out.printf("sum = %f\n",sum);
+					outputQueue.add(new HPSFADCCalorimeterHit(cellID, converter.AtoD((sum + eDepBuffer.currentValue()) / pulseIntegral, cellID), timeMap.get(cellID)));
+					sumMap.remove(cellID);
+				} else
+					sumMap.put(cellID, sum + eDepBuffer.currentValue());
+			}
+			eDepBuffer.step();
+		}
+		while (outputQueue.peek() != null && outputQueue.peek().getTimeStamp() <= readoutCounter - delay0) {
+			if (outputQueue.peek().getTimeStamp() < readoutCounter - delay0) {
+				System.out.println("Stale hit in output queue");
+				outputQueue.poll();
+			} else
+				hits.add(outputQueue.poll());
+		}
+	}
+
+	protected void putHits(List<CalorimeterHit> hits) {
+		//fill the readout buffers
+		for (CalorimeterHit hit : hits) {
+			RingBuffer eDepBuffer = eDepMap.get(hit.getCellID());
+			if (eDepBuffer == null) {
+				eDepBuffer = new RingBuffer(bufferLength);
+				eDepMap.put(hit.getCellID(), eDepBuffer);
+			}
+			for (int i = 0; i < bufferLength; i++) {
+				eDepBuffer.addToCell(i, hit.getRawEnergy() * pulseAmplitude((i + 1) * readoutPeriod + readoutTime() - (ClockSingleton.getTime() + hit.getTime())));
+			}
+		}
+	}
+
+	protected void initReadout() {
+		//initialize buffers
+		eDepMap = new HashMap<Long, RingBuffer>();
+		sumMap = new HashMap<Long, Double>();
+		timeMap = new HashMap<Long, Integer>();
+		outputQueue = new PriorityQueue(20, new HitComparator());
+		pulseIntegral = t0 * Math.E / readoutPeriod;
+	}
+
+	private double pulseAmplitude(double time) {
+		if (time < 0.0)
+			return 0.0;
+		if (t0 > 0.0) {
+			return (time / t0) * Math.exp(1.0 - time / t0);
+		} else {
+			if (time < -t0)
+				return 1.0;
+			else
+				return 0.0;
+		}
+	}
+
+	static class HitComparator implements Comparator<RawCalorimeterHit> {
+
+		public int compare(RawCalorimeterHit o1, RawCalorimeterHit o2) {
+			return o1.getTimeStamp() - o2.getTimeStamp();
+		}
+	}
+}
\ No newline at end of file

hps-java/src/main/java/org/lcsim/hps/recon/ecal
HPSEcalDiscriminatorReadoutDriver.java 1.3 -> 1.4
diff -u -r1.3 -r1.4
--- HPSEcalDiscriminatorReadoutDriver.java	7 Oct 2011 23:14:54 -0000	1.3
+++ HPSEcalDiscriminatorReadoutDriver.java	4 Nov 2011 00:51:19 -0000	1.4
@@ -14,60 +14,61 @@
  * Simulates time evolution of preamp output pulse and leading-edge discriminator.
  *
  * @author Sho Uemura <[log in to unmask]>
- * @version $Id: HPSEcalDiscriminatorReadoutDriver.java,v 1.3 2011/10/07 23:14:54 meeg Exp $
+ * @version $Id: HPSEcalDiscriminatorReadoutDriver.java,v 1.4 2011/11/04 00:51:19 meeg Exp $
  */
-public class HPSEcalDiscriminatorReadoutDriver extends HPSEcalReadoutDriver {
+public class HPSEcalDiscriminatorReadoutDriver extends HPSEcalReadoutDriver<HPSRawCalorimeterHit> {
 
-    //buffer for deposited energy
-    Map<Long, RingBuffer> eDepMap = null;
-    //last time we saw a rising edge
-    Map<Long, Double> edgeTimeMap = null;
-    //length of ring buffer (in multiples of bunch spacing)
-    int bufferLength = 200;
-    //shaper time constant in ns
-    double t0 = 18.0;
-    //discriminator output pulse width in ns
-    double outputWidth = 32.0;
-    //output hit "energy" in GeV
-    double outputEnergy = 10.0;
-
-    public HPSEcalDiscriminatorReadoutDriver() {
-    }
-
-    public void setBufferLength(int bufferLength) {
-        this.bufferLength = bufferLength;
-        eDepMap = new HashMap<Long, RingBuffer>();
-    }
-
-    public void setOutputWidth(double outputWidth) {
-        this.outputWidth = outputWidth;
-    }
-
-    /*
-     * Set shaper time constant.
-     * Positive values interpreted as shaping time of CR-RC pulse;
-     * negative values interpreted as width of rectangular pulse.
-     */
-    public void setT0(double t0) {
-        this.t0 = t0;
-    }
-
-    protected void readHits(List<HPSRawCalorimeterHit> hits) {
-        IDDecoder dec = ecal.getIDDecoder();
-        for (Long cellID : edgeTimeMap.keySet()) {
-            //if there's an output pulse, make a hit
-            if (ClockSingleton.getTime() - edgeTimeMap.get(cellID) < outputWidth) {
-                dec.setID(cellID);
-                hits.add(new HPSRawCalorimeterHit(outputEnergy, dec.getPosition(), 0.0, cellID, hitType));
-            }
-        }
-    }
-
-    protected void putHits(List<CalorimeterHit> hits) {
-        //fill the readout buffers
-        for (CalorimeterHit hit : hits) {
-            IDDecoder dec = ecal.getIDDecoder();
-            dec.setID(hit.getCellID());
+	//buffer for deposited energy
+	Map<Long, RingBuffer> eDepMap = null;
+	//last time we saw a rising edge
+	Map<Long, Double> edgeTimeMap = null;
+	//length of ring buffer (in multiples of bunch spacing)
+	int bufferLength = 200;
+	//shaper time constant in ns
+	double t0 = 18.0;
+	//discriminator output pulse width in ns
+	double outputWidth = 32.0;
+	//output hit "energy" in GeV
+	double outputEnergy = 10.0;
+
+	public HPSEcalDiscriminatorReadoutDriver() {
+		hitClass = HPSRawCalorimeterHit.class;
+	}
+
+	public void setBufferLength(int bufferLength) {
+		this.bufferLength = bufferLength;
+		eDepMap = new HashMap<Long, RingBuffer>();
+	}
+
+	public void setOutputWidth(double outputWidth) {
+		this.outputWidth = outputWidth;
+	}
+
+	/*
+	 * Set shaper time constant.
+	 * Positive values interpreted as shaping time of CR-RC pulse;
+	 * negative values interpreted as width of rectangular pulse.
+	 */
+	public void setT0(double t0) {
+		this.t0 = t0;
+	}
+
+	protected void readHits(List<HPSRawCalorimeterHit> hits) {
+		IDDecoder dec = ecal.getIDDecoder();
+		for (Long cellID : edgeTimeMap.keySet()) {
+			//if there's an output pulse, make a hit
+			if (ClockSingleton.getTime() - edgeTimeMap.get(cellID) < outputWidth) {
+				dec.setID(cellID);
+				hits.add(new HPSRawCalorimeterHit(outputEnergy, dec.getPosition(), readoutTime(), cellID, hitType));
+			}
+		}
+	}
+
+	protected void putHits(List<CalorimeterHit> hits) {
+		//fill the readout buffers
+		for (CalorimeterHit hit : hits) {
+			IDDecoder dec = ecal.getIDDecoder();
+			dec.setID(hit.getCellID());
 //            int ix = dec.getValue("ix");
 //            int iy = dec.getValue("iy");
 //            //temporary hack to disable crystals and flip X coordinate
@@ -75,46 +76,46 @@
 //            if (iy == 1 && ix * side >= -10 && ix * side <= -2)
 //                continue;
 
-            RingBuffer eDepBuffer = eDepMap.get(hit.getCellID());
-            if (eDepBuffer == null) {
-                eDepBuffer = new RingBuffer(bufferLength);
-                eDepMap.put(hit.getCellID(), eDepBuffer);
-            }
-            for (int i = 0; i < bufferLength; i++) {
-                eDepBuffer.addToCell(i, hit.getRawEnergy() * pulseAmplitude(i * ClockSingleton.getDt() - hit.getTime()));
-            }
-        }
-
-        //check for rising edges
-        for (Long cellID : eDepMap.keySet()) {
-            RingBuffer eDepBuffer = eDepMap.get(cellID);
-            //if there's a rising edge between now and the next time step, note the time
-            if ((eDepBuffer.currentValue() < threshold)
-                    && (eDepBuffer.getValue(1) > threshold))
-                edgeTimeMap.put(cellID, ClockSingleton.getTime());
-            eDepBuffer.step();
-        }
-    }
-
-    protected void initReadout() {
-        //initialize buffers
-        eDepMap = new HashMap<Long, RingBuffer>();
-        edgeTimeMap = new HashMap<Long, Double>();
-    }
-
-    /*
-     * Pulse shape as a function of time; normalized to have a peak height of 1.
-     */
-    protected double pulseAmplitude(double time) {
-        if (time < 0.0)
-            return 0.0;
-        if (t0 > 0.0) {
-            return (time / t0) * Math.exp(1.0 - time / t0);
-        } else {
-            if (time < -t0)
-                return 1.0;
-            else
-                return 0.0;
-        }
-    }
+			RingBuffer eDepBuffer = eDepMap.get(hit.getCellID());
+			if (eDepBuffer == null) {
+				eDepBuffer = new RingBuffer(bufferLength);
+				eDepMap.put(hit.getCellID(), eDepBuffer);
+			}
+			for (int i = 0; i < bufferLength; i++) {
+				eDepBuffer.addToCell(i, hit.getRawEnergy() * pulseAmplitude(i * ClockSingleton.getDt() - hit.getTime()));
+			}
+		}
+
+		//check for rising edges
+		for (Long cellID : eDepMap.keySet()) {
+			RingBuffer eDepBuffer = eDepMap.get(cellID);
+			//if there's a rising edge between now and the next time step, note the time
+			if ((eDepBuffer.currentValue() < threshold)
+					&& (eDepBuffer.getValue(1) > threshold))
+				edgeTimeMap.put(cellID, ClockSingleton.getTime());
+			eDepBuffer.step();
+		}
+	}
+
+	protected void initReadout() {
+		//initialize buffers
+		eDepMap = new HashMap<Long, RingBuffer>();
+		edgeTimeMap = new HashMap<Long, Double>();
+	}
+
+	/*
+	 * Pulse shape as a function of time; normalized to have a peak height of 1.
+	 */
+	protected double pulseAmplitude(double time) {
+		if (time < 0.0)
+			return 0.0;
+		if (t0 > 0.0) {
+			return (time / t0) * Math.exp(1.0 - time / t0);
+		} else {
+			if (time < -t0)
+				return 1.0;
+			else
+				return 0.0;
+		}
+	}
 }
\ No newline at end of file

hps-java/src/main/java/org/lcsim/hps/recon/ecal
HPSEcalWindowDiscriminatorReadoutDriver.java 1.1 -> 1.2
diff -u -r1.1 -r1.2
--- HPSEcalWindowDiscriminatorReadoutDriver.java	7 Oct 2011 23:14:54 -0000	1.1
+++ HPSEcalWindowDiscriminatorReadoutDriver.java	4 Nov 2011 00:51:19 -0000	1.2
@@ -16,7 +16,7 @@
  *
  *
  * @author Sho Uemura <[log in to unmask]>
- * @version $Id: HPSEcalWindowDiscriminatorReadoutDriver.java,v 1.1 2011/10/07 23:14:54 meeg Exp $
+ * @version $Id: HPSEcalWindowDiscriminatorReadoutDriver.java,v 1.2 2011/11/04 00:51:19 meeg Exp $
  */
 public class HPSEcalWindowDiscriminatorReadoutDriver extends HPSEcalDiscriminatorReadoutDriver {
     //last time we saw a rising edge
@@ -40,7 +40,7 @@
                 if (highTimeMap.containsKey(cellID) && ClockSingleton.getTime() - highTimeMap.get(cellID) < outputWidth)
                     continue;
                 dec.setID(cellID);
-                hits.add(new HPSRawCalorimeterHit(outputEnergy, dec.getPosition(), 0.0, cellID, hitType));
+                hits.add(new HPSRawCalorimeterHit(outputEnergy, dec.getPosition(), readoutTime(), cellID, hitType));
             }
         }
     }

hps-java/src/main/java/org/lcsim/hps/recon/ecal
HPSEcalTimeEvolutionReadoutDriver.java 1.9 -> 1.10
diff -u -r1.9 -r1.10
--- HPSEcalTimeEvolutionReadoutDriver.java	30 Sep 2011 23:31:27 -0000	1.9
+++ HPSEcalTimeEvolutionReadoutDriver.java	4 Nov 2011 00:51:19 -0000	1.10
@@ -14,9 +14,9 @@
  * Simulates time evolution of preamp output pulse.
  *
  * @author Sho Uemura <[log in to unmask]>
- * @version $Id: HPSEcalTimeEvolutionReadoutDriver.java,v 1.9 2011/09/30 23:31:27 meeg Exp $
+ * @version $Id: HPSEcalTimeEvolutionReadoutDriver.java,v 1.10 2011/11/04 00:51:19 meeg Exp $
  */
-public class HPSEcalTimeEvolutionReadoutDriver extends HPSEcalReadoutDriver {
+public class HPSEcalTimeEvolutionReadoutDriver extends HPSEcalReadoutDriver<HPSRawCalorimeterHit> {
 
     //buffer for deposited energy
     Map<Long, RingBuffer> eDepMap = null;
@@ -26,6 +26,7 @@
     double t0 = 18.0;
 
     public HPSEcalTimeEvolutionReadoutDriver() {
+		hitClass = HPSRawCalorimeterHit.class;
     }
 
     public void setT0(double t0) {
@@ -47,7 +48,7 @@
 //                int iy = dec.getValue("iy");
 //                if (iy == 1 && ix == -2)
 //                    System.out.printf("Time %f, output signal %f\n", ClockSingleton.getTime(), eDepBuffer.currentValue());
-                hits.add(new HPSRawCalorimeterHit(eDepBuffer.currentValue(), dec.getPosition(), readoutTime() - ClockSingleton.getTime(), cellID, hitType));
+                hits.add(new HPSRawCalorimeterHit(eDepBuffer.currentValue(), dec.getPosition(), readoutTime(), cellID, hitType));
             }
             eDepBuffer.step();
         }

hps-java/src/main/java/org/lcsim/hps/recon/ecal
HPSEcalReadoutDriver.java 1.13 -> 1.14
diff -u -r1.13 -r1.14
--- HPSEcalReadoutDriver.java	30 Sep 2011 23:31:27 -0000	1.13
+++ HPSEcalReadoutDriver.java	4 Nov 2011 00:51:19 -0000	1.14
@@ -15,15 +15,16 @@
  * Performs readout of ECal hits.
  *
  * @author Sho Uemura <[log in to unmask]>
- * @version $Id: HPSEcalReadoutDriver.java,v 1.13 2011/09/30 23:31:27 meeg Exp $
+ * @version $Id: HPSEcalReadoutDriver.java,v 1.14 2011/11/04 00:51:19 meeg Exp $
  */
-public abstract class HPSEcalReadoutDriver extends Driver {
+public abstract class HPSEcalReadoutDriver<T> extends Driver {
 
     Subdetector ecal;
     String ecalCollectionName;
     String ecalName;
     String ecalRawCollectionName = "EcalRawHits";
     String ecalReadoutName = "EcalHits";
+	Class hitClass;
     //hit type as in org.lcsim.recon.calorimetry.CalorimeterHitType
     int hitType = 0;
     //number of bunches in readout cycle
@@ -107,7 +108,7 @@
         //write hits into buffers
         putHits(hits);
 
-        ArrayList<HPSRawCalorimeterHit> newHits = new ArrayList<HPSRawCalorimeterHit>();
+        ArrayList<T> newHits = new ArrayList<T>();
 
         //if at the end of a readout cycle, write buffers to hits
         if (readoutCycle > 0) {
@@ -122,7 +123,7 @@
             }
         }
 
-        event.put(ecalRawCollectionName, newHits, HPSRawCalorimeterHit.class, flags, ecalReadoutName);
+        event.put(ecalRawCollectionName, newHits, hitClass, flags, ecalReadoutName);
     }
 
     protected double readoutTime() {
@@ -130,7 +131,7 @@
     }
 
     //read analog signal out of buffers and make hits; reset buffers
-    protected abstract void readHits(List<HPSRawCalorimeterHit> hits);
+    protected abstract void readHits(List<T> hits);
 
     //add deposited energy to buffers
     //must be run every event, even if the list is empty

hps-java/src/main/java/org/lcsim/hps/recon/ecal
HPSEcalSimpleReadoutDriver.java 1.7 -> 1.8
diff -u -r1.7 -r1.8
--- HPSEcalSimpleReadoutDriver.java	30 Sep 2011 23:31:27 -0000	1.7
+++ HPSEcalSimpleReadoutDriver.java	4 Nov 2011 00:51:19 -0000	1.8
@@ -12,13 +12,16 @@
  * No time evolution - this just integrates all hits in a cycle.
  *
  * @author Sho Uemura <[log in to unmask]>
- * @version $Id: HPSEcalSimpleReadoutDriver.java,v 1.7 2011/09/30 23:31:27 meeg Exp $
+ * @version $Id: HPSEcalSimpleReadoutDriver.java,v 1.8 2011/11/04 00:51:19 meeg Exp $
  */
-public class HPSEcalSimpleReadoutDriver extends HPSEcalReadoutDriver {
-
+public class HPSEcalSimpleReadoutDriver extends HPSEcalReadoutDriver<HPSRawCalorimeterHit> {
     //buffer for deposited energy
     Map<Long, Double> eDepMap = null;
 
+	public HPSEcalSimpleReadoutDriver() {
+		hitClass = HPSRawCalorimeterHit.class;
+	}
+
     protected void readHits(List<HPSRawCalorimeterHit> hits) {
         IDDecoder dec = ecal.getIDDecoder();
         for (Long cellID : eDepMap.keySet()) {
@@ -30,7 +33,7 @@
 //            if (iy == 1 && ix*side >= -10 && ix*side <= -2)
 //                continue;
             if (eDepMap.get(cellID) > threshold)
-                hits.add(new HPSRawCalorimeterHit(eDepMap.get(cellID), dec.getPosition(), 0.0, cellID, hitType));
+                hits.add(new HPSRawCalorimeterHit(eDepMap.get(cellID), dec.getPosition(), readoutTime(), cellID, hitType));
         }
         //reset hit integration
         eDepMap = new HashMap<Long, Double>();

hps-java/src/main/java/org/lcsim/hps/analysis/ecal
HPSEcalFADCPlotsDriver.java added at 1.1
diff -N HPSEcalFADCPlotsDriver.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ HPSEcalFADCPlotsDriver.java	4 Nov 2011 00:51:19 -0000	1.1
@@ -0,0 +1,82 @@
+package org.lcsim.hps.analysis.ecal;
+
+import hep.aida.IHistogram1D;
+
+import java.util.List;
+
+import org.lcsim.event.CalorimeterHit;
+import org.lcsim.event.EventHeader;
+import org.lcsim.event.RawCalorimeterHit;
+import org.lcsim.hps.recon.ecal.HPSEcalCluster;
+import org.lcsim.util.Driver;
+import org.lcsim.util.aida.AIDA;
+
+/**
+ * Diagnostic plots for HPS ECal.
+ *
+ * @author Sho Uemura <[log in to unmask]>
+ * @version $Id: HPSEcalFADCPlotsDriver.java,v 1.1 2011/11/04 00:51:19 meeg Exp $
+ */
+public class HPSEcalFADCPlotsDriver extends Driver {
+
+	String edepCollectionName = "EcalHits";
+	String rawCollectionName = "EcalRawHits";
+	String ecalCollectionName = "EcalCorrectedHits";
+	String clusterCollectionName = "EcalClusters";
+	AIDA aida = AIDA.defaultInstance();
+	IHistogram1D edepE;
+	IHistogram1D rawE;
+	IHistogram1D ecalE;
+	double edepThreshold = 0.2;
+
+	public void setEdepThreshold(double edepThreshold) {
+		this.edepThreshold = edepThreshold;
+	}
+
+	public void setEcalCollectionName(String ecalCollectionName) {
+		this.ecalCollectionName = ecalCollectionName;
+	}
+
+	public void setClusterCollectionName(String clusterCollectionName) {
+		this.clusterCollectionName = clusterCollectionName;
+	}
+
+	public void startOfData() {
+		edepE = aida.histogram1D(
+				edepCollectionName + " : Hits",
+				500, 0.0, 5.0);
+		rawE = aida.histogram1D(
+				rawCollectionName + " : Hits",
+				500, 0.0, 500.0);
+		ecalE = aida.histogram1D(
+				ecalCollectionName + " : Hits",
+				500, 0.0, 5.0);
+	}
+
+	public void process(EventHeader event) {
+		List<HPSEcalCluster> clusters = event.get(HPSEcalCluster.class, clusterCollectionName);
+		if (clusters == null)
+			throw new RuntimeException("Missing cluster collection!");
+
+		List<CalorimeterHit> edepHits = event.get(CalorimeterHit.class, edepCollectionName);
+		if (edepHits == null)
+			throw new RuntimeException("Missing hit collection!");
+		List<RawCalorimeterHit> rawHits = event.get(RawCalorimeterHit.class, rawCollectionName);
+		if (rawHits == null)
+			throw new RuntimeException("Missing hit collection!");
+		List<CalorimeterHit> ecalHits = event.get(CalorimeterHit.class, ecalCollectionName);
+		if (ecalHits == null)
+			throw new RuntimeException("Missing hit collection!");
+
+		for (CalorimeterHit hit : edepHits) {
+			if (hit.getRawEnergy() > edepThreshold)
+				edepE.fill(hit.getRawEnergy());
+		}
+		for (RawCalorimeterHit hit : rawHits) {
+			rawE.fill(hit.getAmplitude());
+		}
+		for (CalorimeterHit hit : ecalHits) {
+			ecalE.fill(hit.getRawEnergy());
+		}
+	}
+}
CVSspam 0.2.8