Print

Print


Commit in hps-java/src/main/java/org/lcsim/hps on MAIN
evio/LCSimTestRunEventBuilder.java+306added 1.1
    /TestRunReconToEvio.java+213-2131.2 -> 1.3
users/meeg/EvioFileReader.java+179added 1.1
recon/ecal/HPSEcalFADCReadoutDriver.java+183-241.7 -> 1.8
util/RingBuffer.java+43-431.3 -> 1.4
+924-280
2 added + 3 modified, total 5 files
continue work on ECal data conversion to/from EVIO; start work on FADC readout modes (doesn't work yet)

hps-java/src/main/java/org/lcsim/hps/evio
LCSimTestRunEventBuilder.java added at 1.1
diff -N LCSimTestRunEventBuilder.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ LCSimTestRunEventBuilder.java	1 Apr 2012 21:20:56 -0000	1.1
@@ -0,0 +1,306 @@
+package org.lcsim.hps.evio;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.jlab.coda.jevio.BaseStructure;
+import org.jlab.coda.jevio.BaseStructureHeader;
+import org.jlab.coda.jevio.CompositeData;
+import org.jlab.coda.jevio.EvioEvent;
+import org.jlab.coda.jevio.EvioException;
+import org.lcsim.detector.DetectorElementStore;
+import org.lcsim.detector.IDetectorElement;
+import org.lcsim.detector.identifier.IExpandedIdentifier;
+import org.lcsim.detector.identifier.IIdentifier;
+import org.lcsim.detector.identifier.IIdentifierDictionary;
+import org.lcsim.detector.tracker.silicon.SiSensor;
+import org.lcsim.event.EventHeader;
+import org.lcsim.event.RawCalorimeterHit;
+import org.lcsim.event.RawTrackerHit;
+import org.lcsim.event.base.BaseLCSimEvent;
+import org.lcsim.event.base.BaseRawCalorimeterHit;
+import org.lcsim.event.base.BaseRawTrackerHit;
+import org.lcsim.geometry.Detector;
+import org.lcsim.geometry.Subdetector;
+import org.lcsim.geometry.subdetector.HPSEcal3;
+import org.lcsim.geometry.subdetector.HPSTracker;
+import org.lcsim.geometry.util.IDEncoder;
+import org.lcsim.util.lcio.LCIOConstants;
+
+/**
+ * Build LCSim events from EVIO data.
+ * 
+ * @author Jeremy McCormick <[log in to unmask]>
+ *
+ */
+public class LCSimTestRunEventBuilder {
+
+	// Names of subdetectors.
+	private String trackerName;
+	private String calorimeterName;
+	// Names of raw data collections with default settings.
+	private String rawTrackerHitCollectionName = "RawTrackerHitMaker_RawTrackerHits";
+	private String rawCalorimeterHitCollectionName = "EcalRawHits";
+	// Detector conditions object.
+	private Detector detector;
+	// Debug flag.
+	private boolean debug = false;
+
+	public LCSimTestRunEventBuilder(String detectorName) {
+
+		// Make a dummy event to setup the conditions system.
+		EventHeader dummyEvent = new BaseLCSimEvent(0, 0, detectorName);
+		detector = dummyEvent.getDetector();
+
+		// Set default detector names by looking for HPS detector types.
+		for (Subdetector subdet : detector.getSubdetectorList()) {
+			if (subdet instanceof HPSTracker) {
+				trackerName = subdet.getName();
+				System.out.println("trackerName = " + trackerName);
+			} else if (subdet instanceof HPSEcal3) {
+				calorimeterName = subdet.getName();
+				System.out.println("calorimeterName = " + calorimeterName);
+			}
+		}
+	}
+
+	public void setDebug(boolean debug) {
+		this.debug = debug;
+	}
+
+	public String getRawTrackerHitCollectionName() {
+		return rawTrackerHitCollectionName;
+	}
+
+	public void setRawTrackerHitCollectionName(String rawTrackerHitCollectionName) {
+		this.rawTrackerHitCollectionName = rawTrackerHitCollectionName;
+	}
+
+	public String getRawCalorimeterHitCollectionName() {
+		return rawCalorimeterHitCollectionName;
+	}
+
+	public void setRawCalorimeterHitCollectionName(String rawCalorimeterHitCollectionName) {
+		this.rawCalorimeterHitCollectionName = rawCalorimeterHitCollectionName;
+	}
+
+	public String getTrackerName() {
+		return trackerName;
+	}
+
+	public void setTrackerName(String trackerName) {
+		this.trackerName = trackerName;
+	}
+
+	public String getTrackerReadoutName() {
+		return detector.getSubdetector(trackerName).getReadout().getName();
+	}
+
+	public String getCalorimeterName() {
+		return calorimeterName;
+	}
+
+	public void setCalorimeterName(String calorimeterName) {
+		this.calorimeterName = calorimeterName;
+	}
+
+	public String getCalorimeterReadoutName() {
+		return detector.getSubdetector(calorimeterName).getReadout().getName();
+	}
+
+	public Detector getDetector() {
+		return detector;
+	}
+
+	public EventHeader makeLCSimEvent(EvioEvent evioEvent) {
+
+		// Make RawTrackerHit collection.
+		List<RawTrackerHit> rawTrackerHits = makeRawTrackerHits(evioEvent);
+
+		// Make RawCalorimeterHit collection, combining top and bottom section of ECal into one list.
+		List<RawCalorimeterHit> rawCalorimeterHits = makeRawCalorimeterHits(evioEvent);
+
+		// Create a new LCSimEvent.
+		//EventHeader lcsimEvent = new BaseLCSimEvent(0, evioEvent.getHeader().getNumber(), detectorName);
+		EventHeader lcsimEvent = new BaseLCSimEvent(0, evioEvent.getHeader().getNumber(), detector.getDetectorName());
+
+		// Add the hit collections.
+		lcsimEvent.put(rawTrackerHitCollectionName, rawTrackerHits, RawTrackerHit.class, (1 << LCIOConstants.TRAWBIT_ID1), getTrackerReadoutName());
+		lcsimEvent.put(rawCalorimeterHitCollectionName, rawCalorimeterHits, RawCalorimeterHit.class, 0, getCalorimeterReadoutName());
+
+		return lcsimEvent;
+	}
+
+	private List<RawTrackerHit> makeRawTrackerHits(EvioEvent event) {
+		List<RawTrackerHit> rawTrackerHits = new ArrayList<RawTrackerHit>();
+		for (BaseStructure bank : event.getChildren()) {
+			if (bank.getHeader().getTag() == MCRawDataToEvio4Converter.trackerBankTag) {
+				//System.out.println("found SVT bank; tag = " + MCRawDataToEvio4Converter.trackerBankTag);
+				CompositeData cdata = null;
+				try {
+					cdata = bank.getCompositeData();
+				} catch (EvioException e) {
+					throw new RuntimeException(e);
+				}
+				rawTrackerHits.addAll(makeRawTrackerHits(cdata));
+			}
+		}
+		return rawTrackerHits;
+	}
+
+	private List<RawTrackerHit> makeRawTrackerHits(CompositeData cdata) {
+
+		// Get some ID info before looping in order to strip out irrelevant fields.
+		// TODO Next three should be cached so as to avoid calling every event. 
+		IIdentifierDictionary dict = detector.getSubdetector(trackerName).getDetectorElement().getIdentifierHelper().getIdentifierDictionary();
+		int fieldIdx = dict.getFieldIndex("side");
+		int sideIdx = dict.getFieldIndex("strip");
+
+		// List of hits to return.
+		List<RawTrackerHit> hits = new ArrayList<RawTrackerHit>();
+
+		// Loop over the items in the CompositeData.
+		int n = cdata.getNValue();
+		if (debug) {
+			System.out.println("RawTrackerHit.N = " + n);
+		}
+		for (int i = 0; i < n; i++) {
+
+			// Get values for hit from composite data.
+			Long id = cdata.getLong();
+			int time = cdata.getInt();
+			int adcValue = cdata.getInt();
+
+			// Make the new hit.
+			RawTrackerHit hit = new BaseRawTrackerHit(id, time, new short[]{(short) adcValue});
+
+			// The "side" and "strip" fields needs to be stripped from the ID for sensor lookup.
+			IExpandedIdentifier expId = dict.unpack(hit.getIdentifier());
+			expId.setValue(fieldIdx, 0);
+			expId.setValue(sideIdx, 0);
+			IIdentifier strippedId = dict.pack(expId);
+
+			// Find the sensor for this hit using the stripped ID.
+			SiSensor sensor = findSensor(strippedId);
+
+			// Assign sensor to hit.
+			hit.setDetectorElement(sensor);
+
+			// Add this hit to the list.
+			hits.add(hit);
+		}
+
+		if (debug) {
+			System.out.println("makeRawTrackerHits created " + hits.size() + " hits");
+		}
+
+		return hits;
+	}
+
+	private SiSensor findSensor(IIdentifier id) {
+		List<IDetectorElement> des = DetectorElementStore.getInstance().find(id);
+		SiSensor sensor = null;
+		if (des == null || des.isEmpty()) {
+			throw new RuntimeException("Failed to find any DetectorElements with ID <0x" + Long.toHexString(id.getValue()) + ">.");
+		} else if (des.size() == 1) {
+			sensor = (SiSensor) des.get(0);
+		} else {
+			for (IDetectorElement de : des) {
+				if (de instanceof SiSensor) {
+					sensor = (SiSensor) de;
+					break;
+				}
+			}
+		}
+		if (sensor == null) {
+			throw new RuntimeException("No sensor was found with ID <0x" + Long.toHexString(id.getValue()) + ">.");
+		}
+		return sensor;
+	}
+
+	private List<RawCalorimeterHit> makeRawCalorimeterHits(EvioEvent event) {
+		List<RawCalorimeterHit> hits = new ArrayList<RawCalorimeterHit>();
+		for (BaseStructure bank : event.getChildren()) {
+			BaseStructureHeader header = bank.getHeader();
+			int bankTag = header.getTag();
+			if (bankTag == MCRawDataToEvio4Converter.ecalBottomBankTag || bankTag == MCRawDataToEvio4Converter.ecalTopBankTag) {
+				if (bank.getChildCount() > 0) {
+					System.out.println("ECal bank tag: " + header.getTag() + "; childCount: " + bank.getChildCount());
+					for (BaseStructure slotBank : bank.getChildren()) {
+						CompositeData cdata = null;
+						try {
+							cdata = slotBank.getCompositeData();
+						} catch (EvioException e) {
+							throw new RuntimeException(e);
+						}
+						List<RawCalorimeterHit> bankHits = makeRawCalorimeterHits(cdata, bankTag);
+						hits.addAll(bankHits);
+					}
+				}
+			}
+		}
+		return hits;
+	}
+
+	private List<RawCalorimeterHit> makeRawCalorimeterHits(CompositeData cdata, int bankTag) {
+		List<RawCalorimeterHit> hits = new ArrayList<RawCalorimeterHit>();
+		IDEncoder enc = new IDEncoder(detector.getSubdetector(calorimeterName).getIDDecoder().getIDDescription());
+
+		if (debug) {
+			int n = cdata.getNValues().size();
+			for (int i = 0; i < n; i++) {
+				System.out.println("cdata.N[" + i + "]=" + cdata.getNValues().get(i));
+			}
+			int ni = cdata.getItems().size();
+			for (int i = 0; i < ni; i++) {
+				System.out.println("cdata.type[" + i + "]=" + cdata.getTypes().get(i));
+			}
+		}
+
+		int slot = cdata.getByte();
+		int trigger = cdata.getInt();
+		long timestamp = cdata.getLong();
+		int nchannels = cdata.getNValue();
+		if (debug) {
+			System.out.println("slot#=" + slot + "; trigger=" + trigger + "; timestamp=" + timestamp + "; nchannels=" + nchannels);
+		}
+		for (int j = 0; j < nchannels; j++) {
+			int channelNumber = cdata.getByte();
+			int npulses = cdata.getNValue();
+			if (debug) {
+				System.out.println("  channel=" + channelNumber + "; npulses=" + npulses);
+			}
+			for (int k = 0; k < npulses; k++) {
+				short pulseTime = cdata.getShort();
+				int pulseIntegral = cdata.getInt();
+				if (debug) {
+					System.out.println("    pulseTime=" + pulseTime + "; pulseIntegral=" + pulseIntegral);
+				}
+				
+				//TODO: replace this with the real ID translation scheme
+				if (bankTag == MCRawDataToEvio4Converter.ecalTopBankTag) {
+					enc.setValue("iy", slot);
+				} else {
+					enc.setValue("iy", -1 * slot);
+				}
+				enc.setValue("ix", channelNumber - EventConstants.ECAL_CHANNEL_OFFSET);
+				
+				hits.add(new BaseRawCalorimeterHit(enc.getID(), pulseIntegral, pulseTime));
+			}
+		}
+		return hits;
+	}
+
+	private List<RawCalorimeterHit> makeRawCalorimeterHits_old(CompositeData cdata) {
+		List<RawCalorimeterHit> hits = new ArrayList<RawCalorimeterHit>();
+		List<Object> items = cdata.getItems();
+		int n = cdata.getNValue();
+		for (int i = 0; i < n; i++) {
+			long id = cdata.getLong();
+			int amplitude = cdata.getInt();
+			int timestamp = cdata.getInt();
+			hits.add(new BaseRawCalorimeterHit(id, amplitude, timestamp));
+		}
+		return hits;
+	}
+}
\ No newline at end of file

hps-java/src/main/java/org/lcsim/hps/evio
TestRunReconToEvio.java 1.2 -> 1.3
diff -u -r1.2 -r1.3
--- TestRunReconToEvio.java	29 Mar 2012 04:14:14 -0000	1.2
+++ TestRunReconToEvio.java	1 Apr 2012 21:20:56 -0000	1.3
@@ -37,227 +37,227 @@
  * @author Jeremy McCormick <[log in to unmask]>
  */
 public class TestRunReconToEvio extends Driver {
-             
-    EventWriter writer;
-    
-    String rawCalorimeterHitCollectionName = "EcalDigitizedHits";
-    String svtCollectionName = "SVTData";
-    String evioOutputFile = "MCRawData.evio";
-    
-    EventBuilder builder = null;                  
-    private int eventsWritten = 0;
-        
-    public TestRunReconToEvio() 
-    {}
-        
-    public void setEvioOutputFile(String evioOutputFile) {
-        this.evioOutputFile = evioOutputFile;
-    }
-        
-    public void setSVTDataCollectionName(String svtCollectionName) {
-    	this.svtCollectionName = svtCollectionName;
-    }
-    
-    public void setRawCalorimeterHitCollectionName(String rawCalorimeterHitCollectionName) {
-        this.rawCalorimeterHitCollectionName = rawCalorimeterHitCollectionName;
-    }
-    
-    protected void startOfData() {
-        try {
-            writer = new EventWriter(evioOutputFile);
-        }
-        catch (EvioException e) {
-            throw new RuntimeException(e);
-        }
-    }
-    
-    protected void endOfData() {
-        System.out.println(this.getClass().getSimpleName() + " - wrote " + eventsWritten + " EVIO events in job.");
-        try {
-            writer.close();
-        } catch (EvioException e) {
-            throw new RuntimeException(e);
-        } catch (IOException e) {
-            throw new RuntimeException(e);
-        }
-    }
-        
-    protected void process(EventHeader event) {
-        
-        // Make a new EVIO event.
-        builder = new EventBuilder(0, DataType.BANK, event.getEventNumber());
-                
-        // Write SVTData.
-        writeSVTData(event);        
-        
-        // Write RawCalorimeterHit collection.
-        writeRawCalorimeterHits(event);        
-        
-        // Write this EVIO event.
-        writeEvioEvent();
-    }
+
+	EventWriter writer;
+	String rawCalorimeterHitCollectionName = "EcalDigitizedHits";
+	String svtCollectionName = "SVTData";
+	String evioOutputFile = "MCRawData.evio";
+	EventBuilder builder = null;
+	private int eventsWritten = 0;
+
+	public TestRunReconToEvio() {
+	}
+
+	public void setEvioOutputFile(String evioOutputFile) {
+		this.evioOutputFile = evioOutputFile;
+	}
+
+	public void setSVTDataCollectionName(String svtCollectionName) {
+		this.svtCollectionName = svtCollectionName;
+	}
+
+	public void setRawCalorimeterHitCollectionName(String rawCalorimeterHitCollectionName) {
+		this.rawCalorimeterHitCollectionName = rawCalorimeterHitCollectionName;
+	}
+
+	protected void startOfData() {
+		try {
+			writer = new EventWriter(evioOutputFile);
+		} catch (EvioException e) {
+			throw new RuntimeException(e);
+		}
+	}
+
+	protected void endOfData() {
+		System.out.println(this.getClass().getSimpleName() + " - wrote " + eventsWritten + " EVIO events in job.");
+		try {
+			writer.close();
+		} catch (EvioException e) {
+			throw new RuntimeException(e);
+		} catch (IOException e) {
+			throw new RuntimeException(e);
+		}
+	}
+
+	protected void process(EventHeader event) {
+
+		// Make a new EVIO event.
+		builder = new EventBuilder(0, DataType.BANK, event.getEventNumber());
+
+		// Write SVTData.
+		writeSVTData(event);
+
+		// Write RawCalorimeterHit collection.
+		writeRawCalorimeterHits(event);
+
+		// Write this EVIO event.
+		writeEvioEvent();
+	}
 
 	private void writeEvioEvent() {
 		builder.setAllHeaderLengths();
-        try {
-            writer.writeEvent(builder.getEvent());
-            ++eventsWritten;
-        } catch (EvioException e) {
-            throw new RuntimeException(e);
-        } catch (IOException e) {
-            throw new RuntimeException(e);
-        }
+		try {
+			writer.writeEvent(builder.getEvent());
+			++eventsWritten;
+		} catch (EvioException e) {
+			throw new RuntimeException(e);
+		} catch (IOException e) {
+			throw new RuntimeException(e);
+		}
 	}
 
 	private void writeRawCalorimeterHits(EventHeader event) {
-		List<RawCalorimeterHit> rawCalorimeterHits = event.get(RawCalorimeterHit.class, rawCalorimeterHitCollectionName); 
-        LCMetaData meta = event.getMetaData(rawCalorimeterHits);
-        writeRawCalorimeterHits(meta, rawCalorimeterHits, builder);        
+		List<RawCalorimeterHit> rawCalorimeterHits = event.get(RawCalorimeterHit.class, rawCalorimeterHitCollectionName);
+		LCMetaData meta = event.getMetaData(rawCalorimeterHits);
+		writeRawCalorimeterHits(meta, rawCalorimeterHits, builder);
 	}
 
 	private void writeSVTData(EventHeader event) {
 		List<List<HPSSVTData>> svtDataList = event.get(HPSSVTData.class);
-        if (svtDataList != null) {
-        	if (svtDataList.size() > 0) {
-        		if (svtDataList.get(0) != null) {
-        			this.writeSVTData(svtDataList.get(0));
-        		}         		
-        	}
-        }
-	}
-	
-    private void writeSVTData(List<HPSSVTData> data) {
-    	if (data == null) {
-    		throw new RuntimeException("The list points to null.");
-    	}
-    	
-    	int nsamples = data.size();
-    	int evioIntData[] = new int[nsamples*4];
-    	
-    	int i = 0;
-    	for (HPSSVTData sample : data) {
-    		int[] sampleData = sample.getData();
-    		//System.out.println(Integer.toHexString(sampleData[0]) + ":" + Integer.toHexString(sampleData[1])+ ":" + Integer.toHexString(sampleData[2])+ ":" + Integer.toHexString(sampleData[3]));
-    		evioIntData[i] = sampleData[0];
-    		evioIntData[i+1] = sampleData[1];
-    		evioIntData[i+2] = sampleData[2];
-    		evioIntData[i+3] = sampleData[3];
-    		i += 4;    		
-    	}    	    
-    	EvioBank bank = new EvioBank(SVT_BANK_TAG, DataType.UINT32, SVT_BANK_NUMBER);
-    	try {
-    		bank.appendIntData(evioIntData);
-    	} catch (EvioException e) {
-    		throw new RuntimeException(e);
-    	}
-    	bank.setAllHeaderLengths();
-        try {
-            builder.addChild(builder.getEvent(), bank);
-        } catch (EvioException e) {
-            throw new RuntimeException(e);
-        }
-    }          
-
-    private void writeRawCalorimeterHitCollection(List<RawCalorimeterHit> hits, LCMetaData meta, int bankTag, EventBuilder builder) {
-    	
-    	// Get the ID decoder.
-    	IDDecoder dec = meta.getIDDecoder();
-    	
-    	// Make a hit map.
-    	Map<Long,RawCalorimeterHit> hitMap = new HashMap<Long,RawCalorimeterHit>();
-    	for (RawCalorimeterHit hit : hits) {
-    		hitMap.put(hit.getCellID(), hit);
-    	}
-    	
-    	// Make map of slot number to hit IDs.
-    	Map<Integer,List<Long>> slotMap = new HashMap<Integer,List<Long>>();
-    	for (Long id : hitMap.keySet()) {
-    		dec.setID(id);
-    		int iy = dec.getValue("iy"); // treating as slot number    		
-    		int slot = Math.abs(iy);    		
-    		if (slotMap.get(slot) == null) {
-    			slotMap.put(slot, new ArrayList<Long>());
-    		}
-    		List<Long> slots = slotMap.get(slot);    		
-    		slots.add(id);    		
-    	}
-    	
-    	// Make a new bank for this crate.
-    	EvioBank crateBank = new EvioBank(bankTag, DataType.BANK, ECAL_BANK_NUMBER);
-    	    	    	
-    	// Loop over the slots in the map.
-    	for (int slot : slotMap.keySet()) {
-    		    		    		
-    		// New bank for this slot.
-    		EvioBank slotBank = new EvioBank(ECAL_PULSE_INTEGRAL_BANK_TAG, DataType.COMPOSITE, slot);
-    		    		
-    		// Create composite data for this slot and its channels.
-    		CompositeData.Data data = new CompositeData.Data();    		
-    		data.addUchar((byte)slot); // slot #
-    		data.addUint(0); // trigger #
-    		data.addUlong(0); // timestamp    		
-    		List<Long> hitIDs = slotMap.get(slot);
-    		int nhits = hitIDs.size();    		
-    		data.addN(nhits); // number of channels
-    		for (Long id : hitIDs) {
-    			dec.setID(id);
-    			int ix = dec.getValue("ix");
-    			int channel = ix + ECAL_CHANNEL_OFFSET;
-    			data.addUchar((byte)channel); // channel #
-    			data.addN(1); // number of pulses
-    			RawCalorimeterHit hit = hitMap.get(id);
-    			data.addUshort((short)hit.getTimeStamp()); // pulse time
-    			data.addUint((int)hit.getAmplitude()); // pulse integral
-    		}    		  
-    		    		
-    		// Add CompositeData to bank.
-    		CompositeData cdata = null;
-            try {            	            
-                cdata = new CompositeData(ECAL_PULSE_INTEGRAL_FORMAT, 1, data, ECAL_PULSE_INTEGRAL_BANK_TAG, slot);
-                slotBank.appendCompositeData(cdata);
-            }
-            catch (EvioException e) {
-                throw new RuntimeException(e);
-            }                        
-    		
-            // Add slot bank to crate bank.
-        	slotBank.setAllHeaderLengths();
-        	try {
-        		builder.addChild(crateBank, slotBank);
-            } catch (EvioException e) {
-                throw new RuntimeException(e);
-            }    	    
-    	}    	
-    	try {
-    		crateBank.setAllHeaderLengths();
-            builder.addChild(builder.getEvent(), crateBank);
-        } catch (EvioException e) {
-            throw new RuntimeException(e);
-        }    	    
-    }
-    
-    private void writeRawCalorimeterHits(LCMetaData meta, List<RawCalorimeterHit> rawCalorimeterHits, EventBuilder builder) {        
-
-    	// Make two lists containing the hits from top and bottom sections, which go into separate EVIO data banks.
-        IDDecoder dec = meta.getIDDecoder();
-        List<RawCalorimeterHit> topHits = new ArrayList<RawCalorimeterHit>();
-        List<RawCalorimeterHit> bottomHits = new ArrayList<RawCalorimeterHit>();        
-        for (RawCalorimeterHit hit : rawCalorimeterHits) {
-            dec.setID(hit.getCellID());
-            int iy = dec.getValue("iy");
-            // Negative iy should be bottom section.
-            if (iy < 0) {
-                bottomHits.add(hit);
-            }
-            // Positive iy should be top section.
-            else {
-                topHits.add(hit);
-            }
-        }
-        
-        // Write the two collections for top and bottom hits to separate EVIO banks.
-        writeRawCalorimeterHitCollection(topHits, meta, ECAL_TOP_BANK_TAG, builder);
-        writeRawCalorimeterHitCollection(bottomHits, meta, ECAL_BOTTOM_BANK_TAG, builder);
-    }      
-   
+		if (svtDataList != null) {
+			if (svtDataList.size() > 0) {
+				if (svtDataList.get(0) != null) {
+					this.writeSVTData(svtDataList.get(0));
+				}
+			}
+		}
+	}
+
+	private void writeSVTData(List<HPSSVTData> data) {
+		if (data == null) {
+			throw new RuntimeException("The list points to null.");
+		}
+
+		int nsamples = data.size();
+		int evioIntData[] = new int[nsamples * 4];
+
+		int i = 0;
+		for (HPSSVTData sample : data) {
+			int[] sampleData = sample.getData();
+			//System.out.println(Integer.toHexString(sampleData[0]) + ":" + Integer.toHexString(sampleData[1])+ ":" + Integer.toHexString(sampleData[2])+ ":" + Integer.toHexString(sampleData[3]));
+			evioIntData[i] = sampleData[0];
+			evioIntData[i + 1] = sampleData[1];
+			evioIntData[i + 2] = sampleData[2];
+			evioIntData[i + 3] = sampleData[3];
+			i += 4;
+		}
+		EvioBank bank = new EvioBank(SVT_BANK_TAG, DataType.UINT32, SVT_BANK_NUMBER);
+		try {
+			bank.appendIntData(evioIntData);
+		} catch (EvioException e) {
+			throw new RuntimeException(e);
+		}
+		bank.setAllHeaderLengths();
+		try {
+			builder.addChild(builder.getEvent(), bank);
+		} catch (EvioException e) {
+			throw new RuntimeException(e);
+		}
+	}
+
+	private void writeRawCalorimeterHitCollection(List<RawCalorimeterHit> hits, LCMetaData meta, int bankTag, EventBuilder builder) {
+
+		// Get the ID decoder.
+		IDDecoder dec = meta.getIDDecoder();
+
+		// Make a hit map; allow for multiple hits in a crystal.
+		Map<Long, List<RawCalorimeterHit>> hitMap = new HashMap<Long, List<RawCalorimeterHit>>();
+		for (RawCalorimeterHit hit : hits) {
+			if (hitMap.get(hit.getCellID()) == null) {
+				hitMap.put(hit.getCellID(), new ArrayList<RawCalorimeterHit>());
+			}
+			List<RawCalorimeterHit> channelHits = hitMap.get(hit.getCellID());
+			channelHits.add(hit);
+		}
+
+		// Make map of slot number to hit IDs.
+		Map<Integer, List<Long>> slotMap = new HashMap<Integer, List<Long>>();
+		for (Long id : hitMap.keySet()) {
+			dec.setID(id);
+			int iy = dec.getValue("iy"); // treating as slot number    		
+			int slot = Math.abs(iy);
+			if (slotMap.get(slot) == null) {
+				slotMap.put(slot, new ArrayList<Long>());
+			}
+			List<Long> slots = slotMap.get(slot);
+			slots.add(id);
+		}
+
+		// Make a new bank for this crate.
+		EvioBank crateBank = new EvioBank(bankTag, DataType.BANK, ECAL_BANK_NUMBER);
+
+		// Loop over the slots in the map.
+		for (int slot : slotMap.keySet()) {
+
+			// New bank for this slot.
+			EvioBank slotBank = new EvioBank(ECAL_PULSE_INTEGRAL_BANK_TAG, DataType.COMPOSITE, slot);
+
+			// Create composite data for this slot and its channels.
+			CompositeData.Data data = new CompositeData.Data();
+			data.addUchar((byte) slot); // slot #
+			data.addUint(0); // trigger #
+			data.addUlong(0); // timestamp    		
+			List<Long> hitIDs = slotMap.get(slot);
+			int nhits = hitIDs.size();
+			data.addN(nhits); // number of channels
+			for (Long id : hitIDs) {
+				dec.setID(id);
+				int ix = dec.getValue("ix");
+				int channel = ix + ECAL_CHANNEL_OFFSET;
+				data.addUchar((byte) channel); // channel #
+				List<RawCalorimeterHit> channelHits = hitMap.get(id);
+				data.addN(channelHits.size()); // number of pulses
+				for (RawCalorimeterHit hit : channelHits) {
+					data.addUshort((short) hit.getTimeStamp()); // pulse time
+					data.addUint((int) hit.getAmplitude()); // pulse integral
+				}
+			}
+
+			// Add CompositeData to bank.
+			CompositeData cdata = null;
+			try {
+				cdata = new CompositeData(ECAL_PULSE_INTEGRAL_FORMAT, 1, data, ECAL_PULSE_INTEGRAL_BANK_TAG, slot);
+				slotBank.appendCompositeData(cdata);
+			} catch (EvioException e) {
+				throw new RuntimeException(e);
+			}
+
+			// Add slot bank to crate bank.
+			slotBank.setAllHeaderLengths();
+			try {
+				builder.addChild(crateBank, slotBank);
+			} catch (EvioException e) {
+				throw new RuntimeException(e);
+			}
+		}
+		try {
+			crateBank.setAllHeaderLengths();
+			builder.addChild(builder.getEvent(), crateBank);
+		} catch (EvioException e) {
+			throw new RuntimeException(e);
+		}
+	}
+
+	private void writeRawCalorimeterHits(LCMetaData meta, List<RawCalorimeterHit> rawCalorimeterHits, EventBuilder builder) {
+
+		// Make two lists containing the hits from top and bottom sections, which go into separate EVIO data banks.
+		IDDecoder dec = meta.getIDDecoder();
+		List<RawCalorimeterHit> topHits = new ArrayList<RawCalorimeterHit>();
+		List<RawCalorimeterHit> bottomHits = new ArrayList<RawCalorimeterHit>();
+		for (RawCalorimeterHit hit : rawCalorimeterHits) {
+			dec.setID(hit.getCellID());
+			int iy = dec.getValue("iy");
+			// Negative iy should be bottom section.
+			if (iy < 0) {
+				bottomHits.add(hit);
+			} // Positive iy should be top section.
+			else {
+				topHits.add(hit);
+			}
+		}
+
+		// Write the two collections for top and bottom hits to separate EVIO banks.
+		writeRawCalorimeterHitCollection(topHits, meta, ECAL_TOP_BANK_TAG, builder);
+		writeRawCalorimeterHitCollection(bottomHits, meta, ECAL_BOTTOM_BANK_TAG, builder);
+	}
 }
