Author: [log in to unmask] Date: Tue Nov 10 15:21:05 2015 New Revision: 3947 Log: Updates and improvements to EVIO metadata reader; changes and cleanup to record-util module. Added: java/branches/jeremy-dev/record-util/src/main/java/org/hps/record/evio/EventTagMask.java java/branches/jeremy-dev/record-util/src/main/java/org/hps/record/triggerbank/TriggerType.java - copied, changed from r3945, java/branches/jeremy-dev/record-util/src/main/java/org/hps/record/evio/EventTagBitMask.java Removed: java/branches/jeremy-dev/crawler/src/main/java/org/hps/crawler/RunSummaryMap.java java/branches/jeremy-dev/record-util/src/main/java/org/hps/record/evio/EventCountProcessor.java java/branches/jeremy-dev/record-util/src/main/java/org/hps/record/evio/EventTagBitMask.java Modified: java/branches/jeremy-dev/crawler/src/main/java/org/hps/crawler/AidaMetadataReader.java java/branches/jeremy-dev/crawler/src/main/java/org/hps/crawler/CrawlerFileUtilities.java java/branches/jeremy-dev/crawler/src/main/java/org/hps/crawler/DatacatCrawler.java java/branches/jeremy-dev/crawler/src/main/java/org/hps/crawler/DatacatUtilities.java java/branches/jeremy-dev/crawler/src/main/java/org/hps/crawler/EvioMetadataReader.java java/branches/jeremy-dev/crawler/src/main/java/org/hps/crawler/FileMetadataReader.java java/branches/jeremy-dev/crawler/src/main/java/org/hps/crawler/FileSet.java java/branches/jeremy-dev/crawler/src/main/java/org/hps/crawler/LcioMetadataReader.java java/branches/jeremy-dev/record-util/src/main/java/org/hps/record/epics/EpicsData.java java/branches/jeremy-dev/record-util/src/main/java/org/hps/record/epics/EpicsEvioProcessor.java java/branches/jeremy-dev/record-util/src/main/java/org/hps/record/evio/EventTagConstant.java java/branches/jeremy-dev/record-util/src/main/java/org/hps/record/evio/EvioBankTag.java Modified: java/branches/jeremy-dev/crawler/src/main/java/org/hps/crawler/AidaMetadataReader.java ============================================================================= --- java/branches/jeremy-dev/crawler/src/main/java/org/hps/crawler/AidaMetadataReader.java (original) +++ java/branches/jeremy-dev/crawler/src/main/java/org/hps/crawler/AidaMetadataReader.java Tue Nov 10 15:21:05 2015 @@ -12,7 +12,7 @@ * * @author Jeremy McCormick, SLAC */ -public class AidaMetadataReader implements FileMetadataReader { +final class AidaMetadataReader implements FileMetadataReader { /** * Get the metadata for a ROOT DQM file. Modified: java/branches/jeremy-dev/crawler/src/main/java/org/hps/crawler/CrawlerFileUtilities.java ============================================================================= --- java/branches/jeremy-dev/crawler/src/main/java/org/hps/crawler/CrawlerFileUtilities.java (original) +++ java/branches/jeremy-dev/crawler/src/main/java/org/hps/crawler/CrawlerFileUtilities.java Tue Nov 10 15:21:05 2015 @@ -7,7 +7,7 @@ * * @author Jeremy McCormick, SLAC */ -public class CrawlerFileUtilities { +final class CrawlerFileUtilities { /** * Get run number from file name assuming it looks like "hps_001234". Modified: java/branches/jeremy-dev/crawler/src/main/java/org/hps/crawler/DatacatCrawler.java ============================================================================= --- java/branches/jeremy-dev/crawler/src/main/java/org/hps/crawler/DatacatCrawler.java (original) +++ java/branches/jeremy-dev/crawler/src/main/java/org/hps/crawler/DatacatCrawler.java Tue Nov 10 15:21:05 2015 @@ -35,7 +35,7 @@ * * @author Jeremy McCormick, SLAC */ -public class DatacatCrawler { +public final class DatacatCrawler { /** * Visitor which creates a {@link FileSet} from walking a directory tree. @@ -175,7 +175,7 @@ * @param folder the folder in the datacat * @throws RuntimeException if the given path does not exist or it is not a folder */ - void checkFolder(final String folder) { + private void checkFolder(final String folder) { final DatacatClient datacatClient = new DatacatClientFactory().createClient(); if (!datacatClient.exists(folder)) { throw new RuntimeException("The folder " + folder + " does not exist in the data catalog."); @@ -191,7 +191,7 @@ * @param args the command line arguments * @return this object (for method chaining) */ - public DatacatCrawler parse(final String[] args) { + private DatacatCrawler parse(final String[] args) { config = new CrawlerConfig(); LOGGER.config("parsing command line options"); @@ -323,6 +323,11 @@ } LOGGER.config("dataset site " + site); config.setDatasetSite(site); + + // Dry run. + if (cl.hasOption("D")) { + config.setDryRun(true); + } } catch (final ParseException e) { throw new RuntimeException("Error parsing options.", e); @@ -353,7 +358,7 @@ /** * Run the crawler job. */ - void run() { + private void run() { // Create the file visitor for crawling the root directory with the given date filter. final DatacatFileVisitor visitor = new DatacatFileVisitor(); @@ -411,7 +416,7 @@ throw new RuntimeException("HTTP error code " + response + " received from server."); } } else { - LOGGER.info("update on " + file.getPath() + " skipped from dry run"); + LOGGER.info("skipped updated on " + file.getPath() + " from dry run"); } } LOGGER.info("successfully added " + formatFiles.size() + " " + fileFormat + " files"); Modified: java/branches/jeremy-dev/crawler/src/main/java/org/hps/crawler/DatacatUtilities.java ============================================================================= --- java/branches/jeremy-dev/crawler/src/main/java/org/hps/crawler/DatacatUtilities.java (original) +++ java/branches/jeremy-dev/crawler/src/main/java/org/hps/crawler/DatacatUtilities.java Tue Nov 10 15:21:05 2015 @@ -21,7 +21,7 @@ /** * Static map of strings to dataset file formats. */ - static Map<String, DatasetFileFormat> formatMap = new HashMap<String, DatasetFileFormat>(); + private static Map<String, DatasetFileFormat> formatMap = new HashMap<String, DatasetFileFormat>(); static { for (final DatasetFileFormat format : DatasetFileFormat.values()) { formatMap.put(format.extension(), format); Modified: java/branches/jeremy-dev/crawler/src/main/java/org/hps/crawler/EvioMetadataReader.java ============================================================================= --- java/branches/jeremy-dev/crawler/src/main/java/org/hps/crawler/EvioMetadataReader.java (original) +++ java/branches/jeremy-dev/crawler/src/main/java/org/hps/crawler/EvioMetadataReader.java Tue Nov 10 15:21:05 2015 @@ -2,38 +2,49 @@ import java.io.File; import java.io.IOException; +import java.math.RoundingMode; +import java.text.DecimalFormat; +import java.util.ArrayList; import java.util.HashMap; import java.util.LinkedHashMap; +import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; -import org.hps.record.evio.EventTagBitMask; +import org.hps.record.epics.EpicsData; +import org.hps.record.epics.EpicsEvioProcessor; import org.hps.record.evio.EventTagConstant; +import org.hps.record.evio.EventTagMask; import org.hps.record.evio.EvioEventUtilities; import org.hps.record.evio.EvioFileUtilities; +import org.hps.record.scalers.ScalerData; import org.hps.record.scalers.ScalersEvioProcessor; +import org.hps.record.triggerbank.TriggerType; import org.jlab.coda.jevio.EvioEvent; import org.jlab.coda.jevio.EvioException; import org.jlab.coda.jevio.EvioReader; /** - * Reads metadata from EVIO files. - * + * Reads metadata from EVIO files, including the event count, run min and run max expected by the datacat, + * as well as many custom field values applicable to HPS EVIO raw data. + * <p> + * The size of the data file is set externally to this reader using the datacat client. + * * @author Jeremy McCormick, SLAC */ -public class EvioMetadataReader implements FileMetadataReader { +final class EvioMetadataReader implements FileMetadataReader { /** * Initialize the logger. */ private static Logger LOGGER = Logger.getLogger(EvioMetadataReader.class.getPackage().getName()); - + /** * Get the EVIO file metadata. - * + * * @param file the EVIO file * @return the metadata map of key and value pairs */ @@ -42,26 +53,37 @@ Integer firstTimestamp = null; Integer lastTimestamp = null; + Integer firstPhysicsTimestamp = null; + Integer lastPhysicsTimestamp = null; + int totalEvents = 0; int badEvents = 0; - int eventCount = 0; int epicsEvents = 0; - int scalerBanks = 0; - boolean prestart = false; - boolean end = false; - boolean go = false; + int scalerEvents = 0; + int physicsEvents = 0; + int syncEvents = 0; + int pauseEvents = 0; + int prestartEvents = 0; + int endEvents = 0; + int goEvents = 0; boolean blinded = true; Integer run = null; Integer lastPhysicsEvent = null; Integer firstPhysicsEvent = null; + double triggerRate = 0; + List<ScalerData> scalerData = new ArrayList<ScalerData>(); + List<EpicsData> epicsData = new ArrayList<EpicsData>(); + + // Create map for counting event masks. + Map<TriggerType, Integer> eventCounts = new HashMap<TriggerType, Integer>(); + for (TriggerType mask : TriggerType.values()) { + eventCounts.put(mask, 0); + } - // Create map for counting event masks. - Map<EventTagBitMask, Integer> triggerCounts = new HashMap<EventTagBitMask, Integer>(); - for (EventTagBitMask mask : EventTagBitMask.values()) { - triggerCounts.put(mask, 0); - } - // Scaler processor to check for scaler bank. ScalersEvioProcessor scalersProcessor = new ScalersEvioProcessor(); + + // EPICS data processor. + EpicsEvioProcessor epicsProcessor = new EpicsEvioProcessor(); // Get the file number from the name. final int fileNumber = EvioFileUtilities.getSequenceFromName(file); @@ -72,10 +94,9 @@ } EvioReader evioReader = null; - try { - - evioReader = EvioFileUtilities.open(file, true); - + try { + // Open file in sequential mode. + evioReader = EvioFileUtilities.open(file, true); EvioEvent evioEvent = null; // Event read loop. @@ -84,122 +105,173 @@ // Read in an EVIO event, trapping exceptions in case a parse error occurs. boolean badEvent = false; try { - evioEvent = evioReader.parseNextEvent(); + // Parse next event. + evioEvent = evioReader.parseNextEvent(); } catch (IOException | EvioException e) { + // Trap event parsing errors from bad EVIO data. badEvent = true; + badEvents++; LOGGER.warning("bad EVIO event " + evioEvent.getEventNumber() + " could not be parsed"); + } finally { + // End of file. + if (!badEvent && evioEvent == null) { + LOGGER.info("EOF after " + totalEvents + " events"); + break; + } + + // Increment event count. + totalEvents++; } - // Increment bad event count and continue. + // Continue to next event if a parse error occurred. if (badEvent) { - badEvents++; continue; - } - - // End of file. - if (evioEvent == null) { - LOGGER.info("end of file reached after " + eventCount + " events"); - break; - } - + } + + // Debug print event number and tag. + LOGGER.finest("parsed event " + evioEvent.getEventNumber() + " with tag 0x" + String.format("%08x", evioEvent.getHeader().getTag())); + // Process different event types. - if (EventTagConstant.PRESTART.equals(evioEvent)) { + if (EventTagConstant.PRESTART.matches(evioEvent)) { // File has PRESTART event. - LOGGER.info("found PRESTART event " + evioEvent.getEventNumber()); - prestart = true; + LOGGER.fine("found PRESTART event " + evioEvent.getEventNumber()); + ++prestartEvents; // Set the run number from the PRESTART event. final int[] controlEventData = EvioEventUtilities.getControlEventData(evioEvent); if (run == null) { run = controlEventData[1]; - LOGGER.info("set run to " + run + " from PRESTART"); - } - - } else if (EventTagConstant.GO.equals(evioEvent)) { + LOGGER.fine("set run to " + run + " from PRESTART"); + } + + // Set the first timestamp from the PRESTART event. + if (firstTimestamp == null) { + firstTimestamp = controlEventData[0]; + LOGGER.fine("set first timestamp to " + firstTimestamp + " from PRESTART event " + evioEvent.getEventNumber()); + } + + } else if (EventTagConstant.GO.matches(evioEvent)) { // File has GO event. - go = true; - - // Set the first timestamp from the GO event. - final int[] controlEventData = EvioEventUtilities.getControlEventData(evioEvent); - firstTimestamp = controlEventData[0]; - LOGGER.info("set first timestamp to " + firstTimestamp + " from GO event " + evioEvent.getEventNumber()); - - } else if (EventTagConstant.END.equals(evioEvent)) { + goEvents++; + + // Set first timestamp from the GO event (will not override PRESTART time). + if (firstTimestamp == null) { + final int[] controlEventData = EvioEventUtilities.getControlEventData(evioEvent); + firstTimestamp = controlEventData[0]; + LOGGER.fine("set first timestamp to " + firstTimestamp + " from GO event " + evioEvent.getEventNumber()); + } + + } else if (EventTagConstant.END.matches(evioEvent)) { // File has END event. - LOGGER.info("got END event"); - end = true; + LOGGER.fine("got END event"); + endEvents++; // Set the last timestamp from the END event. final int[] controlEventData = EvioEventUtilities.getControlEventData(evioEvent); lastTimestamp = controlEventData[0]; - LOGGER.info("set last timestamp " + lastTimestamp + " from END event " + evioEvent.getEventNumber()); + LOGGER.fine("set last timestamp " + lastTimestamp + " from END event " + evioEvent.getEventNumber()); if (run == null) { run = controlEventData[1]; - LOGGER.info("set run to " + run); - } + LOGGER.fine("set run to " + run); + } + + } else if (EventTagConstant.PAUSE.matches(evioEvent)) { + + // Count pause events. + pauseEvents++; } else if (EvioEventUtilities.isPhysicsEvent(evioEvent)) { - // Event count on the file only includes physics events. - eventCount++; + // Count physics events. + physicsEvents++; // Get head bank. final int[] headBankData = EvioEventUtilities.getHeadBankData(evioEvent); - // Set first timestamp from head bank. - if (firstTimestamp == null) { + // Is head bank present? + if (headBankData != null) { + + // Is timestamp set? if (headBankData[3] != 0) { - firstTimestamp = headBankData[3]; - LOGGER.info("set first timestamp to " + firstTimestamp + " from physics event " + evioEvent.getEventNumber()); + + // Set first timestamp. + if (firstTimestamp == null) { + firstTimestamp = headBankData[3]; + LOGGER.fine("set first timestamp to " + firstTimestamp + " from physics event " + evioEvent.getEventNumber()); + } + + // Set first physics timestamp. + if (firstPhysicsTimestamp == null) { + firstPhysicsTimestamp = headBankData[3]; + LOGGER.fine("set first physics timestamp to " + firstTimestamp + " from event " + evioEvent.getEventNumber()); + } + + // Set last physics timestamp. + lastPhysicsTimestamp = headBankData[3]; + LOGGER.finest("set last physics timestamp to " + firstTimestamp + " from event " + evioEvent.getEventNumber()); + + // Set last timestamp. + lastTimestamp = headBankData[3]; } - } - - // Set run number from head bank if not set already. - if (run == null) { - run = headBankData[1]; - LOGGER.info("set run to " + run + " from physics event " + evioEvent.getEventNumber()); - } - + + // Set run number. + if (run == null) { + run = headBankData[1]; + LOGGER.info("set run to " + run + " from physics event " + evioEvent.getEventNumber()); + } + } + // Get the event ID data. final int[] eventIdData = EvioEventUtilities.getEventIdData(evioEvent); - if (eventIdData == null) { - throw new RuntimeException("The event ID data bank for event " + evioEvent.getEventNumber() + " is null."); - } - - // Set the first physics event from event ID data. - if (firstPhysicsEvent == null) { - firstPhysicsEvent = eventIdData[0]; - LOGGER.info("set start event " + firstPhysicsEvent + " from physics event " + evioEvent.getEventNumber()); - } - - // Set the last physics event from the event ID data. - lastPhysicsEvent = eventIdData[0]; - - // Set the last timestamp from head bank. - if (headBankData[3] != 0) { - lastTimestamp = headBankData[3]; - } - - // Increment scaler bank count if exists in event. + if (eventIdData != null) { + + // Set the last physics event. + lastPhysicsEvent = eventIdData[0]; + + // Set the first physics event. + if (firstPhysicsEvent == null) { + firstPhysicsEvent = eventIdData[0]; + LOGGER.fine("set start event " + firstPhysicsEvent + " from physics event " + evioEvent.getEventNumber()); + } + } + + // Count scaler events. scalersProcessor.process(evioEvent); if (scalersProcessor.getCurrentScalerData() != null) { - scalerBanks++; - } - - // Increment event mask counts for each type. - Set<EventTagBitMask> masks = EventTagBitMask.getEventTagBitMasks(evioEvent); - for (EventTagBitMask mask : masks) { - int count = triggerCounts.get(mask) + 1; - triggerCounts.put(mask, count); - } - - } else if (EventTagConstant.EPICS.equals(evioEvent)) { + scalerData.add(scalersProcessor.getCurrentScalerData()); + scalerEvents++; + } + + // Count trigger types for this event. + Set<TriggerType> triggerTypes = TriggerType.getTriggerTypes(evioEvent); + for (TriggerType mask : triggerTypes) { + int count = eventCounts.get(mask) + 1; + eventCounts.put(mask, count); + LOGGER.finer("incremented " + mask.name() + " to " + count); + } + + // Count sync events. + if (EventTagMask.SYNC.matches(evioEvent.getHeader().getTag())) { + // Count sync events. + ++syncEvents; + LOGGER.finer("got sync event from tag " + String.format("%08x", evioEvent.getHeader().getTag())); + } + + } else if (EventTagConstant.EPICS.matches(evioEvent)) { + // Count EPICS events. ++epicsEvents; - } + + // Get EPICS data for charge calculation. + epicsProcessor.process(evioEvent); + EpicsData epicsEvent = epicsProcessor.getEpicsData(); + if (epicsEvent.hasKey("scaler_calc1")) { + epicsData.add(epicsEvent); + } + } } } catch (final EvioException e) { @@ -215,34 +287,89 @@ } } } - + + LOGGER.info("done reading " + totalEvents + " events"); + + // Rough trigger rate calculation. + triggerRate = calculateTriggerRate(firstPhysicsTimestamp, lastPhysicsTimestamp, physicsEvents); + + // Calculate ungated charge. + //double ungatedCharge = calculateCharge(epicsData, firstPhysicsTimestamp, lastPhysicsTimestamp); + + // Calculated gated charge. + //double gatedCharge = calculateGatedCharge(ungatedCharge, scalerData, ScalerDataIndex.FCUP_TRG_GATED, ScalerDataIndex.FCUP_TRG_UNGATED); + // Create and fill the metadata map. - final Map<String, Object> metaDataMap = new LinkedHashMap<String, Object>(); - metaDataMap.put("runMin", run); - metaDataMap.put("runMax", run); - metaDataMap.put("eventCount", eventCount); - metaDataMap.put("FILE", fileNumber); - metaDataMap.put("FIRST_TIMESTAMP", firstTimestamp); - metaDataMap.put("LAST_TIMESTAMP", lastTimestamp); - metaDataMap.put("FIRST_PHYSICS_EVENT", firstPhysicsEvent); - metaDataMap.put("LAST_PHYSICS_EVENT", lastPhysicsEvent); - metaDataMap.put("BAD_EVENTS", badEvents); - metaDataMap.put("EPICS_EVENTS", epicsEvents); - metaDataMap.put("SCALER_BANKS", scalerBanks); - metaDataMap.put("END", end); - metaDataMap.put("PRESTART", prestart); - metaDataMap.put("GO", go); - metaDataMap.put("BLINDED", blinded); - - // Add the event mask counts. - for (Entry<EventTagBitMask, Integer> entry : triggerCounts.entrySet()) { - // These two keys aren't working right so don't include them. - if (EventTagBitMask.PHYSICS != entry.getKey() && EventTagBitMask.SYNC != entry.getKey()) { - metaDataMap.put(entry.getKey().name(), entry.getValue()); - } - } - + final Map<String, Object> metadataMap = new LinkedHashMap<String, Object>(); + + // Built-in fields of datacat. + metadataMap.put("runMin", run); + metadataMap.put("runMax", run); + metadataMap.put("eventCount", totalEvents); + + // Run number. + metadataMap.put("RUN", run); + + // File sequence number. + metadataMap.put("FILE_NUMBER", fileNumber); + + // Blinded flag. + metadataMap.put("BLINDED", blinded); + + // First and last timestamps which may come from control or physics events. + metadataMap.put("FIRST_TIMESTAMP", firstTimestamp); + metadataMap.put("LAST_TIMESTAMP", lastTimestamp); + + // First and last physics events. + metadataMap.put("FIRST_PHYSICS_EVENT", firstPhysicsEvent); + metadataMap.put("LAST_PHYSICS_EVENT", lastPhysicsEvent); + + // First and last physics event timestamps. + metadataMap.put("FIRST_PHYSICS_TIMESTAMP", firstPhysicsTimestamp); + metadataMap.put("LAST_PHYSICS_TIMESTAMP", lastPhysicsTimestamp); + + // Event counts. + metadataMap.put("PHYSICS_EVENTS", physicsEvents); + metadataMap.put("BAD_EVENTS", badEvents); + metadataMap.put("EPICS_EVENTS", epicsEvents); + metadataMap.put("SCALER_EVENTS", scalerEvents); + metadataMap.put("END_EVENTS", endEvents); + metadataMap.put("PRESTART_EVENTS", prestartEvents); + metadataMap.put("GO_EVENTS", goEvents); + metadataMap.put("PAUSE_EVENTS", pauseEvents); + metadataMap.put("SYNC_EVENTS", syncEvents); + + // Trigger rate. + DecimalFormat df = new DecimalFormat("#.####"); + df.setRoundingMode(RoundingMode.CEILING); + metadataMap.put("TRIGGER_RATE_KHZ", Double.parseDouble(df.format(triggerRate))); + + // Add the trigger counts. + for (Entry<TriggerType, Integer> entry : eventCounts.entrySet()) { + metadataMap.put(entry.getKey().name(), entry.getValue()); + } + + // Print the file metadata to log. + StringBuffer sb = new StringBuffer(); + sb.append('\n'); + for (Entry<String, Object> entry : metadataMap.entrySet()) { + sb.append(" " + entry.getKey() + " = " + entry.getValue() + '\n'); + } + LOGGER.info("file metadata ..." + '\n' + sb.toString()); + // Return the completed metadata map. - return metaDataMap; + return metadataMap; } + + /** + * Calculate the trigger rate in KHz. + * + * @param firstTimestamp the first physics timestamp + * @param lastTimestamp the last physics timestamp + * @param physicsEvents the number of physics events + * @return the trigger rate calculation in KHz + */ + private double calculateTriggerRate(Integer firstTimestamp, Integer lastTimestamp, int physicsEvents) { + return ((double) physicsEvents / ((double) lastTimestamp - (double) firstTimestamp)) / 1000.; + } } Modified: java/branches/jeremy-dev/crawler/src/main/java/org/hps/crawler/FileMetadataReader.java ============================================================================= --- java/branches/jeremy-dev/crawler/src/main/java/org/hps/crawler/FileMetadataReader.java (original) +++ java/branches/jeremy-dev/crawler/src/main/java/org/hps/crawler/FileMetadataReader.java Tue Nov 10 15:21:05 2015 @@ -18,5 +18,5 @@ * @return the metadata map * @throws IOException if there is an error reading the file */ - public Map<String, Object> getMetadata(File file) throws IOException; + Map<String, Object> getMetadata(File file) throws IOException; } Modified: java/branches/jeremy-dev/crawler/src/main/java/org/hps/crawler/FileSet.java ============================================================================= --- java/branches/jeremy-dev/crawler/src/main/java/org/hps/crawler/FileSet.java (original) +++ java/branches/jeremy-dev/crawler/src/main/java/org/hps/crawler/FileSet.java Tue Nov 10 15:21:05 2015 @@ -14,14 +14,14 @@ */ public class FileSet extends HashMap<DatasetFileFormat, List<File>> { - public List<File> get(DatasetFileFormat format) { + List<File> get(DatasetFileFormat format) { if (super.get(format) == null) { this.put(format, new ArrayList<File>()); } return super.get(format); } - public void addFile(DatasetFileFormat format, File file) { + void addFile(DatasetFileFormat format, File file) { this.get(format).add(file); } } Modified: java/branches/jeremy-dev/crawler/src/main/java/org/hps/crawler/LcioMetadataReader.java ============================================================================= --- java/branches/jeremy-dev/crawler/src/main/java/org/hps/crawler/LcioMetadataReader.java (original) +++ java/branches/jeremy-dev/crawler/src/main/java/org/hps/crawler/LcioMetadataReader.java Tue Nov 10 15:21:05 2015 @@ -21,7 +21,7 @@ */ public class LcioMetadataReader implements FileMetadataReader { - /* + /** * Setup the conditions system in dummy mode. */ static { Modified: java/branches/jeremy-dev/record-util/src/main/java/org/hps/record/epics/EpicsData.java ============================================================================= --- java/branches/jeremy-dev/record-util/src/main/java/org/hps/record/epics/EpicsData.java (original) +++ java/branches/jeremy-dev/record-util/src/main/java/org/hps/record/epics/EpicsData.java Tue Nov 10 15:21:05 2015 @@ -281,7 +281,7 @@ EpicsData epicsData = null; // Is this an EPICS event? - if (EventTagConstant.EPICS.equals(evioEvent)) { + if (EventTagConstant.EPICS.matches(evioEvent)) { // Find the bank with the EPICS data string. final BaseStructure epicsBank = EvioBankTag.EPICS_STRING.findBank(evioEvent); Modified: java/branches/jeremy-dev/record-util/src/main/java/org/hps/record/epics/EpicsEvioProcessor.java ============================================================================= --- java/branches/jeremy-dev/record-util/src/main/java/org/hps/record/epics/EpicsEvioProcessor.java (original) +++ java/branches/jeremy-dev/record-util/src/main/java/org/hps/record/epics/EpicsEvioProcessor.java Tue Nov 10 15:21:05 2015 @@ -45,7 +45,7 @@ public void process(final EvioEvent evioEvent) { // Is this an EPICS event? - if (EventTagConstant.EPICS.equals(evioEvent)) { + if (EventTagConstant.EPICS.matches(evioEvent)) { LOGGER.fine("processing EPICS event " + evioEvent.getEventNumber()); Modified: java/branches/jeremy-dev/record-util/src/main/java/org/hps/record/evio/EventTagConstant.java ============================================================================= --- java/branches/jeremy-dev/record-util/src/main/java/org/hps/record/evio/EventTagConstant.java (original) +++ java/branches/jeremy-dev/record-util/src/main/java/org/hps/record/evio/EventTagConstant.java Tue Nov 10 15:21:05 2015 @@ -63,7 +63,7 @@ return tag == this.tag; } - public boolean equals(final EvioEvent evioEvent) { + public boolean matches(final EvioEvent evioEvent) { return evioEvent.getHeader().getTag() == this.tag; } Added: java/branches/jeremy-dev/record-util/src/main/java/org/hps/record/evio/EventTagMask.java ============================================================================= --- java/branches/jeremy-dev/record-util/src/main/java/org/hps/record/evio/EventTagMask.java (added) +++ java/branches/jeremy-dev/record-util/src/main/java/org/hps/record/evio/EventTagMask.java Tue Nov 10 15:21:05 2015 @@ -0,0 +1,40 @@ +package org.hps.record.evio; + +/** + * Event tag mask for physics and sync events. + * @author Jeremy McCormick, SLAC + */ +public enum EventTagMask { + + /** Sync event with scalers and/or trigger config. */ + SYNC(0x40), + /** Physics events. */ + PHYSICS(0x80); + + /** + * Define an event tag with a mask. + * @param mask the bit mask value + */ + EventTagMask(int mask) { + this.mask = mask; + } + + private int mask; + + /** + * Get the tag's mask value. + * @return the tag's mask value + */ + public int getMask() { + return mask; + } + + /** + * Return <code>true</code> if the <code>eventTag</code> matches this mask. + * @param eventTag the event tag value from the EVIO header + * @return <code>true</code> if <code>eventTag</code> matches this mask + */ + public boolean matches(int eventTag) { + return (eventTag & mask) > 0; + } +} Modified: java/branches/jeremy-dev/record-util/src/main/java/org/hps/record/evio/EvioBankTag.java ============================================================================= --- java/branches/jeremy-dev/record-util/src/main/java/org/hps/record/evio/EvioBankTag.java (original) +++ java/branches/jeremy-dev/record-util/src/main/java/org/hps/record/evio/EvioBankTag.java Tue Nov 10 15:21:05 2015 @@ -25,8 +25,10 @@ /** Scaler data bank. */ SCALERS(57621), /** Trigger configuration bank. */ - TRIGGER_CONFIG(0xE10E); - + TRIGGER_CONFIG(0xE10E), + /** TI trigger bank. */ + TI_TRIGGER(0xe10a); + /** * The bank's tag value. */ @@ -46,7 +48,7 @@ * * @param startBank the starting bank * @return the first bank matching the tag or <code>null<code> if not found - */ + */ public BaseStructure findBank(final BaseStructure startBank) { BaseStructure foundBank = null; if (this.equals(startBank)) { @@ -60,8 +62,8 @@ } } return foundBank; - } - + } + /** * Get the bank tag value. * Copied: java/branches/jeremy-dev/record-util/src/main/java/org/hps/record/triggerbank/TriggerType.java (from r3945, java/branches/jeremy-dev/record-util/src/main/java/org/hps/record/evio/EventTagBitMask.java) ============================================================================= --- java/branches/jeremy-dev/record-util/src/main/java/org/hps/record/evio/EventTagBitMask.java (original) +++ java/branches/jeremy-dev/record-util/src/main/java/org/hps/record/triggerbank/TriggerType.java Tue Nov 10 15:21:05 2015 @@ -1,112 +1,86 @@ -package org.hps.record.evio; +package org.hps.record.triggerbank; import java.util.HashSet; import java.util.Set; +import org.hps.record.triggerbank.AbstractIntData.IntBankDefinition; +import org.jlab.coda.jevio.BaseStructure; import org.jlab.coda.jevio.EvioEvent; /** - * Encapsulates bit mask values for different types of physics events as described at + * Provides bit mask checks for the trigger types defined in * <a href="https://confluence.slac.stanford.edu/display/hpsg/EVIO+Data+Format#EVIODataFormat-EVIOEventtypes-2015DataSet">EVIO Event types</a>. * - * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a> + * @author Jeremy McCormick, SLAC */ -public enum EventTagBitMask { - - /** LED or Cosmic trigger. */ - LED_COSMIC(4), +public enum TriggerType { + + /** LED or Cosmic trigger (sometimes called calibration also). */ + LED_COSMIC(28), /** Pair 0 trigger. */ - PAIRS0(2), + PAIRS0(26), /** Pair 1 trigger. */ - PAIRS1(3), - /** Physics event. */ - PHYSICS(7), // FIXME: Doesn't work! + PAIRS1(27), /** Pulser triggered event. */ - PULSER(5), + PULSER(29), /** Single 0 trigger. */ - SINGLE0(0), + SINGLES0(24), /** Single 1 trigger. */ - SINGLE1(1), - /** Physics sync event. */ - SYNC(6); - + SINGLES1(25); + /** * The bit number. */ private int bit; /** - * The bit mask. + * Constructor with bit number which is used to shift the input TI bits. + * @param bit the bit number for shifting the TI bits */ - private int bitMask; - - /** - * Constructor with bit number. - * - * @param bit the bit number - */ - private EventTagBitMask(final int bit) { + private TriggerType(final int bit) { this.bit = bit; - this.bitMask = 1 >> this.bit; } /** - * Get the bit number. - * + * Get the bit number. * @return the bit number */ public int getBit() { return this.bit; } - + /** - * Get the bit mask. - * - * @return the bit mask + * Return <code>true</code> if the bits match this mask. + * @param triggerBits the trigger bits from the TI bank + * @return <code>true</code> if the bits match this mask */ - public int getBitMask() { - return this.bitMask; - } - - /** - * Return <code>true</code> if the event's tag matches this mask. - * - * @param event an <code>EvioEvent</code> with tag to check against this mask - * @return <code>true</code> if the event's tag matches this mask - */ - public boolean equals(final EvioEvent event) { - return equals(event.getHeader().getTag()); - } - - /** - * Return <code>true</code> if the tag matches this mask. - * - * @param eventTag the event's tag from the header bank - * @return <code>true</code> if the tag matches this mask - */ - public boolean equals(final int eventTag) { - return (eventTag & this.bitMask) == 1; + public boolean matches(final int triggerBits) { + return ((triggerBits >> this.bit) & 1) == 1; } - public static Set<EventTagBitMask> getEventTagBitMasks(EvioEvent evioEvent) { - Set<EventTagBitMask> bitMasks = new HashSet<EventTagBitMask>(); - if (LED_COSMIC.equals(evioEvent)) { - bitMasks.add(LED_COSMIC); - } if (PAIRS0.equals(evioEvent)) { - bitMasks.add(PAIRS0); - } if (PAIRS1.equals(evioEvent)) { - bitMasks.add(PAIRS1); - } if (PHYSICS.equals(evioEvent)) { - bitMasks.add(PHYSICS); - } if (PULSER.equals(evioEvent)) { - bitMasks.add(PULSER); - } if (SINGLE0.equals(evioEvent)) { - bitMasks.add(SINGLE0); - } if (SINGLE1.equals(evioEvent)) { - bitMasks.add(SINGLE1); - } if (SYNC.equals(evioEvent)) { - bitMasks.add(SYNC); + /** + * Definition of the TI bank in the EVIO event. + */ + private static IntBankDefinition TI_BANK = new IntBankDefinition(TIData.class, new int[] {0x2e, 0xe10a}); + + /** + * Get the applicable trigger types from the TI data in an EVIO event. + * @param evioEvent the input EVIO event with the TI data + * @return the set of matching trigger types for the event + */ + public static Set<TriggerType> getTriggerTypes(EvioEvent evioEvent) { + Set<TriggerType> matches = new HashSet<TriggerType>(); + BaseStructure tiBank = TI_BANK.findBank(evioEvent); + if (tiBank != null) { + int[] triggerData = tiBank.getIntData(); + if (triggerData != null) { + for (TriggerType triggerType : TriggerType.values()) { + if (triggerType.matches(triggerData[0])) { + matches.add(triggerType); + } + } + } } - return bitMasks; - } + return matches; + } }