Author: [log in to unmask] Date: Wed Jan 28 11:03:46 2015 New Revision: 1996 Log: Improve handling of max records and event processing errors. Modified: java/trunk/record-util/src/main/java/org/hps/record/MaxRecordsException.java java/trunk/record-util/src/main/java/org/hps/record/composite/CompositeLoop.java java/trunk/record-util/src/main/java/org/hps/record/composite/CompositeLoopAdapter.java java/trunk/record-util/src/main/java/org/hps/record/composite/CompositeLoopConfiguration.java java/trunk/record-util/src/main/java/org/hps/record/composite/EvioEventAdapter.java java/trunk/record-util/src/main/java/org/hps/record/composite/MaxRecordsProcessor.java java/trunk/record-util/src/main/java/org/hps/record/evio/EvioFileSource.java Modified: java/trunk/record-util/src/main/java/org/hps/record/MaxRecordsException.java ============================================================================= --- java/trunk/record-util/src/main/java/org/hps/record/MaxRecordsException.java (original) +++ java/trunk/record-util/src/main/java/org/hps/record/MaxRecordsException.java Wed Jan 28 11:03:46 2015 @@ -4,11 +4,11 @@ * Exception thrown when maximum number of records is reached. */ // FIXME: Use loop(nevents) instead of this for controlling number of records run. -public class MaxRecordsException extends Exception { +public class MaxRecordsException extends RuntimeException { - int maxRecords; + long maxRecords; - public MaxRecordsException(String message, int maxRecords) { + public MaxRecordsException(String message, long maxRecords) { super(message); this.maxRecords = maxRecords; } @@ -17,7 +17,7 @@ * Get the maximum number of records. * @return The maximum number of records. */ - public int getMaxRecords() { + public long getMaxRecords() { return maxRecords; } } Modified: java/trunk/record-util/src/main/java/org/hps/record/composite/CompositeLoop.java ============================================================================= --- java/trunk/record-util/src/main/java/org/hps/record/composite/CompositeLoop.java (original) +++ java/trunk/record-util/src/main/java/org/hps/record/composite/CompositeLoop.java Wed Jan 28 11:03:46 2015 @@ -10,6 +10,7 @@ import org.freehep.record.source.RecordSource; import org.hps.record.EndRunException; import org.hps.record.MaxRecordsException; +import org.hps.record.RecordProcessingException; import org.hps.record.enums.DataSourceType; import org.hps.record.enums.ProcessingStage; import org.hps.record.et.EtEventProcessor; @@ -98,7 +99,7 @@ // Ignore the error! return; } - + // Set the exception on the super class. this._exception = x; @@ -112,7 +113,7 @@ protected void handleSourceError(Throwable x) { x.printStackTrace(); - + // Is the error ignorable? if (isIgnorable(x)) { // Ignore the error! @@ -127,47 +128,39 @@ } /** - * True if an error is ignorable. If <code>stopOnErrors</code> + * <p> + * True if an error is ignore-able. If <code>stopOnErrors</code> * is true, then this method always returns false. Otherwise, * the error cause determines whether the loop can continue * processing. + * <p> + * The assumption here is that errors coming from event processing + * of the composite records are caught in the adapters and then wrapped + * in a {@link org.hps.record.RecordProcessingException}. Certain + * errors which should never be ignored are also wrapped in a + * similar way, so we need to check for these error types before + * assuming that event processing can continue. + * * @param x The error that occurred. * @return True if the error can be ignored. */ - private boolean isIgnorable(Throwable x) { - - // Should the loop try to recover from the error if possible? - if (!stopOnErrors) { - - // EndRunExceptions are never ignored. - if (x.getCause() instanceof EndRunException) - return false; - - // MaxRecordsExceptions are never ignored. - if (x.getCause() instanceof MaxRecordsException) - return false; - - // ET system errors are always considered fatal. - if (x.getCause() instanceof EtSourceException) - return false; - - // The NoSuchRecordException indicates a RecordSource - // was exhausted so processing needs to end. - if (x.getCause() instanceof NoSuchRecordException) - return false; - - // When this occurs one of the loops is probably messed up, - // so it is not considered recoverable. - if (x.getCause() instanceof IllegalStateException) - return false; - - // Ignore the error. - return true; - - } else { - // Error is not ignored. - return false; - } + private boolean isIgnorable(Throwable x) { + if (!stopOnErrors) { + if (x instanceof RecordProcessingException) { + Throwable cause = x.getCause(); + if (cause instanceof MaxRecordsException || + cause instanceof EndRunException || + cause instanceof EtSourceException || + cause instanceof NoSuchRecordException) { + // These types of exceptions are never ignored. + return false; + } else { + // Other types of record processing exceptions are considered non-fatal. + return true; + } + } + } + return false; } /** Modified: java/trunk/record-util/src/main/java/org/hps/record/composite/CompositeLoopAdapter.java ============================================================================= --- java/trunk/record-util/src/main/java/org/hps/record/composite/CompositeLoopAdapter.java (original) +++ java/trunk/record-util/src/main/java/org/hps/record/composite/CompositeLoopAdapter.java Wed Jan 28 11:03:46 2015 @@ -32,7 +32,7 @@ * @param loopEvent */ public void finish(LoopEvent loopEvent) { - System.out.println(this.getClass().getCanonicalName() + ".finish"); + //System.out.println(this.getClass().getCanonicalName() + ".finish"); // Call end job hook on all processors. for (CompositeRecordProcessor processor : processors) { processor.endJob(); Modified: java/trunk/record-util/src/main/java/org/hps/record/composite/CompositeLoopConfiguration.java ============================================================================= --- java/trunk/record-util/src/main/java/org/hps/record/composite/CompositeLoopConfiguration.java (original) +++ java/trunk/record-util/src/main/java/org/hps/record/composite/CompositeLoopConfiguration.java Wed Jan 28 11:03:46 2015 @@ -30,7 +30,7 @@ boolean stopOnErrors = true; boolean stopOnEndRun = true; - int maxRecords = -1; + long maxRecords = -1; DataSourceType sourceType = DataSourceType.ET_SERVER; ProcessingStage processingStage = ProcessingStage.LCIO; @@ -158,7 +158,7 @@ * @param maxRecords * @return */ - public CompositeLoopConfiguration setMaxRecords(int maxRecords) { + public CompositeLoopConfiguration setMaxRecords(long maxRecords) { if (maxRecords < 1) throw new IllegalArgumentException("Invalid maxRecords value: " + maxRecords); this.maxRecords = maxRecords; Modified: java/trunk/record-util/src/main/java/org/hps/record/composite/EvioEventAdapter.java ============================================================================= --- java/trunk/record-util/src/main/java/org/hps/record/composite/EvioEventAdapter.java (original) +++ java/trunk/record-util/src/main/java/org/hps/record/composite/EvioEventAdapter.java Wed Jan 28 11:03:46 2015 @@ -65,8 +65,12 @@ } } else { // Load the next record from the EVIO record source. - source.next(); - evioEvent = (EvioEvent)source.getCurrentRecord(); + if (source.hasNext()) { + source.next(); + evioEvent = (EvioEvent)source.getCurrentRecord(); + } else { + throw new NoSuchRecordException("EVIO event source has no more records."); + } } // Failed to create an EvioEvent? if (evioEvent == null) { Modified: java/trunk/record-util/src/main/java/org/hps/record/composite/MaxRecordsProcessor.java ============================================================================= --- java/trunk/record-util/src/main/java/org/hps/record/composite/MaxRecordsProcessor.java (original) +++ java/trunk/record-util/src/main/java/org/hps/record/composite/MaxRecordsProcessor.java Wed Jan 28 11:03:46 2015 @@ -1,34 +1,48 @@ package org.hps.record.composite; import org.hps.record.MaxRecordsException; -import org.hps.record.RecordProcessingException; +import org.hps.record.evio.EvioEventUtilities; /** * A @{link CompositeProcessor} for throwing an error when the * maximum number of records is reached or exceeded. */ -// FIXME: This should be done different by using directly the loop and adapter. public class MaxRecordsProcessor extends CompositeRecordProcessor { - int maxRecords; - int recordsReceived; + long maxRecords; + long recordsReceived; /** * Constructor with the maximum number of records. * @param maxRecords The maximum number of records. */ - public MaxRecordsProcessor(int maxRecords) { + public MaxRecordsProcessor(long maxRecords) { this.maxRecords = maxRecords; } /** * Process a record and check if max number of records was reached. + * Only records with certain types are considered in this total, + * which are basically "physics" events when processing LCIO + * or EVIO files. For an ET system without any other record processing, + * all events count towards the total. */ public void process(CompositeRecord record) { - if (recordsReceived >= maxRecords) - throw new RecordProcessingException( - "Maximum number of records received.", - new MaxRecordsException("Maximum number of records received.", maxRecords)); - ++recordsReceived; + if (record.getLcioEvent() != null) { + // All LCSim events count as records. + ++recordsReceived; + } else if (record.getEvioEvent() != null) { + if (EvioEventUtilities.isPhysicsEvent(record.getEvioEvent())) { + // Only EVIO physics events are counted. + ++recordsReceived; + } + } else { + // Otherwise (ET only?) count all records. + ++recordsReceived; + } + if (recordsReceived >= maxRecords) { + // Throw exception if max records was reached or exceeded. + new MaxRecordsException("Maximum number of records received.", maxRecords); + } } } Modified: java/trunk/record-util/src/main/java/org/hps/record/evio/EvioFileSource.java ============================================================================= --- java/trunk/record-util/src/main/java/org/hps/record/evio/EvioFileSource.java (original) +++ java/trunk/record-util/src/main/java/org/hps/record/evio/EvioFileSource.java Wed Jan 28 11:03:46 2015 @@ -121,7 +121,7 @@ public boolean supportsNext() { return true; } - + /** * True if there is a current record loaded. * @return True if there is a current record loaded. @@ -137,6 +137,10 @@ */ @Override public boolean hasNext() { - return !atEnd; + try { + return reader.getNumEventsRemaining() != 0; + } catch (IOException | EvioException e) { + throw new RuntimeException("Error getting num remaining events."); + } } }