\ No newline at end of file

hps-java/src/main/java/org/lcsim/hps/users/meeg
EvioFileReader.java added at 1.1
diff -N EvioFileReader.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ EvioFileReader.java	1 Apr 2012 21:20:56 -0000	1.1
@@ -0,0 +1,179 @@
+package org.lcsim.hps.users.meeg;
+
+import java.io.InputStream;
+import org.freehep.record.loop.event.RecordSuppliedEvent;
+import static org.lcsim.hps.evio.EventConstants.ECAL_BOTTOM_BANK_TAG;
+import static org.lcsim.hps.evio.EventConstants.ECAL_TOP_BANK_TAG;
+import static org.lcsim.hps.evio.EventConstants.SVT_BANK_TAG;
+
+import org.jlab.coda.jevio.BaseStructure;
+import org.jlab.coda.jevio.CompositeData;
+import org.jlab.coda.jevio.EvioEvent;
+import org.jlab.coda.jevio.EvioReader;
+import org.lcsim.event.EventHeader;
+import org.lcsim.hps.evio.LCSimEventBuilder;
+import org.lcsim.hps.recon.tracking.HPSTrackerSample;
+import org.lcsim.job.JobControlManager;
+import org.lcsim.util.DriverAdapter;
+
+// This is copied and modified from Carl Timmer's EvioProducer class in et 12 org.jlab.coda.et.apps package.
+// TODO Add option to set number of events in put array.
+// TODO Add option for multiple EVIO input files.
+public class EvioFileReader {
+
+	EvioReader reader;
+	String evioFileName;
+	private static final String defaultDetectorName = "HPS-Test-JLAB-v4pt0";
+	private static final String defaultSteeringFile = "/org/lcsim/hps/steering/EtSensorOccupancy.lcsim";
+	String steeringFile = defaultSteeringFile;
+	String detectorName = defaultDetectorName;
+	private JobControlManager jobMgr;
+
+	EvioFileReader() {
+	}
+
+	private static void usage() {
+		System.out.println("\nUsage: java Producer -e <evio file> [-s <steering file>] [-d <detector>]\n\n"
+				+ "       -s     steering file\n"
+				+ "       -d     detector name\n");
+		System.exit(1);
+	}
+
+	public static void main(String[] args) {
+		(new EvioFileReader()).doMain(args); // call wrapper method
+	}
+
+	public void doMain(String[] args) {
+		try {
+			for (int i = 0; i < args.length; i++) {
+				if (args[i].equalsIgnoreCase("-e")) {
+					evioFileName = new String(args[++i]);
+				} else if (args[i].equalsIgnoreCase("-s")) {
+					steeringFile = new String(args[++i]);
+				} else if (args[i].equalsIgnoreCase("-d")) {
+					detectorName = new String(args[++i]);
+				} else {
+					usage();
+					return;
+				}
+			}
+
+			if (evioFileName == null) {
+				usage();
+				return;
+			}
+
+			// Job manager to run LCSim.
+			jobMgr = new JobControlManager();
+			jobMgr.checkInputFiles(false);
+			InputStream is = this.getClass().getResourceAsStream(steeringFile);
+			jobMgr.setup(is);
+
+			// Make a DriverAdapter for wrapping event loop.
+			DriverAdapter driverAdapter = jobMgr.getDriverAdapter();
+
+			// Call wrapper to startOfData() on DriverAdapter.
+			driverAdapter.configure(null);
+
+			LCSimEventBuilder eventBuilder = new LCSimEventBuilder(detectorName);
+			eventBuilder.setDebug(true);
+
+			// Open EVIO reader.
+			reader = new EvioReader(evioFileName);
+
+			// Print number of events.
+			System.out.println("EVIO file opened with " + reader.getEventCount() + " events");
+
+			// Loop until event source is exhausted.
+			//int eventCount = 0;
+			EvioEvent event = reader.parseNextEvent();
+			while (event != null) {
+				// Create LCSim event from EVIO data.
+				EventHeader lcsimEvent = eventBuilder.makeLCSimEvent(event);
+
+				// Supply record to Driver Adapter.
+				driverAdapter.recordSupplied(new RecordSuppliedEvent(new Object(), lcsimEvent));
+
+
+
+//				if (event.getChildren() != null) {
+//					for (BaseStructure crateBank : event.getChildren()) {
+//						int crateTag = crateBank.getHeader().getTag();
+//						if (crateTag == SVT_BANK_TAG) {
+//							int[] intData = crateBank.getIntData();
+//							if (intData.length % 4 != 0) {
+//								throw new RuntimeException("Size of int array not divisible by 4!");
+//							}
+//							int n = intData.length;
+//							for (int i = 0; i < n; i += 4) {
+//
+//								int[] sampleData = new int[4];
+//								sampleData[0] = intData[i];
+//								sampleData[1] = intData[i + 1];
+//								sampleData[2] = intData[i + 2];
+//								sampleData[3] = intData[i + 3];
+//
+//								HPSTrackerSample trackerSample = new HPSTrackerSample();
+//								trackerSample.setData(sampleData);
+//
+//								int fpga = trackerSample.fpgaAddress();
+//								int hybrid = trackerSample.hybrid();
+//								int channel = trackerSample.channel();
+//								int apv = trackerSample.apv();
+//
+//								System.out.println("fpga=" + fpga + "; hybrid=" + hybrid + "; channel=" + channel + "; apv=" + apv);
+//								for (int j = 0; j < 6; j++) {
+//									int val = trackerSample.value(j);
+//									System.out.println("  sample[" + j + "]=" + val);
+//								}
+//							}
+//						} else if (crateTag == ECAL_TOP_BANK_TAG || crateTag == ECAL_BOTTOM_BANK_TAG) {
+//							if (crateBank.getChildCount() > 0) {
+//								for (BaseStructure slotBank : crateBank.getChildren()) {
+//									CompositeData cdata = slotBank.getCompositeData();
+//									System.out.println("ecal.tag=" + Integer.toHexString(slotBank.getHeader().getTag()));
+//									System.out.println("cdata has " + cdata.getItems().size() + " items");
+//									System.out.println("cdata has " + cdata.getTypes().size() + " types");
+//									System.out.println("cdata has " + cdata.getNValues().size() + " N values");
+//									int n = cdata.getNValues().size();
+//									for (int i = 0; i < n; i++) {
+//										System.out.println("cdata.N[" + i + "]=" + cdata.getNValues().get(i));
+//									}
+//									int ni = cdata.getItems().size();
+//									for (int i = 0; i < ni; i++) {
+//										System.out.println("cdata.type[" + i + "]=" + cdata.getTypes().get(i));
+//									}
+//									int slot = cdata.getByte();
+//									int trigger = cdata.getInt();
+//									long timestamp = cdata.getLong();
+//									int nchannels = cdata.getNValue();
+//									System.out.println("slot#=" + slot + "; trigger=" + trigger + "; timestamp=" + timestamp + "; nchannels=" + nchannels);
+//									for (int i = 0; i < nchannels; i++) {
+//										int channelNumber = cdata.getByte();
+//										int npulses = cdata.getNValue();
+//										System.out.println("  channel=" + channelNumber + "; npulses=" + npulses);
+//										for (int j = 0; j < npulses; j++) {
+//											short pulseTime = cdata.getShort();
+//											int pulseIntegral = cdata.getInt();
+//											System.out.println("    pulseTime=" + pulseTime + "; pulseIntegral=" + pulseIntegral);
+//										}
+//									}
+//								}
+//							}
+//						}
+//					}
+//
+//					if (reader.getNumEventsRemaining() == 0) {
+//						break;
+//					}
+//				}
+				event = reader.parseNextEvent();
+			}
+			// Cleanup.
+			driverAdapter.finish(null);
+			reader.close();
+		} catch (Exception e) {
+			throw new RuntimeException(e);
+		}
+	}
+}

