Author: [log in to unmask]
Date: Tue Mar 24 14:35:16 2015
New Revision: 2523
Log:
Add parsing of scalar data from EVIO and persistency to LCIO. HPSJAVA-470
Added:
java/trunk/evio/src/test/java/org/hps/evio/ScalarsTest.java
java/trunk/record-util/src/main/java/org/hps/record/scalars/
java/trunk/record-util/src/main/java/org/hps/record/scalars/ScalarData.java
java/trunk/record-util/src/main/java/org/hps/record/scalars/ScalarsEvioProcessor.java
java/trunk/record-util/src/main/java/org/hps/record/scalars/ScalarsGenericObject.java
Modified:
java/trunk/evio/src/main/java/org/hps/evio/LCSimEngRunEventBuilder.java
Modified: java/trunk/evio/src/main/java/org/hps/evio/LCSimEngRunEventBuilder.java
=============================================================================
--- java/trunk/evio/src/main/java/org/hps/evio/LCSimEngRunEventBuilder.java (original)
+++ java/trunk/evio/src/main/java/org/hps/evio/LCSimEngRunEventBuilder.java Tue Mar 24 14:35:16 2015
@@ -11,33 +11,41 @@
import org.hps.record.epics.EpicsEvioProcessor;
import org.hps.record.epics.EpicsScalarData;
import org.hps.record.evio.EvioEventUtilities;
+import org.hps.record.scalars.ScalarData;
+import org.hps.record.scalars.ScalarsEvioProcessor;
import org.jlab.coda.jevio.EvioEvent;
import org.lcsim.event.EventHeader;
-
/**
- * Build LCSim events from EVIO data.
+ * This is the {@link org.hps.record.LCSimEventBuilder} implementation for the Engineering Run and the Commissioning Run.
+ * <p>
+ * It has several modifications from the Test Run builder including different values for certain bank tags.
+ * <p>
+ * Additionally, this builder will write DAQ config information, EPICS control data, and scalar bank data into the output LCSim events if these banks are present in the EVIO data.
*
* @author Sho Uemura <[log in to unmask]>
* @author Jeremy McCormick <[log in to unmask]>
*/
public class LCSimEngRunEventBuilder extends LCSimTestRunEventBuilder {
-
+
TriggerConfigEvioReader triggerConfigReader = null;
-
+
EpicsEvioProcessor epicsProcessor = new EpicsEvioProcessor();
EpicsScalarData epicsData;
-
- public LCSimEngRunEventBuilder() {
+
+ ScalarsEvioProcessor scalarProcessor = new ScalarsEvioProcessor();
+ ScalarData scalarData;
+
+ public LCSimEngRunEventBuilder() {
ecalReader.setTopBankTag(0x25);
- ecalReader.setBotBankTag(0x27);
- svtReader = new SvtEvioReader();
- sspCrateBankTag = 0x2E; //A.C. modification after Sergey's confirmation
+ ecalReader.setBotBankTag(0x27);
+ svtReader = new SvtEvioReader();
+ sspCrateBankTag = 0x2E; // A.C. modification after Sergey's confirmation
sspBankTag = 0xe10c;
intBanks = new ArrayList<IntBankDefinition>();
- intBanks.add(new IntBankDefinition(SSPData.class, new int[]{sspCrateBankTag, sspBankTag}));
- intBanks.add(new IntBankDefinition(TIData.class, new int[]{sspCrateBankTag, 0xe10a}));
- // ecalReader = new ECalEvioReader(0x25, 0x27);
+ intBanks.add(new IntBankDefinition(SSPData.class, new int[] { sspCrateBankTag, sspBankTag }));
+ intBanks.add(new IntBankDefinition(TIData.class, new int[] { sspCrateBankTag, 0xe10a }));
+ // ecalReader = new ECalEvioReader(0x25, 0x27);
triggerConfigReader = new TriggerConfigEvioReader();
}
@@ -51,18 +59,36 @@
}
return 0;
}
-
+
@Override
public void readEvioEvent(EvioEvent evioEvent) {
super.readEvioEvent(evioEvent);
+
+ // Create EPICS data if this is an EPICS control event.
if (EvioEventUtilities.isEpicsEvent(evioEvent)) {
createEpicsScalarData(evioEvent);
}
}
-
+
+ /**
+ * Create and cache an {@link org.hps.record.epics.EpicsScalarData} object.
+ * @param evioEvent The EVIO event data.
+ */
void createEpicsScalarData(EvioEvent evioEvent) {
epicsProcessor.process(evioEvent);
epicsData = epicsProcessor.getEpicsScalarData();
+ }
+
+ /**
+ * Write EVIO scalar data into the LCSim event, if it exists.
+ * @param evioEvent The EVIO event data.
+ * @param lcsimEvent The output LCSim event.
+ */
+ void writeScalarData(EvioEvent evioEvent, EventHeader lcsimEvent) {
+ scalarProcessor.process(evioEvent);
+ if (scalarProcessor.getScalarData() != null) {
+ scalarProcessor.getScalarData().write(lcsimEvent);
+ }
}
@Override
@@ -73,10 +99,10 @@
// Create a new LCSimEvent.
EventHeader lcsimEvent = getEventData(evioEvent);
-
- // Put DAQ Configuration info into lcsimEvent
- triggerConfigReader.getDAQConfig(evioEvent,lcsimEvent);
-
+
+ // Put DAQ Configuration info into lcsimEvent.
+ triggerConfigReader.getDAQConfig(evioEvent, lcsimEvent);
+
// Make RawCalorimeterHit collection, combining top and bottom section
// of ECal into one list.
try {
@@ -84,21 +110,24 @@
} catch (Exception e) {
Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, "Error making ECal hits", e);
}
-
- // Write EPICS bank into the subsequent physics event.
+
+ // FIXME: This is commented out for now while SVT is not integrated.
+ // Make SVT RawTrackerHits.
+ // try {
+ // svtReader.makeHits(evioEvent, lcsimEvent);
+ // } catch (Exception e) {
+ // Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, "Error making SVT hits", e);
+ // }
+
+ // Write the current EPICS data into this event.
if (epicsData != null) {
epicsData.write(lcsimEvent);
epicsData = null;
}
- // Make SVT RawTrackerHits
- // try {
- // svtReader.makeHits(evioEvent, lcsimEvent);
- // } catch (Exception e) {
- // Logger.getLogger(this.getClass().getName()).log(Level.SEVERE,
- // "Error making SVT hits", e);
- // }
-
+ // Write scalars into the event, if they exist in this EVIO data.
+ writeScalarData(evioEvent, lcsimEvent);
+
return lcsimEvent;
- }
+ }
}
Added: java/trunk/evio/src/test/java/org/hps/evio/ScalarsTest.java
=============================================================================
--- java/trunk/evio/src/test/java/org/hps/evio/ScalarsTest.java (added)
+++ java/trunk/evio/src/test/java/org/hps/evio/ScalarsTest.java Tue Mar 24 14:35:16 2015
@@ -0,0 +1,110 @@
+package org.hps.evio;
+
+import java.io.File;
+import java.net.URL;
+
+import junit.framework.TestCase;
+
+import org.hps.conditions.database.DatabaseConditionsManager;
+import org.hps.record.LCSimEventBuilder;
+import org.hps.record.composite.CompositeLoop;
+import org.hps.record.composite.CompositeLoopConfiguration;
+import org.hps.record.enums.DataSourceType;
+import org.hps.record.enums.ProcessingStage;
+import org.hps.record.evio.EvioDetectorConditionsProcessor;
+import org.hps.record.scalars.ScalarData;
+import org.hps.record.scalars.ScalarsEvioProcessor;
+import org.lcsim.event.EventHeader;
+import org.lcsim.util.Driver;
+import org.lcsim.util.cache.FileCache;
+import org.lcsim.util.loop.LCIODriver;
+import org.lcsim.util.loop.LCSimLoop;
+import org.lcsim.util.test.TestUtil.TestOutputFile;
+
+/**
+ * Test of reading scalar data from EVIO files.
+ * <p>
+ * <a href="https://jira.slac.stanford.edu/browse/HPSJAVA-470">HPSJAVA-470</a>
+ *
+ * @author Jeremy McCormick <[log in to unmask]>
+ */
+public class ScalarsTest extends TestCase {
+
+ static final String TEST_FILE_URL = "http://www.lcsim.org/test/hps-java/ScalarsTest/hpsecal_004469_1000_events.evio.0";
+
+ public void test() throws Exception {
+
+ // Cache the input EVIO file (1000 events).
+ FileCache cache = new FileCache();
+ File inputFile = cache.getCachedFile(new URL(TEST_FILE_URL));
+
+ // Setup conditions and event building.
+ DatabaseConditionsManager manager = new DatabaseConditionsManager();
+ LCSimEventBuilder builder = new LCSimEngRunEventBuilder();
+ manager.addConditionsListener(builder);
+
+ // Configure and run the job to write out the LCIO from EVIO.
+ CompositeLoopConfiguration configuration = new CompositeLoopConfiguration();
+ configuration.add(new ScalarsEvioProcessor());
+ configuration.setDataSourceType(DataSourceType.EVIO_FILE);
+ configuration.add(new EvioDetectorConditionsProcessor("HPS-ECalCommissioning-v2"));
+ configuration.setLCSimEventBuilder(builder);
+ configuration.setFilePath(inputFile.getPath());
+ configuration.setProcessingStage(ProcessingStage.LCIO);
+ configuration.setStopOnEndRun(false);
+ configuration.setStopOnErrors(true);
+ TestOutputFile outputFile = new TestOutputFile("ScalarsTest.slcio");
+ configuration.add(new LCIODriver(outputFile.getPath()));
+ CompositeLoop loop = new CompositeLoop();
+ loop.setConfiguration(configuration);
+ loop.loop(1000);
+
+ // Read back the LCIO data and perform calculations referenced in JIRA item.
+ LCSimLoop readLoop = new LCSimLoop();
+ readLoop.setLCIORecordSource(outputFile);
+ readLoop.add(new Driver() {
+ public void process(EventHeader event) {
+ ScalarData data = ScalarData.read(event);
+ if (data != null) {
+ System.out.println("Driver got ScalarData in LCIO event ...");
+ System.out.println(data.toString());
+
+ // [03] - gated faraday cup with "TDC" threshold
+ int word03 = data.getValue(3);
+
+ // [19] - gated faraday cup with "TRG" threshold
+ int word19 = data.getValue(19);
+
+ // [35] - ungated faraday cup with "TDC" threshold
+ int word35 = data.getValue(35);
+
+ // [51] - ungated faraday cup with "TRG" threshold
+ int word51 = data.getValue(51);
+
+ // [67] - gated clock
+ int word67 = data.getValue(67);
+
+ // [68] - ungated clock
+ int word68 = data.getValue(68);
+
+ double fcupTdc = (double) word03 / (double) word35;
+ double fcupTrg = (double) word19 / (double) word51;
+ double clock = (double) word67 / (double) word68;
+
+ System.out.println("word03 = " + word03);
+ System.out.println("word19 = " + word19);
+ System.out.println("word35 = " + word35);
+ System.out.println("word51 = " + word51);
+ System.out.println("word67 = " + word67);
+ System.out.println("word68 = " + word68);
+
+ System.out.println("fcupTdc = " + fcupTdc);
+ System.out.println("fcupTrg = " + fcupTrg);
+ System.out.println("clock = " + clock);
+ }
+ }
+ });
+ readLoop.loop(-1);
+ }
+
+}
Added: java/trunk/record-util/src/main/java/org/hps/record/scalars/ScalarData.java
=============================================================================
--- java/trunk/record-util/src/main/java/org/hps/record/scalars/ScalarData.java (added)
+++ java/trunk/record-util/src/main/java/org/hps/record/scalars/ScalarData.java Tue Mar 24 14:35:16 2015
@@ -0,0 +1,118 @@
+package org.hps.record.scalars;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.lcsim.event.EventHeader;
+import org.lcsim.event.GenericObject;
+
+/**
+ * This class encapsulates EVIO scalar data which is simply an array
+ * of integer values. The exact meaning of each of these integer
+ * words is defined externally to this class.
+ *
+ * @author Jeremy McCormick <[log in to unmask]>
+ */
+public class ScalarData {
+
+ // The default name for reading and writing the LCIO event collection.
+ static String DEFAULT_SCALAR_DATA_COLLECTION_NAME = "ScalarData";
+
+ // The scalar data values.
+ int[] data;
+
+ /**
+ * This is the no argument constructor which is for package internal use.
+ */
+ ScalarData() {
+ }
+
+ /**
+ * Create from provided scalar data values.
+ * @param data The scalar data.
+ */
+ public ScalarData(int[] data) {
+ this.data = new int[data.length];
+ System.arraycopy(data, 0, this.data, 0, data.length);
+ }
+
+ /**
+ * Get the number of scalars.
+ * @return The number of scalars.
+ */
+ public int size() {
+ return data.length;
+ }
+
+ /**
+ * Get the scalar data value at the index.
+ * @param index The scalar data index.
+ * @return The scalar data value.
+ */
+ public Integer getValue(int index) {
+ return data[index];
+ }
+
+ /**
+ * Convert this object to an lcsim {@link org.lcsim.event.GenericObject} for
+ * persistency to LCIO.
+ * @return The LCIO GenericObject.
+ */
+ GenericObject toGenericObject() {
+ ScalarsGenericObject object = new ScalarsGenericObject();
+ object.values = data;
+ return object;
+ }
+
+ /**
+ * Load data into this object from an {@link org.lcsim.event.GenericObject}
+ * read from an LCIO event.
+ * @param object The GenericObject with the scalar data.
+ */
+ void fromGenericObject(GenericObject object) {
+ this.data = new int[object.getNInt()];
+ for (int index = 0; index < object.getNInt(); index++) {
+ this.data[index] = object.getIntVal(index);
+ }
+ }
+
+ /**
+ * Write this object out to an LCIO event.
+ * @param event The output LCIO event.
+ */
+ public void write(EventHeader event) {
+ List<GenericObject> collection = new ArrayList<GenericObject>();
+ collection.add(toGenericObject());
+ event.put(DEFAULT_SCALAR_DATA_COLLECTION_NAME, collection, GenericObject.class, 0);
+ }
+
+ /**
+ * Create a new object from the data in an LCIO event, using the default collection name.
+ * @param event The LCIO event data.
+ * @return The created ScalarData object or null if does not exist in event.
+ */
+ public static ScalarData read(EventHeader event) {
+ ScalarData data = null;
+ if (event.hasCollection(GenericObject.class, DEFAULT_SCALAR_DATA_COLLECTION_NAME)) {
+ List<GenericObject> objects = event.get(GenericObject.class, DEFAULT_SCALAR_DATA_COLLECTION_NAME);
+ data = new ScalarData();
+ data.fromGenericObject(objects.get(0));
+ }
+ return data;
+ }
+
+ /**
+ * Convert this object to a readable string, which is basically just a list of int values
+ * enclosed in braces and separated by commas.
+ */
+ public String toString() {
+ StringBuffer sb = new StringBuffer();
+ sb.append("[");
+ for (int value : data) {
+ sb.append(value + ", ");
+ }
+ sb.setLength(sb.length() - 2);
+ sb.append("]");
+ return sb.toString();
+ }
+}
Added: java/trunk/record-util/src/main/java/org/hps/record/scalars/ScalarsEvioProcessor.java
=============================================================================
--- java/trunk/record-util/src/main/java/org/hps/record/scalars/ScalarsEvioProcessor.java (added)
+++ java/trunk/record-util/src/main/java/org/hps/record/scalars/ScalarsEvioProcessor.java Tue Mar 24 14:35:16 2015
@@ -0,0 +1,55 @@
+package org.hps.record.scalars;
+
+import org.hps.record.evio.EvioEventProcessor;
+import org.jlab.coda.jevio.BaseStructure;
+import org.jlab.coda.jevio.EvioEvent;
+
+/**
+ * This is an EVIO event processor for creating a {@link ScalarData} object from scalar bank data.
+ *
+ * @author Jeremy McCormick <[log in to unmask]>
+ */
+public class ScalarsEvioProcessor extends EvioEventProcessor {
+
+ // Tag of the crate bank, which is a child of the top bank.
+ static final int SCALARS_CRATE_TAG = 39;
+
+ // Tag of the scalars integer bank, which is a child of the crate bank.
+ static final int SCALARS_BANK_TAG = 57621;
+
+ // Currently cached ScalarData object which was created by the process method.
+ ScalarData data;
+
+ /**
+ * This method will create a <code>ScalarData</code> object and cache it.
+ * The current object is first reset to null every time this is called.
+ *
+ * @param evio The EVIO event data.
+ */
+ public void process(EvioEvent evio) {
+ data = null;
+ for (BaseStructure bank : evio.getChildrenList()) {
+ // Does the crate tag match?
+ if (bank.getHeader().getTag() == SCALARS_CRATE_TAG) {
+ if (bank.getChildrenList() != null) {
+ for (BaseStructure subBank : bank.getChildrenList()) {
+ // Does the bank tag match?
+ if (subBank.getHeader().getTag() == SCALARS_BANK_TAG) {
+ // Scalar data exists in event so create object and stop processing.
+ data = new ScalarData(subBank.getIntData());
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Get the current scalar data or null if there was none in the last event processed.
+ * @return The current scalar data or null if none exists.
+ */
+ public ScalarData getScalarData() {
+ return data;
+ }
+}
Added: java/trunk/record-util/src/main/java/org/hps/record/scalars/ScalarsGenericObject.java
=============================================================================
--- java/trunk/record-util/src/main/java/org/hps/record/scalars/ScalarsGenericObject.java (added)
+++ java/trunk/record-util/src/main/java/org/hps/record/scalars/ScalarsGenericObject.java Tue Mar 24 14:35:16 2015
@@ -0,0 +1,51 @@
+package org.hps.record.scalars;
+
+import org.lcsim.event.GenericObject;
+
+/**
+ * This is the LCIO {@link org.lcsim.event.GenericObject} binding
+ * for EVIO scalar data. This should not be used directly. Rather
+ * the {@link ScalarData} class should be used for loading data
+ * from LCIO events.
+ *
+ * @author Jeremy McCormick <[log in to unmask]>
+ */
+final class ScalarsGenericObject implements GenericObject {
+
+ int[] values;
+
+ @Override
+ public int getNInt() {
+ return values.length;
+ }
+
+ @Override
+ public int getNFloat() {
+ return 0;
+ }
+
+ @Override
+ public int getNDouble() {
+ return 0;
+ }
+
+ @Override
+ public int getIntVal(int index) {
+ return values[index];
+ }
+
+ @Override
+ public float getFloatVal(int index) {
+ return 0;
+ }
+
+ @Override
+ public double getDoubleVal(int index) {
+ return 0;
+ }
+
+ @Override
+ public boolean isFixedSize() {
+ return false;
+ }
+}
|