Author: [log in to unmask] Date: Tue Aug 25 19:40:38 2015 New Revision: 3402 Log: read TI offset in crawler Added: java/trunk/record-util/src/main/java/org/hps/record/triggerbank/TriggerEvioProcessor.java Modified: java/trunk/evio/src/main/java/org/hps/evio/BasicEvioFileReader.java java/trunk/evio/src/main/java/org/hps/evio/LCSimEngRunEventBuilder.java java/trunk/evio/src/main/java/org/hps/evio/LCSimTestRunEventBuilder.java java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/RunProcessor.java java/trunk/record-util/src/main/java/org/hps/record/run/RunSummary.java java/trunk/record-util/src/main/java/org/hps/record/run/TriggerConfig.java java/trunk/record-util/src/main/java/org/hps/record/triggerbank/AbstractIntData.java Modified: java/trunk/evio/src/main/java/org/hps/evio/BasicEvioFileReader.java ============================================================================= --- java/trunk/evio/src/main/java/org/hps/evio/BasicEvioFileReader.java (original) +++ java/trunk/evio/src/main/java/org/hps/evio/BasicEvioFileReader.java Tue Aug 25 19:40:38 2015 @@ -2,7 +2,6 @@ import java.io.File; import java.util.Date; - import org.apache.commons.cli.CommandLine; import org.apache.commons.cli.CommandLineParser; import org.apache.commons.cli.HelpFormatter; @@ -10,8 +9,8 @@ import org.apache.commons.cli.Options; import org.apache.commons.cli.ParseException; import org.apache.commons.cli.PosixParser; -import org.hps.evio.LCSimTestRunEventBuilder.IntBankDefinition; import org.hps.record.evio.EvioEventUtilities; +import org.hps.record.triggerbank.AbstractIntData.IntBankDefinition; import org.hps.record.triggerbank.HeadBankData; import org.hps.record.triggerbank.TIData; import org.jlab.coda.jevio.BaseStructure; @@ -51,8 +50,8 @@ boolean seqRead = cl.hasOption("s"); boolean printTimestamps = cl.hasOption("t"); - IntBankDefinition headBankDefinition = new LCSimTestRunEventBuilder.IntBankDefinition(HeadBankData.class, new int[]{0x2e, 0xe10f}); - IntBankDefinition tiBankDefinition = new LCSimTestRunEventBuilder.IntBankDefinition(TIData.class, new int[]{0x2e, 0xe10a}); + IntBankDefinition headBankDefinition = new IntBankDefinition(HeadBankData.class, new int[]{0x2e, 0xe10f}); + IntBankDefinition tiBankDefinition = new IntBankDefinition(TIData.class, new int[]{0x2e, 0xe10a}); // String evioFileName = args[0]; for (String evioFileName : cl.getArgs()) { 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 Aug 25 19:40:38 2015 @@ -4,13 +4,13 @@ import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; - import org.hps.record.epics.EpicsData; import org.hps.record.epics.EpicsEvioProcessor; import org.hps.record.evio.EvioEventUtilities; import org.hps.record.scalers.ScalerData; import org.hps.record.scalers.ScalersEvioProcessor; import org.hps.record.triggerbank.AbstractIntData; +import org.hps.record.triggerbank.AbstractIntData.IntBankDefinition; import org.hps.record.triggerbank.HeadBankData; import org.hps.record.triggerbank.SSPData; import org.hps.record.triggerbank.TDCData; Modified: java/trunk/evio/src/main/java/org/hps/evio/LCSimTestRunEventBuilder.java ============================================================================= --- java/trunk/evio/src/main/java/org/hps/evio/LCSimTestRunEventBuilder.java (original) +++ java/trunk/evio/src/main/java/org/hps/evio/LCSimTestRunEventBuilder.java Tue Aug 25 19:40:38 2015 @@ -5,11 +5,11 @@ import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; - import org.hps.record.LCSimEventBuilder; import org.hps.record.evio.EvioEventConstants; import org.hps.record.evio.EvioEventUtilities; import org.hps.record.triggerbank.AbstractIntData; +import org.hps.record.triggerbank.AbstractIntData.IntBankDefinition; import org.hps.record.triggerbank.TestRunTriggerData; import org.jlab.coda.jevio.BaseStructure; import org.jlab.coda.jevio.EvioEvent; @@ -172,13 +172,13 @@ BaseStructure bank = def.findBank(evioEvent); if (bank != null) { //returns null if no banks found try { - AbstractIntData data = (AbstractIntData) def.dataClass.getConstructor(int[].class).newInstance(bank.getIntData()); + AbstractIntData data = (AbstractIntData) def.getDataClass().getConstructor(int[].class).newInstance(bank.getIntData()); triggerList.add(data); } catch (Exception ex) { LOGGER.log(Level.SEVERE, ex.getMessage(), ex); } } else { - LOGGER.finest("No trigger bank found of type " + def.dataClass.getSimpleName()); + LOGGER.finest("No trigger bank found of type " + def.getDataClass().getSimpleName()); } } return triggerList; @@ -193,37 +193,4 @@ public void conditionsChanged(ConditionsEvent conditionsEvent) { ecalReader.initialize(); } - - protected static class IntBankDefinition { - - int[] bankTags; - Class<? extends AbstractIntData> dataClass; - - public IntBankDefinition(Class<? extends AbstractIntData> dataClass, int[] bankTags) { - this.bankTags = bankTags; - this.dataClass = dataClass; - } - - public BaseStructure findBank(EvioEvent evioEvent) { - BaseStructure currentBank = evioEvent; - searchLoop: - for (int bankTag : bankTags) { - if (currentBank.getChildCount() > 0) { - for (BaseStructure childBank : currentBank.getChildrenList()) { - if (childBank.getHeader().getTag() == bankTag) { - // Found a bank with the right tag; step inside this bank and continue searching. - currentBank = childBank; - continue searchLoop; - } - } - // Didn't find a bank with the right tag so stop. - return null; - } else { - // Bank has no children so stop. - return null; - } - } - return currentBank; // matched every tag, so this is the bank we want - } - } } Modified: java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/RunProcessor.java ============================================================================= --- java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/RunProcessor.java (original) +++ java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/RunProcessor.java Tue Aug 25 19:40:38 2015 @@ -3,7 +3,6 @@ import java.io.File; import java.util.logging.Level; import java.util.logging.Logger; - import org.hps.record.epics.EpicsRunProcessor; import org.hps.record.evio.EvioFileMetaData; import org.hps.record.evio.EvioFileMetaDataReader; @@ -11,14 +10,16 @@ import org.hps.record.evio.EvioLoop; import org.hps.record.run.RunSummary; import org.hps.record.scalers.ScalersEvioProcessor; +import org.hps.record.triggerbank.TriggerEvioProcessor; import org.lcsim.util.log.DefaultLogFormatter; import org.lcsim.util.log.LogUtil; /** - * Processes EVIO files from a run in order to extract various meta data information including start and end dates. + * Processes EVIO files from a run in order to extract various meta data + * information including start and end dates. * <p> - * This class is a wrapper for activating different sub-tasks, including optionally caching all files from the JLAB MSS - * to the cache disk. + * This class is a wrapper for activating different sub-tasks, including + * optionally caching all files from the JLAB MSS to the cache disk. * <p> * There is also a list of processors which is run on all events from the run. * @@ -90,6 +91,11 @@ private final ScalersEvioProcessor scalersProcessor; /** + * Processor for extracting trigger config. + */ + private final TriggerEvioProcessor triggerProcessor; + + /** * Set to <code>true</code> to use file caching. */ private boolean useFileCache; @@ -118,6 +124,9 @@ scalersProcessor = new ScalersEvioProcessor(); scalersProcessor.setResetEveryEvent(false); evioLoop.addEvioEventProcessor(scalersProcessor); + + triggerProcessor = new TriggerEvioProcessor(); + evioLoop.addEvioEventProcessor(triggerProcessor); // Set whether file caching from MSS is enabled. this.useFileCache(config.useFileCache()); @@ -126,8 +135,9 @@ /** * Cache all files and wait for the operation to complete. * <p> - * Potentially, this operation can take a very long time. This can be managed using the - * {@link JCacheManager#setWaitTime(long)} method to set a timeout. + * Potentially, this operation can take a very long time. This can be + * managed using the {@link JCacheManager#setWaitTime(long)} method to set a + * timeout. */ private void cacheFiles() { @@ -146,10 +156,12 @@ } /** - * Process the run by executing the registered {@link org.hps.record.evio.EvioEventProcessor}s and extracting the - * start and end dates. + * Process the run by executing the registered + * {@link org.hps.record.evio.EvioEventProcessor}s and extracting the start + * and end dates. * <p> - * This method will also execute file caching from MSS, if enabled by the {@link #useFileCache} option. + * This method will also execute file caching from MSS, if enabled by the + * {@link #useFileCache} option. * * @throws Exception if there is an error processing a file */ @@ -184,7 +196,8 @@ } /** - * Set the run end date by getting meta data from the last file and copying it to the run summary. + * Set the run end date by getting meta data from the last file and copying + * it to the run summary. */ private void processLastFile() { final File lastEvioFile = runSummary.getEvioFileList().get(runSummary.getEvioFileList().size() - 1); @@ -202,7 +215,8 @@ } /** - * Set the run start date by getting meta data from the first file and copying it to the run summary. + * Set the run start date by getting meta data from the first file and + * copying it to the run summary. */ private void processFirstFile() { final File firstEvioFile = runSummary.getEvioFileList().get(0); @@ -219,7 +233,8 @@ } /** - * Update the current run summary by copying data to it from the EVIO processors. + * Update the current run summary by copying data to it from the EVIO + * processors. */ private void updateRunSummary() { @@ -231,13 +246,17 @@ // Add EPICS data from the EPICS EVIO processor. runSummary.setEpicsData(this.epicsLog.getEpicsData()); - } - - /** - * Set whether or not to use the file caching, which copies files from the JLAB MSS to the cache disk. + + // Add trigger config from the trigger EVIO processor. + runSummary.setTriggerConfig(this.triggerProcessor.getTriggerConfig()); + } + + /** + * Set whether or not to use the file caching, which copies files from the + * JLAB MSS to the cache disk. * <p> - * Since EVIO data files at JLAB are primarily kept on the MSS, running without this option enabled there will - * likely cause the job to fail. + * Since EVIO data files at JLAB are primarily kept on the MSS, running + * without this option enabled there will likely cause the job to fail. * * @param cacheFiles <code>true</code> to enabled file caching */ Modified: java/trunk/record-util/src/main/java/org/hps/record/run/RunSummary.java ============================================================================= --- java/trunk/record-util/src/main/java/org/hps/record/run/RunSummary.java (original) +++ java/trunk/record-util/src/main/java/org/hps/record/run/RunSummary.java Tue Aug 25 19:40:38 2015 @@ -17,8 +17,8 @@ import org.hps.record.scalers.ScalerData; /** - * This class models the run summary information which is persisted as a row in the <i>run_log</i> table of the run - * database. + * This class models the run summary information which is persisted as a row in + * the <i>run_log</i> table of the run database. * <p> * This information includes: * <ul> @@ -27,12 +27,15 @@ * <li>end time (UTC)</li> * <li>total number of events in the run</li> * <li>number of EVIO files in the run</li> - * <li>whether the END event was found indicating that the DAQ did not crash</li> + * <li>whether the END event was found indicating that the DAQ did not + * crash</li> * <li>whether the run is considered good (all <code>true</code> for now)</li> * </ul> * <p> - * It also references several complex objects including lists of {@link org.hps.record.epics.EpicsData} and - * {@link org.hps.record.scalers.ScalerData} for the run, as well as a list of EVIO files. + * It also references several complex objects including lists of + * {@link org.hps.record.epics.EpicsData} and + * {@link org.hps.record.scalers.ScalerData} for the run, as well as a list of + * EVIO files. * * @author Jeremy McCormick, SLAC */ @@ -45,7 +48,8 @@ static { /** - * Set default time zone for display to East Coast (JLAB) where data was taken. + * Set default time zone for display to East Coast (JLAB) where data was + * taken. */ DATE_DISPLAY.setCalendar(new GregorianCalendar(TimeZone.getTimeZone("America/New_York"))); } @@ -101,6 +105,11 @@ private List<ScalerData> scalerDataList; /** + * The trigger data for the run. + */ + private TriggerConfig triggerConfig; + + /** * Start date of run. */ private Date startDate; @@ -175,8 +184,8 @@ } /** - * Get the event rate (effectively the trigger rate) which is the total events divided by the number of seconds in - * the run. + * Get the event rate (effectively the trigger rate) which is the total + * events divided by the number of seconds in the run. * * @return the event rate */ @@ -215,7 +224,8 @@ } /** - * Return <code>true</code> if the run was okay (no major errors or data corruption occurred). + * Return <code>true</code> if the run was okay (no major errors or data + * corruption occurred). * * @return <code>true</code> if the run was okay */ @@ -233,6 +243,15 @@ } /** + * Get the trigger config of this run. + * + * @return the trigger config of this run + */ + public TriggerConfig getTriggerConfig() { + return triggerConfig; + } + + /** * Get the start date. * * @return the start date @@ -260,7 +279,8 @@ } /** - * Get the number of seconds in the run which is the difference between the start and end times. + * Get the number of seconds in the run which is the difference between the + * start and end times. * * @return the total seconds in the run */ @@ -366,7 +386,8 @@ } /** - * Set whether the run was "okay" meaning the data is usable for physics analysis. + * Set whether the run was "okay" meaning the data is usable for physics + * analysis. * * @param runOkay <code>true</code> if the run is okay */ @@ -381,6 +402,15 @@ */ public void setScalerData(final List<ScalerData> scalerDataList) { this.scalerDataList = scalerDataList; + } + + /** + * Set the trigger config of the run. + * + * @param triggerConfig the trigger config + */ + public void setTriggerConfig(final TriggerConfig triggerConfig) { + this.triggerConfig = triggerConfig; } /** Modified: java/trunk/record-util/src/main/java/org/hps/record/run/TriggerConfig.java ============================================================================= --- java/trunk/record-util/src/main/java/org/hps/record/run/TriggerConfig.java (original) +++ java/trunk/record-util/src/main/java/org/hps/record/run/TriggerConfig.java Tue Aug 25 19:40:38 2015 @@ -4,28 +4,28 @@ * Trigger information available in the run database. * <p> * Currently this only has the TI time offset. - * + * * @author Jeremy McCormick, SLAC */ public final class TriggerConfig { - + /** * The TI time offset. */ private long tiTimeOffset; - + /** * Set the TI time offset. - * + * * @param tiTimeOffset the TI time offset */ - void setTiTimeOffset(long tiTimeOffset) { + public void setTiTimeOffset(long tiTimeOffset) { this.tiTimeOffset = tiTimeOffset; } - + /** * Get the TI time offset. - * + * * @return the TI time offset */ public long getTiTimeOffset() { Modified: java/trunk/record-util/src/main/java/org/hps/record/triggerbank/AbstractIntData.java ============================================================================= --- java/trunk/record-util/src/main/java/org/hps/record/triggerbank/AbstractIntData.java (original) +++ java/trunk/record-util/src/main/java/org/hps/record/triggerbank/AbstractIntData.java Tue Aug 25 19:40:38 2015 @@ -1,16 +1,17 @@ package org.hps.record.triggerbank; import java.util.Arrays; +import org.jlab.coda.jevio.BaseStructure; +import org.jlab.coda.jevio.EvioEvent; import org.lcsim.event.GenericObject; /** - * Class <code>GenericObject</code> representation of an INT32/UINT32 - * bank read from EvIO. The bank header tag identifies the type of - * data, and is stored as the first int in the <code>GenericObject</code>. - * The contents of the bank are the remaining N-1 <code>int</code> - * primitives. Constructors are provided from <code>int[]</code> (for - * reading from EvIO) and from <code>GenericObject</code> (for reading - * from LCIO).<br/> + * Class <code>GenericObject</code> representation of an INT32/UINT32 bank read + * from EvIO. The bank header tag identifies the type of data, and is stored as + * the first int in the <code>GenericObject</code>. The contents of the bank are + * the remaining N-1 <code>int</code> primitives. Constructors are provided from + * <code>int[]</code> (for reading from EvIO) and from + * <code>GenericObject</code> (for reading from LCIO).<br/> * <br/> * Subclasses must implement the two constructors and two abstract methods, plus * whatever methods are needed to access the parsed data. @@ -19,49 +20,59 @@ * @see GenericObject */ public abstract class AbstractIntData implements GenericObject { - /** The data bank. */ + + /** + * The data bank. + */ protected int[] bank; - - /** - * Constructs an <code>AbstractIntData</code> from a raw EvIO integer - * bank. It is expected that the EvIO reader will verify that the - * bank tag is the appropriate type before calling the constructor. + + /** + * Constructs an <code>AbstractIntData</code> from a raw EvIO integer bank. + * It is expected that the EvIO reader will verify that the bank tag is the + * appropriate type before calling the constructor. + * * @param bank - An EvIO bank of <code>int</code> data. */ protected AbstractIntData(int[] bank) { - if(bank == null) { this.bank = new int[0]; } - else { this.bank = Arrays.copyOf(bank, bank.length); } - } - + if (bank == null) { + this.bank = new int[0]; + } else { + this.bank = Arrays.copyOf(bank, bank.length); + } + } + /** * Create an <code>AbstractIntData</code> object from an LCIO * <code>genericObject</code>. Constructor requires that the - * <code>GenericObject</code> tag match the expected EvIO header - * tag type as defined by the implementing class. + * <code>GenericObject</code> tag match the expected EvIO header tag type as + * defined by the implementing class. + * * @param data - The source data bank. * @param expectedTag - The required EvIO bank header tag. */ protected AbstractIntData(GenericObject data, int expectedTag) { - // If the EvIO bank header tag is not the required type, - // produce an exception. - if(getTag(data) != expectedTag) { + // If the EvIO bank header tag is not the required type, + // produce an exception. + if (getTag(data) != expectedTag) { throw new RuntimeException("expected tag " + expectedTag + ", got " + getTag(data)); } - + // Otherwise, store the bank. this.bank = getBank(data); } - + /** * Gets the entire, unparsed integer data bank from the object. + * * @return Returns the data as an <code>int[]</code> array. */ public int[] getBank() { return bank; } - + /** * Return the int bank of an AbstractIntData read from LCIO. + * * @param object * @return */ @@ -73,10 +84,11 @@ } return bank; } - + /** * Return a single value from the integer bank of an * <code>AbstractIntData</code>. + * * @param object - The bank from which to obtain the data. * @param index - The index of the data in the bank. * @return Returns the requested entry from the integer bank. @@ -84,44 +96,46 @@ public static int getBankInt(GenericObject object, int index) { return object.getIntVal(index + 1); } - + /** * Returns the EvIO bank header tag expected for this data. + * * @return Returns the tag as an <code>int</code> primitive. */ public abstract int getTag(); - + /** * Returns the EVIO bank tag for a data object. - * @param data - A <code>GenericObject</code> representing an integer - * data bank. + * + * @param data - A <code>GenericObject</code> representing an integer data + * bank. * @return Returns the EvIO tag identifying the type of bank the object * represents. */ public static int getTag(GenericObject data) { return data.getIntVal(0); } - + /** * Parses the bank so the object can be used in analysis. */ protected abstract void decodeData(); - + @Override public int getNInt() { return bank.length + 1; } - + @Override public int getNFloat() { return 0; } - + @Override public int getNDouble() { return 0; } - + @Override public int getIntVal(int index) { if (index == 0) { @@ -129,19 +143,59 @@ } return bank[index - 1]; } - + @Override public float getFloatVal(int index) { throw new UnsupportedOperationException("No float values in " + this.getClass().getSimpleName()); } - + @Override public double getDoubleVal(int index) { throw new UnsupportedOperationException("No double values in " + this.getClass().getSimpleName()); } - + @Override public boolean isFixedSize() { return true; } -} + + /** + * Utility class used to search an EVIO event for a specified int bank. + */ + public static class IntBankDefinition { + + int[] bankTags; + Class<? extends AbstractIntData> dataClass; + + public IntBankDefinition(Class<? extends AbstractIntData> dataClass, int[] bankTags) { + this.bankTags = bankTags; + this.dataClass = dataClass; + } + + public Class<? extends AbstractIntData> getDataClass() { + return dataClass; + } + + public BaseStructure findBank(EvioEvent evioEvent) { + BaseStructure currentBank = evioEvent; + searchLoop: + for (int bankTag : bankTags) { + if (currentBank.getChildCount() > 0) { + for (BaseStructure childBank : currentBank.getChildrenList()) { + if (childBank.getHeader().getTag() == bankTag) { + // Found a bank with the right tag; step inside this bank and continue searching. + currentBank = childBank; + continue searchLoop; + } + } + // Didn't find a bank with the right tag so stop. + return null; + } else { + // Bank has no children so stop. + return null; + } + } + return currentBank; // matched every tag, so this is the bank we want + } + } +} Added: java/trunk/record-util/src/main/java/org/hps/record/triggerbank/TriggerEvioProcessor.java ============================================================================= --- java/trunk/record-util/src/main/java/org/hps/record/triggerbank/TriggerEvioProcessor.java (added) +++ java/trunk/record-util/src/main/java/org/hps/record/triggerbank/TriggerEvioProcessor.java Tue Aug 25 19:40:38 2015 @@ -0,0 +1,56 @@ +package org.hps.record.triggerbank; + +import org.hps.record.evio.EvioEventProcessor; +import org.hps.record.run.TriggerConfig; +import org.hps.record.triggerbank.AbstractIntData.IntBankDefinition; +import org.jlab.coda.jevio.BaseStructure; +import org.jlab.coda.jevio.EvioEvent; + +/** + * + * @author Sho Uemura <[log in to unmask]> + * @version $Id: $ + */ +public class TriggerEvioProcessor extends EvioEventProcessor { + + private final IntBankDefinition headBankDefinition; + private final IntBankDefinition tiBankDefinition; + private long minOffset = 0; + private long maxOffset = 0; + + public TriggerEvioProcessor() { + headBankDefinition = new IntBankDefinition(HeadBankData.class, new int[]{0x2e, 0xe10f}); + tiBankDefinition = new IntBankDefinition(TIData.class, new int[]{0x2e, 0xe10a}); + } + + @Override + public void process(final EvioEvent evioEvent) { + BaseStructure headBank = headBankDefinition.findBank(evioEvent); + BaseStructure tiBank = tiBankDefinition.findBank(evioEvent); + if (headBank != null && tiBank != null) { + int[] headData = headBank.getIntData(); + int thisTimestamp = headData[3]; + TIData tiData = new TIData(tiBank.getIntData()); + if (thisTimestamp != 0) { + long offset = thisTimestamp * 1000000000L - tiData.getTime(); + if (minOffset == 0 || minOffset > offset) { + minOffset = offset; + } + if (maxOffset == 0 || maxOffset < offset) { + maxOffset = offset; + } + } + } + } + + public TriggerConfig getTriggerConfig() { + TriggerConfig triggerConfig = new TriggerConfig(); + long offsetRange = maxOffset - minOffset; + if (offsetRange > 0.99 * 1e9 && offsetRange < 1.01 * 1e9) { + triggerConfig.setTiTimeOffset(minOffset); + } else { + triggerConfig.setTiTimeOffset(0); + } + return triggerConfig; + } +}