hps-java/src/main/java/org/lcsim/hps/recon/ecal
HPSEcalFADCReadoutDriver.java 1.7 -> 1.8
diff -u -r1.7 -r1.8
--- HPSEcalFADCReadoutDriver.java	19 Jan 2012 18:26:28 -0000	1.7
+++ HPSEcalFADCReadoutDriver.java	1 Apr 2012 21:20:56 -0000	1.8
@@ -1,14 +1,19 @@
 package org.lcsim.hps.recon.ecal;
 
-import java.util.Comparator;
+import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 
 import java.util.PriorityQueue;
+import java.util.Set;
 import org.lcsim.event.CalorimeterHit;
+import org.lcsim.event.EventHeader;
 import org.lcsim.event.RawCalorimeterHit;
+import org.lcsim.event.RawTrackerHit;
+import org.lcsim.event.base.BaseRawTrackerHit;
+import org.lcsim.geometry.subdetector.HPSEcal3;
 import org.lcsim.hps.util.ClockSingleton;
 import org.lcsim.hps.util.RingBuffer;
 import org.lcsim.util.lcio.LCIOConstants;
@@ -18,30 +23,47 @@
  * Simulates time evolution of preamp output pulse.
  *
  * @author Sho Uemura <[log in to unmask]>
- * @version $Id: HPSEcalFADCReadoutDriver.java,v 1.7 2012/01/19 18:26:28 meeg Exp $
+ * @version $Id: HPSEcalFADCReadoutDriver.java,v 1.8 2012/04/01 21:20:56 meeg Exp $
  */
 public class HPSEcalFADCReadoutDriver extends HPSEcalReadoutDriver<RawCalorimeterHit> {
-	//buffer for deposited energy
 
-	Map<Long, RingBuffer> eDepMap = null;
+	//buffer for deposited energy
+	private Map<Long, RingBuffer> eDepMap = null;
+	//ADC pipeline for readout
+	private Map<Long, FADCPipeline> pipelineMap = null;
 	//buffer for window sums
-	Map<Long, Double> sumMap = null;
+	private Map<Long, Double> sumMap = null;
 	//buffer for timestamps
-	Map<Long, Integer> timeMap = null;
+	private Map<Long, Integer> timeMap = null;
 	//queue for hits to be output to clusterer
-	PriorityQueue<HPSFADCCalorimeterHit> outputQueue = null;
+	private PriorityQueue<HPSFADCCalorimeterHit> outputQueue = null;
 	//length of ring buffer (in readout cycles)
-	int bufferLength = 100;
+	private int bufferLength = 100;
+	//length of readout pipeline (in readout cycles)
+	private int pipelineLength = 2000;
 	//shaper time constant in ns; negative values generate square pulses of the given width
-	double t0 = 18.0;
+	private 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;
+	private int delay0 = 32;
+	//start of readout window relative to trigger time (in readout cycles)
+	//in FADC documentation, "Programmable Latency" or PL
+	private int readoutLatency = 200;
+	//number of ADC samples to read out
+	//in FADC documentation, "Programmable Trigger Window" or PTW
+	private int readoutWindow = 64;
+	//number of ADC samples to read out before each pulse maximum
+	//in FADC documentation, "number of samples before" or NSB
+	private int numSamplesBefore = 5;
+	//number of ADC samples to read out before each pulse maximum
+	//in FADC documentation, "number of samples before" or NSA
+	private int numSamplesAfter = 10;
+	private HPSEcalConverter converter = null;
 	//output buffer for hits
-	LinkedList<HPSFADCCalorimeterHit> buffer = new LinkedList<HPSFADCCalorimeterHit>();
+	private LinkedList<HPSFADCCalorimeterHit> buffer = new LinkedList<HPSFADCCalorimeterHit>();
 	//number of readout periods for which a given hit stays in the buffer
-	int coincidenceWindow = 2;
-	double pulseIntegral;
+	private int coincidenceWindow = 2;
+	private double pulseIntegral;
+	private String ecalReadoutCollectionName = "EcalReadoutHits";
 
 	public HPSEcalFADCReadoutDriver() {
 		flags = 0;
@@ -50,6 +72,26 @@
 		converter = new HPSEcalConverter(null);
 	}
 
+	public void setEcalReadoutCollectionName(String ecalReadoutCollectionName) {
+		this.ecalReadoutCollectionName = ecalReadoutCollectionName;
+	}
+
+	public void setNumSamplesAfter(int numSamplesAfter) {
+		this.numSamplesAfter = numSamplesAfter;
+	}
+
+	public void setNumSamplesBefore(int numSamplesBefore) {
+		this.numSamplesBefore = numSamplesBefore;
+	}
+
+	public void setReadoutLatency(int readoutLatency) {
+		this.readoutLatency = readoutLatency;
+	}
+
+	public void setReadoutWindow(int readoutWindow) {
+		this.readoutWindow = readoutWindow;
+	}
+
 	public void setCoincidenceWindow(int coincidenceWindow) {
 		this.coincidenceWindow = coincidenceWindow;
 	}
@@ -57,11 +99,11 @@
 	public void setPedestal(double pedestal) {
 		converter.setPedestal(pedestal);
 	}
-	
+
 	public void setScale(double scale) {
 		converter.setScale(scale);
 	}
-	
+
 	public void setT0(double t0) {
 		this.t0 = t0;
 	}
@@ -73,11 +115,28 @@
 	public void setBufferLength(int bufferLength) {
 		this.bufferLength = bufferLength;
 		eDepMap = new HashMap<Long, RingBuffer>();
+		pipelineMap = new HashMap<Long, FADCPipeline>();
+	}
+
+	public void setPipelineLength(int pipelineLength) {
+		this.pipelineLength = pipelineLength;
+		eDepMap = new HashMap<Long, RingBuffer>();
+		pipelineMap = new HashMap<Long, FADCPipeline>();
 	}
 
+	@Override
 	protected void readHits(List<RawCalorimeterHit> hits) {
+
 		for (Long cellID : eDepMap.keySet()) {
 			RingBuffer eDepBuffer = eDepMap.get(cellID);
+
+			FADCPipeline pipeline = pipelineMap.get(cellID);
+			if (pipeline == null) {
+				pipeline = new FADCPipeline(pipelineLength, converter.AtoD(0.0, cellID));
+				pipelineMap.put(cellID, pipeline);
+			}
+			pipeline.writeValue(converter.AtoD(eDepBuffer.currentValue(), cellID));
+
 			Double sum = sumMap.get(cellID);
 			if (sum == null && eDepBuffer.currentValue() > threshold) {
 				timeMap.put(cellID, readoutCounter);
@@ -89,10 +148,11 @@
 					outputQueue.add(new HPSFADCCalorimeterHit(cellID,
 							converter.AtoD((sum + eDepBuffer.currentValue()) / pulseIntegral, cellID),
 							timeMap.get(cellID),
-							readoutCounter-timeMap.get(cellID)+1));
+							readoutCounter - timeMap.get(cellID) + 1));
 					sumMap.remove(cellID);
-				} else
+				} else {
 					sumMap.put(cellID, sum + eDepBuffer.currentValue());
+				}
 			}
 			eDepBuffer.step();
 		}
