Author: [log in to unmask]
Date: Fri Nov 13 11:11:25 2015
New Revision: 3957
Log:
Updated DAQ configuration driver such that it can now load DAQ settings directly from text files containing the EvIO DAQ configuration data banks.
Modified:
java/trunk/record-util/src/main/java/org/hps/record/daqconfig/DAQConfigDriver.java
Modified: java/trunk/record-util/src/main/java/org/hps/record/daqconfig/DAQConfigDriver.java
=============================================================================
--- java/trunk/record-util/src/main/java/org/hps/record/daqconfig/DAQConfigDriver.java (original)
+++ java/trunk/record-util/src/main/java/org/hps/record/daqconfig/DAQConfigDriver.java Fri Nov 13 11:11:25 2015
@@ -1,16 +1,36 @@
package org.hps.record.daqconfig;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.ArrayList;
import java.util.List;
import org.lcsim.event.EventHeader;
import org.lcsim.util.Driver;
/**
- * Class <code>DAQConfigDriver</code> is responsible for checking events
- * for DAQ configuration settings, and then passing them to the associated
+ * Class <code>DAQConfigDriver</code> is responsible for accessing the
+ * DAQ configuration settings, and then passing them to the associated
* class <code>ConfigurationManager</code> so that they can be accessed
* by other classes.<br/>
* <br/>
+ * The driver may accomplish this by two means. By default, it will
+ * check each event for an <code>EvioDAQParser</code> object which
+ * contains all of the DAQ configuration information and pass this to
+ * the <code>ConfigurationManager</code>. It will continue to update
+ * the <code>ConfigurationManager</code> during the run if new parser
+ * objects appear, and can thusly account for changing DAQ conditions.
+ * <br/><br/>
+ * The driver may also be set to read a DAQ configuration from text
+ * files containing the DAQ configuration bank information. To enable
+ * this mode, the parameter <code>readDataFiles</code> must be set to
+ * <code>true</code> and the parameters <code>runNumber</code> and also
+ * <code>filepath</code> must be defined. <code>runNumber</code> defines
+ * the run number of the configuration to be loaded and the parameter
+ * <code>filepath</code> defines the location of the data file repository.
+ * <br/><br/>
* This driver must be included in the driver chain if any other drivers
* in the chain rely on <code>ConfigurationManager</code>, as it can
* not be initialized otherwise.
@@ -19,15 +39,88 @@
* @see ConfigurationManager
*/
public class DAQConfigDriver extends Driver {
+ private int runNumber = -1;
+ private String filepath = null;
+ private boolean firstEvent = true;
+ private boolean readDataFiles = false;
+ private File[] dataFiles = new File[3];
+ private int[] crateNumber = { 46, 37, 39 };
+
+ /**
+ * Verifies the parameter <code>filepath</code> for the data file
+ * repository and checks that appropriate data files exist for the
+ * requested run number if the driver is set to read from data files.
+ * Otherwise, this does nothing.
+ */
+ @Override
+ public void startOfData() {
+ // Check whether to use stored data files or the EvIO data stream
+ // as the source of the DAQ settings. Nothing needs to be done
+ // in the latter case.
+ if(readDataFiles) {
+ // The user must define a data file prefix and repository
+ // location for this option to be used.
+ if(filepath == null) {
+ throw new NullPointerException("DAQ settings repository filepath must be defined.");
+ } if(runNumber == -1) {
+ throw new NullPointerException("Run number must be defined.");
+ }
+
+ // Verify that the repository actually exist.
+ File repository = new File(filepath);
+ if(!repository.exists() || !repository.isDirectory()) {
+ throw new IllegalArgumentException("Repository location \"" + filepath + "\" must be an existing directory.");
+ }
+
+ // Define the data file objects.
+ for(int i = 0; i < dataFiles.length; i++) {
+ try {
+ dataFiles[i] = new File(repository.getCanonicalPath() + "/" + runNumber + "_" + crateNumber[i] + ".txt");
+ } catch(IOException e) {
+ throw new RuntimeException("Error resolving absolute repository filepath.");
+ }
+ }
+
+ // Verify that the data files actually exist.
+ for(File dataFile : dataFiles) {
+ if(!dataFile.exists() || !dataFile.canRead()) {
+ throw new IllegalArgumentException("Data file \"" + dataFile.getName() + "\" does not exist or can not be read.");
+ }
+ }
+ }
+ }
+
/**
* Checks an event for the DAQ configuration banks and passes them
- * to the <code>ConfigurationManager</code>.
- * @param - The event to check.
+ * to the <code>ConfigurationManager</code> if the driver is set to
+ * read from the EvIO data stream. Otherwise, this will parse the
+ * data files on the first event and then do nothing.
+ * @param event - The current LCIO event.
*/
@Override
public void process(EventHeader event) {
+ // If this is the first event and data files are to be read,
+ // import the data files and generate the DAQ information.
+ if(firstEvent && readDataFiles) {
+ // Get the data files in the form of a data array.
+ String[][] data;
+ try { data = getDataFileArrays(dataFiles); }
+ catch(IOException e) {
+ throw new RuntimeException("An error occurred when processing the data files.");
+ }
+
+ // Instantiate an EvIO DAQ parser and feed it the data.
+ EvioDAQParser daqConfig = new EvioDAQParser();
+ for(int i = 0; i < dataFiles.length; i++) {
+ daqConfig.parse(crateNumber[i], runNumber, data[i]);
+ }
+
+ // Update the configuration manager.
+ ConfigurationManager.updateConfiguration(daqConfig);
+ }
+
// Check if a trigger configuration bank exists.
- if(event.hasCollection(EvioDAQParser.class, "TriggerConfig")) {
+ if(!readDataFiles && event.hasCollection(EvioDAQParser.class, "TriggerConfig")) {
// Get the trigger configuration bank. There should only be
// one in the list.
List<EvioDAQParser> configList = event.get(EvioDAQParser.class, "TriggerConfig");
@@ -37,5 +130,87 @@
// configuration object.
ConfigurationManager.updateConfiguration(daqConfig);
}
+
+ // Note that it is no longer the first event.
+ firstEvent = false;
+ }
+
+ /**
+ * Converts DAQ configuration data files into an array of strings
+ * where each array entry represents a line in the configuration
+ * file. The first array index of the returned object corresponds
+ * to the file, and the second array index corresponds to the line.
+ * @param dataFiles - An array of <code>File</code> objects pointing
+ * to the data files that are to be converted. These are expected
+ * to be plain text files.
+ * @return Returns a two-dimensional array of <code>String</code>
+ * objects where the first array index corresponds to the object
+ * of the same index in the <code>File</code> array and the second
+ * array index corresponds to the lines in the file referenced by
+ * the <code>File</code> object.
+ * @throws IOException Occurs if there is an issue with accessing
+ * or reading the objects in the objects referred to by the files
+ * pointed to in the <code>dataFiles</code> array.
+ */
+ private static final String[][] getDataFileArrays(File[] dataFiles) throws IOException {
+ // Create file readers to process the data files.
+ FileReader[] fr = new FileReader[dataFiles.length];
+ BufferedReader[] reader = new BufferedReader[dataFiles.length];
+ for(int i = 0; i < dataFiles.length; i++) {
+ fr[i] = new FileReader(dataFiles[i]);
+ reader[i] = new BufferedReader(fr[i]);
+ }
+
+ // Generate String arrays where each entry in the array is
+ // a line from the data file.
+ String[][] data = new String[dataFiles.length][0];
+ for(int i = 0; i < dataFiles.length; i++) {
+ // Create a list to hold the raw strings.
+ List<String> rawData = new ArrayList<String>();
+
+ // Add each line from the current data file to the list
+ // as a single entry.
+ String curLine = null;
+ while((curLine = reader[i].readLine()) != null) {
+ rawData.add(curLine);
+ }
+
+ // Convert the list into a String array.
+ data[i] = rawData.toArray(new String[rawData.size()]);
+ }
+
+ // Return the data array.
+ return data;
+ }
+
+ /**
+ * Sets the run number of the DAQ configuration being processed.
+ * This is only used when reading from data files.
+ * @param run - The run number of the data files to be used.
+ */
+ public void setRunNumber(int run) {
+ runNumber = run;
+ }
+
+ /**
+ * Sets the location of the DAQ configuration data files. This is
+ * only used when reading from the data files.
+ * @param filepath - The file path of the data file repository.
+ */
+ public void setDataFileRepository(String filepath) {
+ this.filepath = filepath;
+ }
+
+ /**
+ * Sets whether or not to read the DAQ configuration directly from
+ * the EvIO data stream or whether to read the configuration from
+ * data files. Parameters <code>runNumber</code> and <code>filepath</code>
+ * must also be defined if this is set to <code>true</code>.
+ * @param state - <code>true</code> indicates that the configuration
+ * should be read from data files, and <code>false</code> that it
+ * should be read from the EvIO stream.
+ */
+ public void setReadDataFiles(boolean state) {
+ readDataFiles = state;
}
}
|