Author: [log in to unmask]
Date: Mon May 11 12:27:51 2015
New Revision: 2948
Log:
Miscellaneous updates to EVIO crawler package (still very much a work in progress).
Added:
java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/EpicsLog.java
java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/EventTypeLog.java
java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/EvioFileFilter.java
- copied, changed from r2946, java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/EvioFilter.java
java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/RunProcessor.java
Removed:
java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/EvioFilter.java
Modified:
java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/DateFileFilter.java
java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/EvioFileCrawler.java
java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/EvioFileList.java
java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/EvioFileSequenceComparator.java
java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/EvioFileUtilities.java
java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/EvioFileVisitor.java
java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/RunFilter.java
java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/RunLog.java
java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/RunSummary.java
Modified: java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/DateFileFilter.java
=============================================================================
--- java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/DateFileFilter.java (original)
+++ java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/DateFileFilter.java Mon May 11 12:27:51 2015
@@ -7,7 +7,7 @@
import java.nio.file.attribute.BasicFileAttributes;
import java.util.Date;
-class DateFileFilter implements FileFilter {
+final class DateFileFilter implements FileFilter {
private final Date date;
Added: java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/EpicsLog.java
=============================================================================
--- java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/EpicsLog.java (added)
+++ java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/EpicsLog.java Mon May 11 12:27:51 2015
@@ -0,0 +1,67 @@
+package org.hps.record.evio.crawler;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.hps.record.epics.EpicsEvioProcessor;
+import org.hps.record.epics.EpicsScalarData;
+import org.hps.record.evio.EvioEventProcessor;
+import org.jlab.coda.jevio.EvioEvent;
+
+public final class EpicsLog extends EvioEventProcessor {
+
+ private final Map<String, Integer> counts = new HashMap<String, Integer>();
+
+ private EpicsScalarData currentData;
+
+ private final EpicsScalarData logData = new EpicsScalarData();
+ private final EpicsEvioProcessor processor = new EpicsEvioProcessor();
+
+ private final RunSummary runSummary;
+
+ EpicsLog(final RunSummary runSummary) {
+ this.runSummary = runSummary;
+ }
+
+ @Override
+ public void endJob() {
+ System.out.println(this.logData);
+
+ // Compute means for all EPICS variables.
+ for (final String name : this.logData.getUsedNames()) {
+ final double total = this.logData.getValue(name);
+ final double mean = total / this.counts.get(name);
+ this.logData.setValue(name, mean);
+ }
+
+ // Set the EPICS data on the run summary.
+ this.runSummary.setEpicsData(this.logData);
+ }
+
+ @Override
+ public void process(final EvioEvent evioEvent) {
+ this.processor.process(evioEvent);
+ this.currentData = this.processor.getEpicsScalarData();
+ update();
+ }
+
+ private void update() {
+ if (this.currentData != null) {
+ for (final String name : this.currentData.getUsedNames()) {
+ if (!this.logData.getUsedNames().contains(name)) {
+ this.logData.setValue(name, 0.);
+ }
+ if (!this.counts.keySet().contains(name)) {
+ this.counts.put(name, 0);
+ }
+ int count = this.counts.get(name);
+ count += 1;
+ this.counts.put(name, count);
+ final double value = this.logData.getValue(name) + this.currentData.getValue(name);
+ this.logData.setValue(name, value);
+ System.out.println(name + " => added " + this.currentData.getValue(name) + "; total = " + value
+ + "; mean = " + value / count);
+ }
+ }
+ }
+}
Added: java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/EventTypeLog.java
=============================================================================
--- java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/EventTypeLog.java (added)
+++ java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/EventTypeLog.java Mon May 11 12:27:51 2015
@@ -0,0 +1,50 @@
+package org.hps.record.evio.crawler;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.hps.record.evio.EventTagBitMask;
+import org.hps.record.evio.EventTagConstant;
+import org.hps.record.evio.EvioEventProcessor;
+import org.jlab.coda.jevio.EvioEvent;
+
+public class EventTypeLog extends EvioEventProcessor {
+
+ Map<Object, Integer> eventTypeCounts = new HashMap<Object, Integer>();
+ RunSummary runSummary;
+
+ EventTypeLog(final RunSummary runSummary) {
+ this.runSummary = runSummary;
+ for (final EventTagConstant constant : EventTagConstant.values()) {
+ this.eventTypeCounts.put(constant, 0);
+ }
+ for (final EventTagBitMask mask : EventTagBitMask.values()) {
+ this.eventTypeCounts.put(mask, 0);
+ }
+ }
+
+ @Override
+ public void endJob() {
+ this.runSummary.setEventTypeCounts(this.eventTypeCounts);
+ }
+
+ Map<Object, Integer> getEventTypeCounts() {
+ return this.eventTypeCounts;
+ }
+
+ @Override
+ public void process(final EvioEvent event) {
+ for (final EventTagConstant constant : EventTagConstant.values()) {
+ if (constant.isEventTag(event)) {
+ final int count = this.eventTypeCounts.get(constant) + 1;
+ this.eventTypeCounts.put(constant, count);
+ }
+ }
+ for (final EventTagBitMask mask : EventTagBitMask.values()) {
+ if (mask.isEventTag(event)) {
+ final int count = this.eventTypeCounts.get(mask) + 1;
+ this.eventTypeCounts.put(mask, count);
+ }
+ }
+ }
+}
Modified: java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/EvioFileCrawler.java
=============================================================================
--- java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/EvioFileCrawler.java (original)
+++ java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/EvioFileCrawler.java Mon May 11 12:27:51 2015
@@ -20,12 +20,12 @@
/**
* Crawls EVIO files in a directory tree, groups the files that are found by run, and optionally performs various tasks
- * based on the run summary information, including printing a summary, caching the files from JLAB MSS, and updating a
- * run database.
+ * based on the run summary information that is accumulated, including printing a summary, caching the files from JLAB
+ * MSS, and updating a run database.
*
* @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
*/
-public class EvioFileCrawler {
+public final class EvioFileCrawler {
private static final Logger LOGGER = LogUtil.create(EvioFileVisitor.class);
@@ -41,30 +41,48 @@
OPTIONS.addOption("d", "directory", true, "starting directory");
OPTIONS.addOption("r", "runs", true, "list of runs to accept (others will be excluded)");
OPTIONS.addOption("c", "cache", false, "cache files to /cache/mss from MSS (only works at JLAB)");
- OPTIONS.addOption("p", "print", false, "print run summary at end of job");
+ OPTIONS.addOption("s", "summary", false, "print run summary at end of job");
OPTIONS.addOption("L", "log-level", true, "set log level (INFO, FINE, etc.)");
OPTIONS.addOption("u", "update", false, "update the run database");
+ OPTIONS.addOption("e", "epics", false, "process EPICS data");
}
public static void main(final String[] args) {
- new EvioFileCrawler().parse(args).run();
- }
-
- final Set<Integer> acceptRuns = new HashSet<Integer>();
-
- boolean cache = false;
-
- final PosixParser parser = new PosixParser();
-
- boolean printSummary = false;
-
- File rootDir = new File(System.getProperty("user.dir"));
-
- Date timestamp = null;
-
- File timestampFile = null;
-
- boolean update = false;
+ try {
+ new EvioFileCrawler().parse(args).run();
+ } catch (final Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ private final Set<Integer> acceptRuns = new HashSet<Integer>();
+
+ private boolean cache = false;
+
+ private boolean epics = false;
+
+ private final PosixParser parser = new PosixParser();
+
+ private boolean printSummary = false;
+
+ private File rootDir = new File(System.getProperty("user.dir"));
+
+ private Date timestamp = null;
+
+ private File timestampFile = null;
+
+ private boolean update = false;
+
+ private RunProcessor createRunProcessor(final RunSummary runSummary) {
+ final RunProcessor processor = new RunProcessor(runSummary);
+ if (this.epics) {
+ processor.addProcessor(new EpicsLog(runSummary));
+ }
+ if (this.printSummary) {
+ processor.addProcessor(new EventTypeLog(runSummary));
+ }
+ return processor;
+ }
private EvioFileCrawler parse(final String args[]) {
try {
@@ -109,7 +127,7 @@
}
}
- if (cl.hasOption("p")) {
+ if (cl.hasOption("s")) {
this.printSummary = true;
}
@@ -126,6 +144,10 @@
throw new IllegalArgumentException("File caching cannot be activated with the -p or -u options.");
}
+ if (cl.hasOption("e")) {
+ this.epics = true;
+ }
+
} catch (final ParseException e) {
throw new RuntimeException("Error parsing options.", e);
}
@@ -133,7 +155,22 @@
return this;
}
- public void run() {
+ private void processRuns(final RunLog runs) throws Exception {
+ // Process all files in the runs.
+ for (final int run : runs.getSortedRunNumbers()) {
+
+ // Get the run summary for the run.
+ final RunSummary runSummary = runs.getRunSummary(run);
+
+ // Create a processor to process all the EVIO records in the run.
+ final RunProcessor processor = createRunProcessor(runSummary);
+
+ // Process the run, updating the run summary.
+ processor.process();
+ }
+ }
+
+ public void run() throws Exception {
final EnumSet<FileVisitOption> options = EnumSet.noneOf(FileVisitOption.class);
final EvioFileVisitor visitor = new EvioFileVisitor();
if (this.timestamp != null) {
@@ -160,6 +197,8 @@
// Cache files from MSS.
runs.cache();
} else {
+
+ processRuns(runs);
// Print the run summaries.
if (this.printSummary) {
Copied: java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/EvioFileFilter.java (from r2946, java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/EvioFilter.java)
=============================================================================
--- java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/EvioFilter.java (original)
+++ java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/EvioFileFilter.java Mon May 11 12:27:51 2015
@@ -3,7 +3,7 @@
import java.io.File;
import java.io.FileFilter;
-class EvioFilter implements FileFilter {
+final class EvioFileFilter implements FileFilter {
@Override
public boolean accept(final File pathname) {
Modified: java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/EvioFileList.java
=============================================================================
--- java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/EvioFileList.java (original)
+++ java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/EvioFileList.java Mon May 11 12:27:51 2015
@@ -7,16 +7,20 @@
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collections;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import java.util.logging.Logger;
import org.jlab.coda.jevio.EvioException;
import org.jlab.coda.jevio.EvioReader;
import org.lcsim.util.log.LogUtil;
-class EvioFileList extends ArrayList<File> {
+final class EvioFileList extends ArrayList<File> {
private static final Logger LOGGER = LogUtil.create(EvioFileList.class);
+
+ Map<File, Integer> eventCounts = new HashMap<File, Integer>();
void cache() {
LOGGER.info("running cache commands ...");
@@ -26,25 +30,34 @@
LOGGER.info("done running cache commands");
}
+ void computeEventCount(final File file) {
+ LOGGER.info("computing event count for " + file.getPath() + " ...");
+ int eventCount = 0;
+ EvioReader reader = null;
+ try {
+ reader = new EvioReader(file, false);
+ eventCount += reader.getEventCount();
+ } catch (EvioException | IOException e) {
+ throw new RuntimeException(e);
+ } finally {
+ if (reader != null) {
+ try {
+ reader.close();
+ } catch (final IOException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ this.eventCounts.put(file, eventCount);
+ LOGGER.info("done computing event count for " + file.getPath());
+ }
+
int computeTotalEvents() {
LOGGER.info("computing total events ...");
int totalEvents = 0;
for (final File file : this) {
- EvioReader reader = null;
- try {
- reader = new EvioReader(file, false);
- totalEvents += reader.getEventCount();
- } catch (EvioException | IOException e) {
- throw new RuntimeException(e);
- } finally {
- if (reader != null) {
- try {
- reader.close();
- } catch (final IOException e) {
- e.printStackTrace();
- }
- }
- }
+ getEventCount(file);
+ totalEvents += this.eventCounts.get(file);
}
LOGGER.info("done computing total events");
return totalEvents;
@@ -52,6 +65,13 @@
File first() {
return this.get(0);
+ }
+
+ int getEventCount(final File file) {
+ if (!this.eventCounts.containsKey(file)) {
+ computeEventCount(file);
+ }
+ return this.eventCounts.get(file);
}
void insert(final Connection connection, final int run) throws SQLException {
@@ -67,7 +87,6 @@
filesStatement.setString(3, file.getName());
LOGGER.info("executing statement: " + filesStatement);
filesStatement.executeUpdate();
- // connection.commit();
}
LOGGER.info("run_log_files was updated!");
}
Modified: java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/EvioFileSequenceComparator.java
=============================================================================
--- java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/EvioFileSequenceComparator.java (original)
+++ java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/EvioFileSequenceComparator.java Mon May 11 12:27:51 2015
@@ -3,7 +3,7 @@
import java.io.File;
import java.util.Comparator;
-class EvioFileSequenceComparator implements Comparator<File> {
+final class EvioFileSequenceComparator implements Comparator<File> {
@Override
public int compare(final File o1, final File o2) {
Modified: java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/EvioFileUtilities.java
=============================================================================
--- java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/EvioFileUtilities.java (original)
+++ java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/EvioFileUtilities.java Mon May 11 12:27:51 2015
@@ -13,7 +13,7 @@
import org.jlab.coda.jevio.EvioReader;
import org.lcsim.util.log.LogUtil;
-public class EvioFileUtilities {
+public final class EvioFileUtilities {
private static final Logger LOGGER = LogUtil.create(EvioFileUtilities.class);
Modified: java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/EvioFileVisitor.java
=============================================================================
--- java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/EvioFileVisitor.java (original)
+++ java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/EvioFileVisitor.java Mon May 11 12:27:51 2015
@@ -12,19 +12,19 @@
import org.lcsim.util.log.LogUtil;
-class EvioFileVisitor extends SimpleFileVisitor<Path> {
+final class EvioFileVisitor extends SimpleFileVisitor<Path> {
private static final Logger LOGGER = LogUtil.create(EvioFileVisitor.class);
- List<FileFilter> filters = new ArrayList<FileFilter>();
+ private final List<FileFilter> filters = new ArrayList<FileFilter>();
- RunLog runs = new RunLog();
+ private final RunLog runs = new RunLog();
EvioFileVisitor() {
- addFilter(new EvioFilter());
+ addFilter(new EvioFileFilter());
}
- boolean accept(final File file) {
+ private boolean accept(final File file) {
boolean accept = true;
for (final FileFilter filter : this.filters) {
accept = filter.accept(file);
@@ -57,6 +57,7 @@
LOGGER.info("adding file: " + file.getPath() + "; run: " + run + "; seq = " + seq);
this.runs.getRunSummary(run).addFile(file);
+
} else {
LOGGER.info("rejected file: " + file.getPath());
}
Modified: java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/RunFilter.java
=============================================================================
--- java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/RunFilter.java (original)
+++ java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/RunFilter.java Mon May 11 12:27:51 2015
@@ -4,7 +4,7 @@
import java.io.FileFilter;
import java.util.Set;
-class RunFilter implements FileFilter {
+final class RunFilter implements FileFilter {
Set<Integer> acceptRuns;
RunFilter(final Set<Integer> acceptRuns) {
Modified: java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/RunLog.java
=============================================================================
--- java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/RunLog.java (original)
+++ java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/RunLog.java Mon May 11 12:27:51 2015
@@ -14,7 +14,7 @@
import org.hps.conditions.database.ConnectionParameters;
import org.lcsim.util.log.LogUtil;
-class RunLog {
+final class RunLog {
private static final Logger LOGGER = LogUtil.create(RunLog.class);
@@ -92,7 +92,6 @@
runLogStatement.setInt(5, runSummary.getFiles().size());
runLogStatement.setBoolean(6, runSummary.isEndOkay());
runLogStatement.executeUpdate();
- // connection.commit();
LOGGER.info("committed run " + run + " to run_log");
}
LOGGER.info("run_log was updated!");
Added: 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 (added)
+++ java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/RunProcessor.java Mon May 11 12:27:51 2015
@@ -0,0 +1,68 @@
+package org.hps.record.evio.crawler;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.logging.Logger;
+
+import org.hps.record.evio.EvioEventProcessor;
+import org.jlab.coda.jevio.EvioEvent;
+import org.jlab.coda.jevio.EvioException;
+import org.jlab.coda.jevio.EvioReader;
+import org.lcsim.util.log.LogUtil;
+
+public final class RunProcessor {
+
+ private static final Logger LOGGER = LogUtil.create(RunProcessor.class);
+
+ List<EvioEventProcessor> processors = new ArrayList<EvioEventProcessor>();
+
+ RunSummary runSummary;
+
+ RunProcessor(final RunSummary runSummary) {
+ this.runSummary = runSummary;
+ }
+
+ void addProcessor(final EvioEventProcessor processor) {
+ this.processors.add(processor);
+ LOGGER.config("added processor: " + processor.getClass().getSimpleName());
+ }
+
+ List<EvioEventProcessor> getProcessors() {
+ return this.processors;
+ }
+
+ void process() throws Exception {
+ if (this.processors.isEmpty()) {
+ throw new RuntimeException("The processors list is empty.");
+ }
+ for (final EvioEventProcessor processor : this.processors) {
+ processor.startJob();
+ }
+ for (final File file : this.runSummary.getFiles()) {
+ process(file);
+ }
+ for (final EvioEventProcessor processor : this.processors) {
+ processor.endJob();
+ }
+ }
+
+ private void process(final File file) throws EvioException, IOException, Exception {
+ EvioReader reader = null;
+ try {
+ reader = EvioFileUtilities.open(file);
+ this.runSummary.getFiles().computeEventCount(file);
+ EvioEvent event = null;
+ while ((event = reader.parseNextEvent()) != null) {
+ for (final EvioEventProcessor processor : this.processors) {
+ processor.process(event);
+ }
+ }
+ } finally {
+ if (reader != null) {
+ reader.close();
+ }
+ }
+ }
+}
Modified: java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/RunSummary.java
=============================================================================
--- java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/RunSummary.java (original)
+++ java/trunk/record-util/src/main/java/org/hps/record/evio/crawler/RunSummary.java Mon May 11 12:27:51 2015
@@ -4,19 +4,38 @@
import java.io.IOException;
import java.io.PrintStream;
import java.util.Date;
+import java.util.Map;
import java.util.logging.Logger;
+import org.hps.record.epics.EpicsScalarData;
import org.hps.record.evio.EvioEventConstants;
import org.jlab.coda.jevio.EvioEvent;
import org.jlab.coda.jevio.EvioException;
import org.jlab.coda.jevio.EvioReader;
import org.lcsim.util.log.LogUtil;
-class RunSummary {
+/**
+ * This class models the run summary information which is persisted as one record in the <i>run_log</i> table.
+ * <p>
+ * This information includes:
+ * <ul>
+ * <li>run number</li>
+ * <li>start date</li>
+ * <li>end date</li>
+ * <li>total number of events across all files in the run</li>
+ * <li>number of files found belonging to the run</li>
+ * <li>whether the EVIO END event was found</li>
+ * </ul>
+ *
+ * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
+ */
+final class RunSummary {
private static final Logger LOGGER = LogUtil.create(RunSummary.class);
private Date endDate;
+ private EpicsScalarData epics;
+ private Map<Object, Integer> eventTypeCounts;
private final EvioFileList files = new EvioFileList();
private Boolean isEndOkay;
private final int run;
@@ -39,6 +58,14 @@
this.endDate = EvioFileUtilities.getRunEnd(this.files.last());
}
return this.endDate;
+ }
+
+ EpicsScalarData getEpicsData() {
+ return this.epics;
+ }
+
+ Map<Object, Integer> getEventTypeCounts() {
+ return this.eventTypeCounts;
}
EvioFileList getFiles() {
@@ -66,7 +93,7 @@
final File lastFile = this.files.last();
EvioReader reader = null;
try {
- reader = new EvioReader(lastFile, false);
+ reader = EvioFileUtilities.open(lastFile);
reader.gotoEventNumber(reader.getEventCount() - 5);
EvioEvent event = null;
while ((event = reader.parseNextEvent()) != null) {
@@ -98,10 +125,22 @@
ps.println("started: " + getStartDate());
ps.println("ended: " + getEndDate());
ps.println("total events: " + this.getTotalEvents());
- ps.println("files: " + this.files.size());
+ ps.println("event types");
+ for (final Object key : this.eventTypeCounts.keySet()) {
+ ps.println(" " + key + ": " + this.eventTypeCounts.get(key));
+ }
+ ps.println("files" + this.files.size());
for (final File file : this.files) {
ps.println(file.getPath());
}
+ }
+
+ void setEpicsData(final EpicsScalarData epics) {
+ this.epics = epics;
+ }
+
+ void setEventTypeCounts(final Map<Object, Integer> eventTypeCounts) {
+ this.eventTypeCounts = eventTypeCounts;
}
void sortFiles() {
|