@@ -100,10 +160,10 @@
 			if (outputQueue.peek().getTimeStamp() < readoutCounter - delay0) {
 				System.out.println("Stale hit in output queue");
 				outputQueue.poll();
-			} else
+			} else {
 				buffer.add(outputQueue.poll());
+			}
 		}
-
 		while (!buffer.isEmpty() && buffer.peek().getTimeStamp() <= readoutCounter - delay0 - coincidenceWindow) {
 			buffer.remove();
 		}
@@ -111,6 +171,52 @@
 		hits.addAll(buffer);
 	}
 
+	@Override
+	public void startOfData() {
+		super.startOfData();
+		if (ecalReadoutCollectionName == null) {
+			throw new RuntimeException("The parameter ecalReadoutCollectionName was not set!");
+		}
+	}
+
+	@Override
+	public void process(EventHeader event) {
+		super.process(event);
+		//System.out.println(this.getClass().getCanonicalName() + " - process");
+		// Get the list of ECal hits.
+		List<CalorimeterHit> hits = event.get(CalorimeterHit.class, ecalCollectionName);
+		if (hits == null) {
+			throw new RuntimeException("Event is missing ECal hits collection!");
+		}
+
+		if (ClockSingleton.triggered()) {
+			event.put(ecalReadoutCollectionName, readWindow(), RawTrackerHit.class, 0, ecalReadoutName);
+		}
+	}
+
+	protected List<RawTrackerHit> readWindow() {
+		System.out.println("Reading ADC data");
+		List<RawTrackerHit> hits = new ArrayList<RawTrackerHit>();
+
+		Set<Long> cells = ((HPSEcal3) ecal).getNeighborMap().keySet();
+		for (Long cellID : cells) {
+			FADCPipeline pipeline = pipelineMap.get(cellID);
+			short[] adcValues = new short[readoutWindow];
+			if (pipeline == null) {
+				for (int i = 0; i < readoutWindow; i++) {
+					adcValues[i] = (short) converter.AtoD(0.0, cellID);
+				}
+			} else {
+				for (int i = 0; i < readoutWindow; i++) {
+					adcValues[i] = (short) pipeline.getValue(readoutLatency - i);
+				}
+			}
+			hits.add(new BaseRawTrackerHit(cellID, 0, adcValues));
+		}
+		return hits;
+	}
+
+	@Override
 	protected void putHits(List<CalorimeterHit> hits) {
 		//fill the readout buffers
 		for (CalorimeterHit hit : hits) {
@@ -118,6 +224,7 @@
 			if (eDepBuffer == null) {
 				eDepBuffer = new RingBuffer(bufferLength);
 				eDepMap.put(hit.getCellID(), eDepBuffer);
+				pipelineMap.put(hit.getCellID(), new FADCPipeline(pipelineLength, converter.AtoD(0.0, hit.getCellID())));
 			}
 			for (int i = 0; i < bufferLength; i++) {
 				eDepBuffer.addToCell(i, hit.getRawEnergy() * pulseAmplitude((i + 1) * readoutPeriod + readoutTime() - (ClockSingleton.getTime() + hit.getTime())));
@@ -125,9 +232,11 @@
 		}
 	}
 
+	@Override
 	protected void initReadout() {
 		//initialize buffers
 		eDepMap = new HashMap<Long, RingBuffer>();
+		pipelineMap = new HashMap<Long, FADCPipeline>();
 		sumMap = new HashMap<Long, Double>();
 		timeMap = new HashMap<Long, Integer>();
 		outputQueue = new PriorityQueue(20, new HPSFADCCalorimeterHit.TimeComparator());
@@ -135,15 +244,65 @@
 	}
 
 	private double pulseAmplitude(double time) {
-		if (time < 0.0)
+		if (time < 0.0) {
 			return 0.0;
+		}
 		if (t0 > 0.0) {
 			return (time / t0) * Math.exp(1.0 - time / t0);
 		} else {
-			if (time < -t0)
+			if (time < -t0) {
 				return 1.0;
-			else
+			} else {
 				return 0.0;
+			}
+		}
+	}
+
+	private class FADCPipeline {
+
+		private int[] array;
+		private int size;
+		private int ptr;
+
+		public FADCPipeline(int size) {
+			this.size = size;
+			array = new int[size]; //initialized to 0
+			ptr = 0;
+		}
+
+		//construct pipeline with a nonzero initial value
+		public FADCPipeline(int size, int init) {
+			this.size = size;
+			array = new int[size];
+			for (int i = 0; i < size; i++) {
+				array[i] = init;
+			}
+			ptr = 0;
+		}
+
+		/**
+		 * Write value to current cell
+		 */
+		public void writeValue(int val) {
+			array[ptr] = val;
+		}
+
+		/**
+		 * Write value to current cell
+		 */
+		public void step() {
+			ptr++;
+			if (ptr == size) {
+				ptr = 0;
+			}
+		}
+
+		//return content of specified cell (pos=0 for current cell)
+		public int getValue(int pos) {
+			if (pos > size) {
+				throw new ArrayIndexOutOfBoundsException();
+			}
+			return array[((ptr - pos) % size + size) % size];
 		}
 	}
-}
+}
\ No newline at end of file

