Author: [log in to unmask]
Date: Fri Jul 17 16:50:54 2015
New Revision: 3265
Log:
Rework of conditions tagging. Multiple tags on conditions records now supported. Using more than one tag at a time is supported too. Simplify the tag command line interface (it is much simpler now). Some other small fixes and changes. HPSJAVA-517
Added:
java/branches/conditions-HPSJAVA-517/src/main/java/org/hps/conditions/api/ConditionsTag.java
java/branches/conditions-HPSJAVA-517/src/main/java/org/hps/conditions/database/ConditionsTagConverter.java
java/branches/conditions-HPSJAVA-517/src/test/java/org/hps/conditions/api/ConditionsTagTest.java
Modified:
java/branches/conditions-HPSJAVA-517/ (props changed)
java/branches/conditions-HPSJAVA-517/pom.xml
java/branches/conditions-HPSJAVA-517/src/main/java/org/hps/conditions/ConditionsDriver.java
java/branches/conditions-HPSJAVA-517/src/main/java/org/hps/conditions/api/ConditionsRecord.java
java/branches/conditions-HPSJAVA-517/src/main/java/org/hps/conditions/api/TableMetaData.java
java/branches/conditions-HPSJAVA-517/src/main/java/org/hps/conditions/cli/AbstractCommand.java
java/branches/conditions-HPSJAVA-517/src/main/java/org/hps/conditions/cli/AddCommand.java
java/branches/conditions-HPSJAVA-517/src/main/java/org/hps/conditions/cli/CommandLineTool.java
java/branches/conditions-HPSJAVA-517/src/main/java/org/hps/conditions/cli/TagCommand.java
java/branches/conditions-HPSJAVA-517/src/main/java/org/hps/conditions/database/DatabaseConditionsManager.java
java/branches/conditions-HPSJAVA-517/src/main/java/org/hps/conditions/ecal/EcalPulseWidth.java
java/branches/conditions-HPSJAVA-517/src/test/java/org/hps/conditions/EngRunConditionsTest.java
Modified: java/branches/conditions-HPSJAVA-517/pom.xml
=============================================================================
--- java/branches/conditions-HPSJAVA-517/pom.xml (original)
+++ java/branches/conditions-HPSJAVA-517/pom.xml Fri Jul 17 16:50:54 2015
@@ -38,6 +38,7 @@
<exclude>org/hps/conditions/ecal/EcalHardwareConditionsTest.java</exclude>
<exclude>org/hps/conditions/database/CollectionIdTest.java</exclude>
<exclude>org/hps/conditions/svt/SvtTimingConstantsTest.java</exclude>
+ <exclude>org/hps/conditions/api/ConditionsTagTest.java</exclude>
<exclude>org/hps/conditions/dummy/**.java</exclude>
</excludes>
</configuration>
Modified: java/branches/conditions-HPSJAVA-517/src/main/java/org/hps/conditions/ConditionsDriver.java
=============================================================================
--- java/branches/conditions-HPSJAVA-517/src/main/java/org/hps/conditions/ConditionsDriver.java (original)
+++ java/branches/conditions-HPSJAVA-517/src/main/java/org/hps/conditions/ConditionsDriver.java Fri Jul 17 16:50:54 2015
@@ -75,7 +75,7 @@
if (this.tag != null) {
// Set a tag for filtering ConditionsRecord objects.
- conditionsManager.setTag(this.tag);
+ conditionsManager.addTag(this.tag);
}
if (this.detectorName != null) {
// The manager can only be initialized here if there is a user supplied detector name.
Modified: java/branches/conditions-HPSJAVA-517/src/main/java/org/hps/conditions/api/ConditionsRecord.java
=============================================================================
--- java/branches/conditions-HPSJAVA-517/src/main/java/org/hps/conditions/api/ConditionsRecord.java (original)
+++ java/branches/conditions-HPSJAVA-517/src/main/java/org/hps/conditions/api/ConditionsRecord.java Fri Jul 17 16:50:54 2015
@@ -358,9 +358,11 @@
/**
* Get the string tag associated with these conditions.
*
+ * @deprecated Use the {@link ConditionsTag} class instead.
* @return The string tag.
*/
@Field(names = {"tag"})
+ @Deprecated
public String getTag() {
return this.getFieldValue("tag");
}
Added: java/branches/conditions-HPSJAVA-517/src/main/java/org/hps/conditions/api/ConditionsTag.java
=============================================================================
--- java/branches/conditions-HPSJAVA-517/src/main/java/org/hps/conditions/api/ConditionsTag.java (added)
+++ java/branches/conditions-HPSJAVA-517/src/main/java/org/hps/conditions/api/ConditionsTag.java Fri Jul 17 16:50:54 2015
@@ -0,0 +1,101 @@
+package org.hps.conditions.api;
+
+import org.hps.conditions.api.ConditionsRecord.ConditionsRecordCollection;
+import org.hps.conditions.database.ConditionsTagConverter;
+import org.hps.conditions.database.Converter;
+import org.hps.conditions.database.Field;
+import org.hps.conditions.database.Table;
+
+/**
+ * Conditions tag specifying a set of grouped {@link ConditionsRecord} objects by their row IDs in the database along
+ * with a tag name.
+ * <p>
+ * The run numbers of conditions in the tag with the same key are allowed to overlap. In this case, the
+ * disambiguation is performed at run-time within the job using a {@link org.hps.conditions.database.MultipleCollectionsAction}.
+ *
+ * @author Jeremy McCormick, SLAC
+ */
+@Table(names = {"conditions_tags"})
+@Converter(converter = ConditionsTagConverter.class)
+public final class ConditionsTag extends BaseConditionsObject {
+
+ static {
+ /*
+ * HACK: Remove collection_id from the list of fields; it is defined by the BaseConditionsObject super-class
+ * but not defined in this class's table schema.
+ */
+ TableRegistry.getTableRegistry().findByObjectType(ConditionsTag.class).get(0).removeField("collection_id");
+ }
+
+ /**
+ * Collection of tag records.
+ */
+ public static final class ConditionsTagCollection extends BaseConditionsObjectCollection<ConditionsTag> {
+
+ /**
+ * Return <code>true</code> if the collection contains this conditions record (it is in the tag).
+ *
+ * @param conditionsRecord the conditions record
+ * @return <code>true</code> if the collection contains this conditions record
+ */
+ public boolean contains(final ConditionsRecord conditionsRecord) {
+ for (final ConditionsTag tagRecord : this.getObjects()) {
+ if (tagRecord.getConditionsId().equals(conditionsRecord.getRowId())) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Return a new filtered collection containing only those records that are referenced by this tag.
+ *
+ * @param conditionsRecordCollection the conditions records to filter
+ * @return the filtered collection
+ */
+ public ConditionsRecordCollection filter(final ConditionsRecordCollection conditionsRecordCollection) {
+ final ConditionsRecordCollection tagConditionsRecordCollection = new ConditionsRecordCollection();
+ for (final ConditionsRecord record : conditionsRecordCollection) {
+ if (this.contains(record)) {
+ try {
+ tagConditionsRecordCollection.add(record);
+ } catch (final ConditionsObjectException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+ return tagConditionsRecordCollection;
+ }
+ }
+
+ /**
+ * Create a conditions tag record.
+ *
+ * @param conditionsId the referenced conditions record
+ * @param tag the tag name
+ */
+ public ConditionsTag(final int conditionsId, final String tag) {
+ this.setFieldValue("conditions_id", conditionsId);
+ this.setFieldValue("tag", tag);
+ }
+
+ /**
+ * Get the ID of the referenced conditions record.
+ *
+ * @return the ID of the referenced conditions record
+ */
+ @Field(names = {"conditions_id"})
+ public Integer getConditionsId() {
+ return this.getFieldValue("conditions_id");
+ }
+
+ /**
+ * Get the tag name.
+ *
+ * @return the tag name
+ */
+ @Field(names = {"tag"})
+ public String getTag() {
+ return this.getFieldValue("tag");
+ }
+}
Modified: java/branches/conditions-HPSJAVA-517/src/main/java/org/hps/conditions/api/TableMetaData.java
=============================================================================
--- java/branches/conditions-HPSJAVA-517/src/main/java/org/hps/conditions/api/TableMetaData.java (original)
+++ java/branches/conditions-HPSJAVA-517/src/main/java/org/hps/conditions/api/TableMetaData.java Fri Jul 17 16:50:54 2015
@@ -262,9 +262,16 @@
buff.append('\n');
return buff.toString();
}
-
- // TODO: add methods for getting SQL strings for PreparedStatements; can be setup once at initialization time for
- // each table
+
+ /**
+ * Method for removing a field that was found using the automatic introspection methods.
+ */
+ void removeField(String fieldName) {
+ fieldNames.remove(fieldName);
+ fieldTypes.remove(fieldName);
+ }
+
+ // TODO: add methods for getting SQL strings for PreparedStatements; can be setup once at initialization time for each table
// String getSelectStatement();
// String getInsertStatement();
// String getUpdateStatement();
Modified: java/branches/conditions-HPSJAVA-517/src/main/java/org/hps/conditions/cli/AbstractCommand.java
=============================================================================
--- java/branches/conditions-HPSJAVA-517/src/main/java/org/hps/conditions/cli/AbstractCommand.java (original)
+++ java/branches/conditions-HPSJAVA-517/src/main/java/org/hps/conditions/cli/AbstractCommand.java Fri Jul 17 16:50:54 2015
@@ -6,6 +6,7 @@
import org.apache.commons.cli.ParseException;
import org.apache.commons.cli.Parser;
import org.apache.commons.cli.PosixParser;
+import org.hps.conditions.database.DatabaseConditionsManager;
/**
* This is the API that sub-commands such as 'load' or 'print' must implement in the conditions command line interface.
@@ -108,4 +109,12 @@
final HelpFormatter help = new HelpFormatter();
help.printHelp(this.getName(), this.getOptions());
}
+
+ /**
+ * Convenience method for getting the conditions manager.
+ * @return the conditions manager
+ */
+ public DatabaseConditionsManager getManager() {
+ return DatabaseConditionsManager.getInstance();
+ }
}
Modified: java/branches/conditions-HPSJAVA-517/src/main/java/org/hps/conditions/cli/AddCommand.java
=============================================================================
--- java/branches/conditions-HPSJAVA-517/src/main/java/org/hps/conditions/cli/AddCommand.java (original)
+++ java/branches/conditions-HPSJAVA-517/src/main/java/org/hps/conditions/cli/AddCommand.java Fri Jul 17 16:50:54 2015
@@ -41,7 +41,6 @@
OPTIONS.getOption("t").setRequired(true);
OPTIONS.addOption("c", true, "collection ID (required)");
OPTIONS.getOption("c").setRequired(true);
- OPTIONS.addOption("T", true, "tag value (optional)");
OPTIONS.addOption("u", true, "user name (optional)");
OPTIONS.addOption("m", true, "notes about this conditions set (optional)");
}
@@ -67,7 +66,7 @@
* @return the new conditions record
*/
private ConditionsRecord createConditionsRecord(final int runStart, final int runEnd, final String tableName,
- final String name, final int collectionId, final String createdBy, final String tag, final String notes) {
+ final String name, final int collectionId, final String createdBy, final String notes) {
final ConditionsRecord conditionsRecord = new ConditionsRecord();
final FieldValuesMap fieldValues = new FieldValuesMap();
fieldValues.setValue("run_start", runStart);
@@ -76,9 +75,6 @@
fieldValues.setValue("name", name);
fieldValues.setValue("collection_id", collectionId);
fieldValues.setValue("created_by", createdBy);
- if (tag != null) {
- fieldValues.setValue("tag", tag);
- }
if (notes != null) {
fieldValues.setValue("notes", notes);
}
@@ -134,12 +130,6 @@
createdBy = commandLine.getOptionValue("u");
}
- // Tag to assign (optional).
- String tag = null;
- if (commandLine.hasOption("T")) {
- tag = commandLine.getOptionValue("T");
- }
-
// Notes (optional).
String notes = null;
if (commandLine.hasOption("m")) {
@@ -148,7 +138,7 @@
// Create the conditions record to insert.
final ConditionsRecord conditionsRecord = this.createConditionsRecord(runStart, runEnd, tableName, name,
- collectionId, createdBy, tag, notes);
+ collectionId, createdBy, notes);
LOGGER.info("inserting conditions record ..." + '\n' + conditionsRecord);
try {
boolean createdConnection = false;
Modified: java/branches/conditions-HPSJAVA-517/src/main/java/org/hps/conditions/cli/CommandLineTool.java
=============================================================================
--- java/branches/conditions-HPSJAVA-517/src/main/java/org/hps/conditions/cli/CommandLineTool.java (original)
+++ java/branches/conditions-HPSJAVA-517/src/main/java/org/hps/conditions/cli/CommandLineTool.java Fri Jul 17 16:50:54 2015
@@ -202,7 +202,7 @@
// User specified tag of conditions records.
if (commandLine.hasOption("t")) {
final String tag = commandLine.getOptionValue("t");
- this.conditionsManager.setTag(tag);
+ this.conditionsManager.addTag(tag);
LOGGER.config("using tag " + tag);
}
Modified: java/branches/conditions-HPSJAVA-517/src/main/java/org/hps/conditions/cli/TagCommand.java
=============================================================================
--- java/branches/conditions-HPSJAVA-517/src/main/java/org/hps/conditions/cli/TagCommand.java (original)
+++ java/branches/conditions-HPSJAVA-517/src/main/java/org/hps/conditions/cli/TagCommand.java Fri Jul 17 16:50:54 2015
@@ -1,9 +1,9 @@
package org.hps.conditions.cli;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
import java.sql.SQLException;
-import java.util.HashSet;
-import java.util.LinkedHashSet;
-import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -12,54 +12,81 @@
import org.apache.commons.cli.Options;
import org.hps.conditions.api.ConditionsObjectException;
import org.hps.conditions.api.ConditionsRecord;
-import org.hps.conditions.api.TableRegistry;
import org.hps.conditions.api.ConditionsRecord.ConditionsRecordCollection;
+import org.hps.conditions.api.ConditionsTag;
+import org.hps.conditions.api.ConditionsTag.ConditionsTagCollection;
import org.hps.conditions.api.DatabaseObjectException;
import org.hps.conditions.api.TableMetaData;
-import org.hps.conditions.database.DatabaseConditionsManager;
-import org.lcsim.conditions.ConditionsManager.ConditionsNotFoundException;
+import org.hps.conditions.api.TableRegistry;
+import org.hps.conditions.database.MultipleCollectionsAction;
+import org.lcsim.util.log.DefaultLogFormatter;
import org.lcsim.util.log.LogUtil;
/**
* Create a conditions system tag.
+ * <p>
+ * The tag groups together conditions records from the <i>conditions</i> database table with a run validity range that
+ * is between a specified starting and ending run.
+ * <p>
+ * Tagging will not disambiguate overlapping conditions, which is done at run-time based on the current run number.
*
* @author Jeremy McCormick, SLAC
*/
-public class TagCommand extends AbstractCommand {
-
- /**
- * The default detector name (dummy detector).
- */
- private static final String DETECTOR_NAME = "HPS-dummy-detector";
-
- /**
- * Setup logger.
- */
- private static final Logger LOGGER = LogUtil.create(TagCommand.class);
-
+final class TagCommand extends AbstractCommand {
+
+ /**
+ * Setup the logger.
+ */
+ private static final Logger LOGGER = LogUtil.create(TagCommand.class, new DefaultLogFormatter(), Level.ALL);
+
/**
* Defines command options.
*/
private static Options OPTIONS = new Options();
/**
- * Define command options.
+ * Define all command options.
*/
static {
OPTIONS.addOption(new Option("h", false, "Show help for tag command"));
- OPTIONS.addOption(new Option("r", true, "List of run numbers to scan (at least one must be provided)"));
- OPTIONS.getOption("r").setArgs(Option.UNLIMITED_VALUES);
- OPTIONS.getOption("r").setRequired(true);
- OPTIONS.addOption(new Option("t", true, "The new conditions tag"));
+ OPTIONS.addOption(new Option("t", true, "Conditions tag name"));
+ OPTIONS.addOption(new Option("s", true, "Starting run number (required)"));
+ OPTIONS.getOption("s").setRequired(true);
+ OPTIONS.addOption(new Option("e", true, "Ending run number (default is unlimited)"));
OPTIONS.getOption("t").setRequired(true);
- OPTIONS.addOption(new Option("f", false, "Don't prompt before making tag (careful!)"));
+ OPTIONS.addOption(new Option("m", true,
+ "MultipleCollectionsAction to use for disambiguation (default is LAST_CREATED)"));
+ OPTIONS.addOption(new Option("d", false, "Don't prompt before making tag (be careful!)"));
}
/**
* Class constructor.
*/
TagCommand() {
- super("tag", "Tag a set of collections by copying their conditions records", OPTIONS);
+ super("tag", "Tag a set of conditions records to group them together", OPTIONS);
+ }
+
+ /**
+ * Create the collection with the records for creating a new conditions "tag".
+ *
+ * @param tagConditionsRecordCollection the tag record collection
+ * @param tagName the tag name
+ * @return the tag record collection
+ */
+ private ConditionsTagCollection createConditionsTagCollection(
+ final ConditionsRecordCollection tagConditionsRecordCollection, final String tagName) {
+ final ConditionsTagCollection conditionsTagCollection = new ConditionsTagCollection();
+ conditionsTagCollection.setConnection(this.getManager().getConnection());
+ conditionsTagCollection.setTableMetaData(TableRegistry.getTableRegistry().findByTableName("conditions_tags"));
+ for (final ConditionsRecord conditionsRecord : tagConditionsRecordCollection) {
+ final ConditionsTag conditionsTag = new ConditionsTag(conditionsRecord.getRowId(), tagName);
+ try {
+ conditionsTagCollection.add(conditionsTag);
+ } catch (final ConditionsObjectException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ return conditionsTagCollection;
}
/**
@@ -70,108 +97,154 @@
final CommandLine commandLine = this.parse(arguments);
- final Set<Integer> runNumbers = new LinkedHashSet<Integer>();
- if (commandLine.getOptionValues("r") == null) {
- throw new RuntimeException("Missing -r argument with list of run numbers.");
- }
- for (final String value : commandLine.getOptionValues("r")) {
- runNumbers.add(Integer.parseInt(value));
- }
- if (runNumbers.size() == 0) {
- throw new RuntimeException("At least one run number must be provided with the -r switch.");
- }
-
- final String newTag;
+ // New tag name.
+ final String tagName;
if (commandLine.hasOption("t")) {
- newTag = commandLine.getOptionValue("t");
+ tagName = commandLine.getOptionValue("t");
+ LOGGER.info("tag name set to " + tagName);
} else {
throw new RuntimeException("Missing required -t argument with the tag name.");
}
- boolean dontPrompt = false;
- if (commandLine.hasOption("f")) {
- dontPrompt = true;
- }
-
- final ConditionsRecordCollection tagRecords = new ConditionsRecordCollection();
- final Set<Integer> addedIds = new HashSet<Integer>();
-
- final DatabaseConditionsManager manager = DatabaseConditionsManager.getInstance();
- manager.setXmlConfig("/org/hps/conditions/config/conditions_database_no_svt.xml");
- manager.setLogLevel(Level.ALL);
-
- // Scan through all the runs between the start and end run, inclusive.
- for (final Integer run : runNumbers) {
- try {
- // Setup the conditions manager with the run number.
- manager.setDetector(TagCommand.DETECTOR_NAME, run);
- } catch (final ConditionsNotFoundException e) {
- throw new RuntimeException(e);
- }
-
- // The unique conditions keys from this run.
- final Set<String> keys = manager.getConditionsRecords().getConditionsKeys();
-
- // Scan through all the unique keys.
- for (final String key : keys) {
-
- // Get the table meta data for the key.
- final TableMetaData tableMetaData = manager.findTableMetaData(key);
-
- // Get the ConditionsRecord from the collection.
- final ConditionsRecordCollection records = manager.findConditionsRecords(key);
- records.sortByUpdated();
- final ConditionsRecord record = records.get(records.size() - 1);
-
- manager.getCachedConditions(tableMetaData.getCollectionClass(), tableMetaData.getTableName())
- .getCachedData();
-
- // Is this record already part of the new tag?
- if (!addedIds.contains(record.getRowId())) {
- // Create a new record copied from the old one.
- final ConditionsRecord newRecord = new ConditionsRecord(record);
-
- // Set the tag value.
- newRecord.setFieldValue("tag", newTag);
-
- // Add the record to the tag.
- try {
- tagRecords.add(newRecord);
- } catch (final ConditionsObjectException e) {
- throw new RuntimeException(e);
- }
-
- // Flag the record's ID as used so it is only added once.
- addedIds.add(record.getRowId());
- }
- }
- }
-
- // Print out all the records that were found.
- LOGGER.info("found ConditionsRecords for tag " + newTag + " ...");
- for (final ConditionsRecord record : tagRecords) {
- LOGGER.info(record.toString());
- }
-
- // Prompt user to verify with console input.
- boolean makeTag = true;
- if (!dontPrompt) {
- LOGGER.info("Create conditions tag " + newTag + " in database? (Y/N)");
+ // Starting run number (required).
+ int runStart = -1;
+ if (commandLine.hasOption("s")) {
+ runStart = Integer.parseInt(commandLine.getOptionValue("s"));
+ LOGGER.config("run start set to " + runStart);
+ } else {
+ throw new RuntimeException("missing require -s argument with starting run number");
+ }
+
+ // Ending run number (max integer is default).
+ int runEnd = Integer.MAX_VALUE;
+ if (commandLine.hasOption("e")) {
+ runEnd = Integer.parseInt(commandLine.getOptionValue("e"));
+ LOGGER.config("run end set to " + runEnd);
+ }
+
+ // Run end must be greater than or equal to run start.
+ if (runEnd < runStart) {
+ throw new IllegalArgumentException("runEnd < runStart");
+ }
+
+ // Action for disambiguating overlapping collections (default is to use the most recent creation date).
+ MultipleCollectionsAction multipleCollectionsAction = MultipleCollectionsAction.LAST_CREATED;
+ if (commandLine.hasOption("m")) {
+ multipleCollectionsAction = MultipleCollectionsAction
+ .valueOf(commandLine.getOptionValue("m").toUpperCase());
+ }
+ LOGGER.config("multiple collections action set tco " + multipleCollectionsAction);
+
+ // Whether to prompt before tagging (default is yes).
+ boolean promptBeforeTagging = true;
+ if (commandLine.hasOption("d")) {
+ promptBeforeTagging = false;
+ }
+ LOGGER.config("prompt before tagging: " + promptBeforeTagging);
+
+ // Conditions system configuration.
+ this.getManager().setXmlConfig("/org/hps/conditions/config/conditions_database_no_svt.xml");
+ this.getManager().setLogLevel(Level.ALL);
+
+ // Find all the applicable conditions records by their run number ranges.
+ ConditionsRecordCollection tagConditionsRecordCollection = this.findConditionsRecords(runStart, runEnd);
+
+ LOGGER.info("found " + tagConditionsRecordCollection.size() + " conditions records for the tag");
+
+ // Build the collection of tag records to insert into the database.
+ final ConditionsTagCollection conditionsTagCollection = this.createConditionsTagCollection(
+ tagConditionsRecordCollection, tagName);
+
+ LOGGER.info("created " + conditionsTagCollection.size() + " tag records ..." + '\n' + conditionsTagCollection);
+
+ LOGGER.getHandlers()[0].flush();
+
+ // Prompt user to verify tag creation.
+ boolean createTag = true;
+ if (promptBeforeTagging) {
+ System.out.println("Create conditions tag '" + tagName + "' in the database? (Y/N)");
final String line = System.console().readLine();
if (!line.equals("Y")) {
- makeTag = false;
- }
- }
-
- // Create the tag in the database if user verified or force option was present.
- if (makeTag) {
+ createTag = false;
+ }
+ }
+
+ // Create the tag.
+ if (createTag) {
try {
- tagRecords.setConnection(manager.getConnection());
- tagRecords.setTableMetaData(TableRegistry.getTableRegistry().findByTableName("conditions"));
- tagRecords.insert();
+ LOGGER.info("creating tag " + tagName + " in the database ...");
+ conditionsTagCollection.insert();
} catch (DatabaseObjectException | SQLException e) {
throw new RuntimeException(e);
}
- }
+ } else {
+ LOGGER.warning("user aborted tag operation!");
+ }
+
+ LOGGER.info("done!");
+ }
+
+ /**
+ * Find all the conditions records that are applicable for the given run range.
+ * <p>
+ * Overlapping run numbers in conditions with the same key are not disambiguated.
+ * This must be done in the user's job at runtime; usually the most recently created
+ * conditions record will be used if multiple one's are applicable to the current run.
+ *
+ * @param runStart the start run
+ * @param runEnd the end run (must be greater than or equal to <code>runStart</code>)
+ * @return the conditions records that fall in the run range
+ */
+ private ConditionsRecordCollection findConditionsRecords(final int runStart, final int runEnd) {
+ if (runStart > runEnd) {
+ throw new IllegalArgumentException("runStart > runEnd");
+ }
+ if (runStart < 0) {
+ throw new IllegalArgumentException("invalid runStart: " + runStart);
+ }
+ if (runEnd < 0) {
+ throw new IllegalArgumentException("invalid runEnd: " + runEnd);
+ }
+ final Connection connection = this.getManager().getConnection();
+ final ConditionsRecordCollection conditionsRecordCollection = new ConditionsRecordCollection();
+ final TableMetaData tableMetaData = TableRegistry.getTableRegistry().findByTableName("conditions");
+ PreparedStatement statement = null;
+ try {
+ /*
+ * SQL statement handles 3 cases:
+ * 1) condition's run_start in range
+ * 2) condition's run_end in range
+ * 3) condition's run_start and run_end enclose the range
+ */
+ statement = connection
+ .prepareStatement("SELECT id FROM conditions WHERE (run_start >= ? and run_start <= ?) or (run_end >= ? and run_end <= ?)"
+ + " or (run_start <= ? and run_end >= ?)");
+ statement.setInt(1, runStart);
+ statement.setInt(2, runEnd);
+ statement.setInt(3, runStart);
+ statement.setInt(4, runEnd);
+ statement.setInt(5, runStart);
+ statement.setInt(6, runEnd);
+
+ final ResultSet resultSet = statement.executeQuery();
+ while (resultSet.next()) {
+ final ConditionsRecord record = new ConditionsRecord();
+ record.setConnection(connection);
+ record.setTableMetaData(tableMetaData);
+ record.select(resultSet.getInt(1));
+ conditionsRecordCollection.add(record);
+ }
+ } catch (DatabaseObjectException | ConditionsObjectException | SQLException e) {
+ throw new RuntimeException(e);
+ } finally {
+ try {
+ if (statement != null) {
+ statement.close();
+ }
+ } catch (final SQLException e) {
+ e.printStackTrace();
+ }
+ }
+ return conditionsRecordCollection;
}
}
Added: java/branches/conditions-HPSJAVA-517/src/main/java/org/hps/conditions/database/ConditionsTagConverter.java
=============================================================================
--- java/branches/conditions-HPSJAVA-517/src/main/java/org/hps/conditions/database/ConditionsTagConverter.java (added)
+++ java/branches/conditions-HPSJAVA-517/src/main/java/org/hps/conditions/database/ConditionsTagConverter.java Fri Jul 17 16:50:54 2015
@@ -0,0 +1,78 @@
+package org.hps.conditions.database;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+import org.hps.conditions.api.AbstractConditionsObjectConverter;
+import org.hps.conditions.api.ConditionsObjectException;
+import org.hps.conditions.api.ConditionsTag;
+import org.hps.conditions.api.ConditionsTag.ConditionsTagCollection;
+import org.lcsim.conditions.ConditionsManager;
+
+/**
+ * Convert records in the <i>conditions_tags</i> table to a conditions object collection.
+ *
+ * @author Jeremy McCormick, SLAC
+ */
+public class ConditionsTagConverter extends AbstractConditionsObjectConverter<ConditionsTagCollection> {
+
+ /**
+ * SQL SELECT string.
+ */
+ private static final String SELECT_SQL = "SELECT conditions_id, tag from conditions_tags where tag = ?";
+
+ /**
+ * Get a {@link org.hps.conditions.api.ConditionsTagCollection} which specifies a group of collections
+ * that are tagged in the <i>conditions_tags</i> table in the database.
+ * <p>
+ * The run number is not used, and the <code>name</code> argument specifies the tag name.
+ *
+ * @param manager The current conditions manager.
+ * @param name The name of the conditions set.
+ * @return The matching ConditionsRecords.
+ */
+ @Override
+ public ConditionsTagCollection getData(final ConditionsManager manager, final String name) {
+
+ ConditionsTagCollection conditionsTagCollection = new ConditionsTagCollection();
+ DatabaseConditionsManager dbConditionsManager = DatabaseConditionsManager.class.cast(manager);
+ if (dbConditionsManager == null) {
+ throw new IllegalArgumentException("The conditions manager has the wrong type.");
+ }
+ boolean openedConnection = dbConditionsManager.openConnection();
+ Connection connection = DatabaseConditionsManager.getInstance().getConnection();
+ try {
+ PreparedStatement statement = connection.prepareStatement(SELECT_SQL);
+ statement.setString(1, name);
+ ResultSet resultSet = statement.executeQuery();
+ while (resultSet.next()) {
+ Integer conditionsId = resultSet.getInt(1);
+ String tag = resultSet.getString(2);
+ ConditionsTag record = new ConditionsTag(conditionsId, tag);
+ conditionsTagCollection.add(record);
+ }
+ } catch (SQLException e) {
+ throw new RuntimeException(e);
+ } catch (ConditionsObjectException e) {
+ throw new RuntimeException(e);
+ } finally {
+ dbConditionsManager.closeConnection(openedConnection);
+ }
+ if (conditionsTagCollection.size() == 0) {
+ throw new IllegalArgumentException("The conditions tag " + name + " does not exist in the database.");
+ }
+ return conditionsTagCollection;
+ }
+
+ /**
+ * Get the type handled by this converter.
+ *
+ * @return The type handled by this converter, which is <code>ConditionsRecordCollection</code>.
+ */
+ @Override
+ public Class<ConditionsTagCollection> getType() {
+ return ConditionsTagCollection.class;
+ }
+}
Modified: java/branches/conditions-HPSJAVA-517/src/main/java/org/hps/conditions/database/DatabaseConditionsManager.java
=============================================================================
--- java/branches/conditions-HPSJAVA-517/src/main/java/org/hps/conditions/database/DatabaseConditionsManager.java (original)
+++ java/branches/conditions-HPSJAVA-517/src/main/java/org/hps/conditions/database/DatabaseConditionsManager.java Fri Jul 17 16:50:54 2015
@@ -12,6 +12,7 @@
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
+import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
@@ -21,10 +22,10 @@
import org.hps.conditions.api.AbstractConditionsObjectConverter;
import org.hps.conditions.api.ConditionsObject;
import org.hps.conditions.api.ConditionsObjectCollection;
-import org.hps.conditions.api.ConditionsObjectException;
import org.hps.conditions.api.ConditionsRecord;
import org.hps.conditions.api.ConditionsRecord.ConditionsRecordCollection;
import org.hps.conditions.api.ConditionsSeries;
+import org.hps.conditions.api.ConditionsTag.ConditionsTagCollection;
import org.hps.conditions.api.TableMetaData;
import org.hps.conditions.api.TableRegistry;
import org.hps.conditions.ecal.EcalConditions;
@@ -259,10 +260,20 @@
private final TableRegistry tableRegistry = TableRegistry.getTableRegistry();
/**
- * The currently active conditions tag.
- */
- private String tag = null;
-
+ * The currently active conditions tag (empty collection means no tag is active).
+ */
+ private ConditionsTagCollection conditionsTagCollection = new ConditionsTagCollection();
+
+ /**
+ * The current set of conditions for the run.
+ */
+ private ConditionsRecordCollection conditionsRecordCollection = null;
+
+ /**
+ * The currently applied conditions tags.
+ */
+ private Set<String> tags = new HashSet<String>();
+
/**
* Class constructor. Calling this will automatically register this manager as the global default.
*/
@@ -382,27 +393,7 @@
* @return the set of matching conditions records
*/
public ConditionsRecordCollection findConditionsRecords(final String name) {
- final ConditionsRecordCollection runConditionsRecords = this.getCachedConditions(
- ConditionsRecordCollection.class, "conditions").getCachedData();
- logger.fine("searching for conditions with name " + name + " in " + runConditionsRecords.size() + " records");
- final ConditionsRecordCollection foundConditionsRecords = new ConditionsRecordCollection();
- for (final ConditionsRecord record : runConditionsRecords) {
- if (record.getName().equals(name)) {
- if (this.matchesTag(record)) {
- try {
- foundConditionsRecords.add(record);
- } catch (final ConditionsObjectException e) {
- throw new RuntimeException(e);
- }
- logger.finer("found matching conditions record " + record.getRowId());
- } else {
- logger.finer("conditions record " + record.getRowId() + " rejected from non-matching tag "
- + record.getTag());
- }
- }
- }
- logger.fine("found " + foundConditionsRecords.size() + " conditions records matching tag " + this.tag);
- return foundConditionsRecords;
+ return getConditionsRecords().findByKey(name);
}
/**
@@ -483,31 +474,30 @@
collection.setCollectionId(collectionId);
return collectionId;
}
-
- /**
- * Get a list of all the {@link ConditionsRecord} objects.
- *
- * @return the list of all the {@link ConditionsRecord} objects
- */
- // FIXME: This should use a cache that is created during initialization, rather than look these up every time.
+
+ /**
+ * Get the list of conditions records for the run, filtered by the current set of active tags.
+ *
+ * @return the list of conditions records for the run
+ */
public ConditionsRecordCollection getConditionsRecords() {
- logger.finer("getting conditions records ...");
- final ConditionsRecordCollection conditionsRecords = new ConditionsRecordCollection();
- for (final TableMetaData tableMetaData : this.tableRegistry.values()) {
- try {
- final ConditionsRecordCollection foundConditionsRecords = this.findConditionsRecords(tableMetaData
- .getKey());
- logger.finer("found " + foundConditionsRecords.size() + " collections with name "
- + tableMetaData.getKey());
- conditionsRecords.addAll(foundConditionsRecords);
- } catch (final Exception e) {
- e.printStackTrace();
- logger.warning(e.getMessage());
- }
- }
- logger.finer("found " + conditionsRecords + " conditions records");
- logger.getHandlers()[0].flush();
- return conditionsRecords;
+ if (this.run == -1 || this.detectorName == null) {
+ throw new IllegalStateException("Conditions system is not initialized.");
+ }
+ // If the collection is null then the new conditions records need to be retrieved from the database.
+ if (this.conditionsRecordCollection == null) {
+
+ // Get the collection of conditions that are applicable for the current run.
+ this.conditionsRecordCollection =
+ this.getCachedConditions(ConditionsRecordCollection.class, "conditions").getCachedData();
+
+ // If there is one or more tags enabled then filter the collection by the tag names.
+ if (this.conditionsTagCollection.size() > 0) {
+ this.conditionsRecordCollection =
+ this.conditionsTagCollection.filter(this.conditionsRecordCollection);
+ }
+ }
+ return this.conditionsRecordCollection;
}
/**
@@ -675,11 +665,14 @@
// Open the database connection.
this.openConnection();
-
+
+ // Reset the conditions records to trigger a re-caching.
+ this.conditionsRecordCollection = null;
+
// Call the super class's setDetector method to construct the detector object and activate conditions listeners.
logger.fine("activating default conditions manager");
super.setDetector(detectorName, runNumber);
-
+
// Should all conditions sets be cached?
if (this.cacheAllConditions) {
// Cache the conditions sets of all registered converters.
@@ -811,24 +804,11 @@
}
/**
- * Return <code>true</code> if the conditions record matches the current tag
- *
- * @param record the conditions record
- * @return <code>true</code> if conditions record matches the currently used tag
- */
- private boolean matchesTag(final ConditionsRecord record) {
- if (this.tag == null) {
- // If there is no tag set then all records pass.
- return true;
- }
- final String recordTag = record.getTag();
- if (recordTag == null) {
- // If there is a tag set but the record has no tag, it is rejected.
- return false;
- }
- return this.tag.equals(recordTag);
- }
-
+ * Create a new collection with the given type.
+ *
+ * @param collectionType the collection type
+ * @return the new collection
+ */
public <CollectionType extends ConditionsObjectCollection<?>> CollectionType newCollection(
final Class<CollectionType> collectionType) {
final List<TableMetaData> tableMetaDataList = TableRegistry.getTableRegistry().findByCollectionType(
@@ -849,6 +829,13 @@
return collection;
}
+ /**
+ * Create a new collection with the given type and table name.
+ *
+ * @param collectionType the collection type
+ * @param tableName the table name
+ * @return the new collection
+ */
public <CollectionType extends ConditionsObjectCollection<?>> CollectionType newCollection(
final Class<CollectionType> collectionType, final String tableName) {
final TableMetaData tableMetaData = TableRegistry.getTableRegistry().findByTableName(tableName);
@@ -1044,13 +1031,40 @@
}
/**
- * Set a tag used to filter the accessible conditions records
+ * Add a tag used to filter the accessible conditions records.
+ * <p>
+ * Multiple tags are OR'd together.
*
* @param tag the tag value used to filter returned conditions records
*/
- public void setTag(final String tag) {
- this.tag = tag;
- logger.info("using conditions tag: " + tag);
+ public void addTag(final String tag) {
+ if (!this.tags.contains(tag)) {
+ logger.info("adding tag " + tag);
+ ConditionsTagCollection addConditionsTagCollection = this.getCachedConditions(ConditionsTagCollection.class, tag).getCachedData();
+ logger.info("adding conditions tag " + tag + " with " + conditionsTagCollection.size() + " records");
+ this.conditionsTagCollection.addAll(addConditionsTagCollection);
+ } else {
+ logger.warning("tag " + tag + " is already added");
+ }
+ }
+
+ /**
+ * Add one or more tags for filtering records.
+ *
+ * @param tags the <code>Set</code> of tags to add
+ */
+ public void addTags(final Set<String> tags) {
+ for (String tag : tags) {
+ this.addTag(tag);
+ }
+ }
+
+ /**
+ * Clear the tags used to filter the {@link org.hps.conditons.api.ConditionsRecord}s.
+ */
+ public void clearTags() {
+ this.tags.clear();
+ this.conditionsTagCollection.clear();
}
/**
Modified: java/branches/conditions-HPSJAVA-517/src/main/java/org/hps/conditions/ecal/EcalPulseWidth.java
=============================================================================
--- java/branches/conditions-HPSJAVA-517/src/main/java/org/hps/conditions/ecal/EcalPulseWidth.java (original)
+++ java/branches/conditions-HPSJAVA-517/src/main/java/org/hps/conditions/ecal/EcalPulseWidth.java Fri Jul 17 16:50:54 2015
@@ -34,8 +34,8 @@
* Get the signal pulse width.
* @return the signal pulse width
*/
- @Field(names = {"ecal_pulse_width"})
+ @Field(names = {"pulse_width"})
public Double getPulseWidth() {
- return this.getFieldValue("ecal_pulse_width");
+ return this.getFieldValue("pulse_width");
}
}
Modified: java/branches/conditions-HPSJAVA-517/src/test/java/org/hps/conditions/EngRunConditionsTest.java
=============================================================================
--- java/branches/conditions-HPSJAVA-517/src/test/java/org/hps/conditions/EngRunConditionsTest.java (original)
+++ java/branches/conditions-HPSJAVA-517/src/test/java/org/hps/conditions/EngRunConditionsTest.java Fri Jul 17 16:50:54 2015
@@ -220,7 +220,7 @@
final DatabaseConditionsManager manager = DatabaseConditionsManager.getInstance();
DatabaseConditionsManager.getLogger().setLevel(Level.ALL);
- manager.setTag("pass0");
+ manager.addTag("pass0");
manager.setXmlConfig("/org/hps/conditions/config/conditions_database_engrun.xml");
final FileCache cache = new FileCache();
Added: java/branches/conditions-HPSJAVA-517/src/test/java/org/hps/conditions/api/ConditionsTagTest.java
=============================================================================
--- java/branches/conditions-HPSJAVA-517/src/test/java/org/hps/conditions/api/ConditionsTagTest.java (added)
+++ java/branches/conditions-HPSJAVA-517/src/test/java/org/hps/conditions/api/ConditionsTagTest.java Fri Jul 17 16:50:54 2015
@@ -0,0 +1,119 @@
+package org.hps.conditions.api;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import junit.framework.TestCase;
+
+import org.hps.conditions.api.ConditionsRecord.ConditionsRecordCollection;
+import org.hps.conditions.database.DatabaseConditionsManager;
+import org.hps.conditions.ecal.EcalCalibration.EcalCalibrationCollection;
+import org.hps.conditions.ecal.EcalChannel.EcalChannelCollection;
+import org.hps.conditions.ecal.EcalGain.EcalGainCollection;
+import org.hps.conditions.ecal.EcalTimeShift.EcalTimeShiftCollection;
+import org.hps.conditions.svt.SvtAlignmentConstant.SvtAlignmentConstantCollection;
+import org.hps.conditions.svt.SvtCalibration.SvtCalibrationCollection;
+import org.hps.conditions.svt.SvtChannel.SvtChannelCollection;
+import org.hps.conditions.svt.SvtDaqMapping.SvtDaqMappingCollection;
+import org.hps.conditions.svt.SvtGain.SvtGainCollection;
+import org.hps.conditions.svt.SvtShapeFitParameters.SvtShapeFitParametersCollection;
+import org.hps.conditions.svt.SvtT0Shift.SvtT0ShiftCollection;
+import org.hps.conditions.svt.SvtTimingConstants.SvtTimingConstantsCollection;
+
+public class ConditionsTagTest extends TestCase {
+
+ private static final int[] RUNS = { 5037, 5038, 5066, 5076, 5139, 5149, 5174, 5181, 5200, 5218, 5236, 5251, 5253,
+ 5263, 5299, 5310, 5375, 5388, 5389, 5400, 5404, 5533, 5538, 5558, 5575, 5596, 5601, 5603, 5610, 5623, 5640,
+ 5641, 5642, 5673, 5686, 5711, 5712, 5713, 5714, 5722, 5747, 5748, 5779
+ };
+
+ private static final String[] CONDITIONS = {
+ "ecal_calibrations",
+ "ecal_channels",
+ "ecal_gains",
+ "ecal_time_shifts",
+ "svt_alignments",
+ "svt_calibrations",
+ "svt_channels",
+ "svt_daq_map",
+ "svt_gains",
+ "svt_shape_fit_parameters",
+ "svt_t0_shifts",
+ "svt_timing_constants"
+ };
+
+ private static final Class<?> TYPES[] = {
+ EcalCalibrationCollection.class,
+ EcalChannelCollection.class,
+ EcalGainCollection.class,
+ EcalTimeShiftCollection.class,
+ SvtAlignmentConstantCollection.class,
+ SvtCalibrationCollection.class,
+ SvtChannelCollection.class,
+ SvtDaqMappingCollection.class,
+ SvtGainCollection.class,
+ SvtShapeFitParametersCollection.class,
+ SvtT0ShiftCollection.class,
+ SvtTimingConstantsCollection.class
+ };
+
+ private static DatabaseConditionsManager MANAGER;
+
+ @Override
+ public void setUp() {
+ // Configure the conditions system.
+ MANAGER = DatabaseConditionsManager.getInstance();
+ MANAGER.setConnectionResource("/org/hps/conditions/config/jeremym_dev_connection.prop");
+ MANAGER.setXmlConfig("/org/hps/conditions/config/conditions_database_no_svt.xml");
+ //MANAGER.setLogLevel(Level.WARNING);
+ }
+
+ public void testConditionsTag() throws Exception {
+ MANAGER.addTag("pass1");
+ for (int run : RUNS) {
+ MANAGER.setDetector("HPS-conditions-test", run);
+ ConditionsRecordCollection conditionsRecordCollection = MANAGER.getConditionsRecords();
+ System.out.println("run " + run + " has " + conditionsRecordCollection.size());
+ System.out.println(conditionsRecordCollection);
+ for (int i = 0; i < CONDITIONS.length; i++) {
+ try {
+ BaseConditionsObjectCollection<?> conditionsObjectCollection =
+ BaseConditionsObjectCollection.class.cast(
+ MANAGER.getCachedConditions(TYPES[i], CONDITIONS[i]).getCachedData());
+ System.out.println("got collection " + conditionsObjectCollection.getTableMetaData().getTableName()
+ + " with type " + conditionsObjectCollection.getTableMetaData().getCollectionClass().getName()
+ + " and " + conditionsObjectCollection.size() + " objects");
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+
+ public void testMultipleConditionsTags() throws Exception {
+ Set<String> tags = new HashSet<String>();
+ tags.add("pass1");
+ tags.add("dev");
+ tags.add("eng_run");
+ tags.add("derp");
+
+ for (int run : RUNS) {
+ MANAGER.setDetector("HPS-conditions-test", run);
+ ConditionsRecordCollection conditionsRecordCollection = MANAGER.getConditionsRecords();
+ System.out.println("run " + run + " has " + conditionsRecordCollection.size());
+ System.out.println(conditionsRecordCollection);
+ for (int i = 0; i < CONDITIONS.length; i++) {
+ try {
+ BaseConditionsObjectCollection<?> conditionsObjectCollection =
+ BaseConditionsObjectCollection.class.cast(
+ MANAGER.getCachedConditions(TYPES[i], CONDITIONS[i]).getCachedData());
+ System.out.println("got collection " + conditionsObjectCollection.getTableMetaData().getTableName()
+ + " with type " + conditionsObjectCollection.getTableMetaData().getCollectionClass().getName()
+ + " and " + conditionsObjectCollection.size() + " objects");
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+}
|