Commit in hps-java/src/main/java/org/lcsim/hps on MAIN | |||
evio/LCSimTestRunEventBuilder.java | +306 | added 1.1 | |
/TestRunReconToEvio.java | +213 | -213 | 1.2 -> 1.3 |
users/meeg/EvioFileReader.java | +179 | added 1.1 | |
recon/ecal/HPSEcalFADCReadoutDriver.java | +183 | -24 | 1.7 -> 1.8 |
util/RingBuffer.java | +43 | -43 | 1.3 -> 1.4 |
+924 | -280 |
continue work on ECal data conversion to/from EVIO; start work on FADC readout modes (doesn't work yet)
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
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
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); + } + } +}
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
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; + }
}
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