hps-java/src/main/java/org/lcsim/hps/util
RingBuffer.java 1.3 -> 1.4
diff -u -r1.3 -r1.4
--- RingBuffer.java	2 Sep 2011 23:37:17 -0000	1.3
+++ RingBuffer.java	1 Apr 2012 21:20:56 -0000	1.4
@@ -4,50 +4,50 @@
  * Ring buffer for storing ECal (and possibly SVT) samples for trigger and readout
  *
  * @author Sho Uemura <[log in to unmask]>
- * @version $Id: RingBuffer.java,v 1.3 2011/09/02 23:37:17 meeg Exp $
+ * @version $Id: RingBuffer.java,v 1.4 2012/04/01 21:20:56 meeg Exp $
  */
 public class RingBuffer {
 
-    private double[] array;
-    private int size;
-    private int ptr;
-
-    public RingBuffer(int size) {
-        this.size = size;
-        array = new double[size]; //initialized to 0
-        ptr = 0;
-    }
-    
-    /**
-     * 
-     * @return value stored at current cell
-     */
-    public double currentValue() {
-        return array[ptr];
-    }
-    
-    //return content of specified cell (pos=0 for current cell)
-    public double getValue(int pos) {
-        return array[(ptr+pos)%size];
-    }
-     
-    /**
-     * Clear value at current cell and step to the next one
-     */
-    public void step() {
-        array[ptr]=0;
-        ptr++;
-        if (ptr==size) ptr = 0;
-    }
-    
-    /**
-     * Add given value to specified cell
-     * @param pos Target position relative to current cell (pos=0 for current cell)
-     * @param val 
-     */
-    public void addToCell(int pos, double val) {
-        array[(ptr+pos)%size]+=val;
-    }
-    
-    
+	private double[] array;
+	private int size;
+	private int ptr;
+
+	public RingBuffer(int size) {
+		this.size = size;
+		array = new double[size]; //initialized to 0
+		ptr = 0;
+	}
+
+	/**
+	 * 
+	 * @return value stored at current cell
+	 */
+	public double currentValue() {
+		return array[ptr];
+	}
+
+	//return content of specified cell (pos=0 for current cell)
+	public double getValue(int pos) {
+		return array[((ptr + pos) % size + size) % size];
+	}
+
+	/**
+	 * Clear value at current cell and step to the next one
+	 */
+	public void step() {
+		array[ptr] = 0;
+		ptr++;
+		if (ptr == size) {
+			ptr = 0;
+		}
+	}
+
+	/**
+	 * Add given value to specified cell
+	 * @param pos Target position relative to current cell (pos=0 for current cell)
+	 * @param val 
+	 */
+	public void addToCell(int pos, double val) {
+		array[(ptr + pos) % size] += val;
+	}
 }
CVSspam 0.2.12


Use REPLY-ALL to reply to list

To unsubscribe from the LCD-CVS list, click the following link:
https://listserv.slac.stanford.edu/cgi-bin/wa?SUBED1=LCD-CVS&A=1