Commit in java/trunk/conditions on MAIN
pom.xml+42added 61
src/main/java/org/hps/conditions/ChannelCollection.java+10added 61
                                /ConditionsConstants.java+55added 61
                                /ConditionsConverterRegister.java+76added 61
                                /ConditionsDriver.java+49added 61
                                /ConditionsRecord.java+261added 61
                                /ConditionsRecordCollection.java+26added 61
                                /ConditionsRecordConverter.java+65added 61
                                /ConnectionManager.java+150added 61
                                /ConnectionParameters.java+129added 61
                                /DatabaseConditionsConverter.java+21added 61
                                /DatabaseConditionsReader.java+164added 61
                                /TestRunConditionsReader.java+63added 61
src/main/java/org/hps/conditions/beam/BeamCurrent.java+26added 61
                                     /BeamCurrentConverter.java+72added 61
src/main/java/org/hps/conditions/ecal/EcalBadChannelCollection.java+9added 61
                                     /EcalBadChannelConverter.java+70added 61
                                     /EcalCalibration.java+42added 61
                                     /EcalCalibrationCollection.java+15added 61
                                     /EcalCalibrationConverter.java+76added 61
                                     /EcalChannel.java+122added 61
                                     /EcalChannelConstants.java+69added 61
                                     /EcalChannelMap.java+52added 61
                                     /EcalChannelMapConverter.java+71added 61
                                     /EcalConditions.java+125added 61
                                     /EcalConditionsConverter.java+72added 61
                                     /EcalConditionsLoader.java+67added 61
                                     /EcalGain.java+29added 61
                                     /EcalGainCollection.java+14added 61
                                     /EcalGainConverter.java+74added 61
src/main/java/org/hps/conditions/package-info.java+13added 61
src/main/java/org/hps/conditions/svt/ChannelConstants.java+101added 61
                                    /PulseParameters.java+80added 61
                                    /PulseParametersCollection.java+12added 61
                                    /PulseParametersConverter.java+81added 61
                                    /SvtBadChannelCollection.java+11added 61
                                    /SvtBadChannelConverter.java+69added 61
                                    /SvtCalibration.java+45added 61
                                    /SvtCalibrationCollection.java+16added 61
                                    /SvtCalibrationConverter.java+85added 61
                                    /SvtChannel.java+83added 61
                                    /SvtChannelMap.java+53added 61
                                    /SvtChannelMapConverter.java+65added 61
                                    /SvtConditions.java+171added 61
                                    /SvtConditionsConverter.java+81added 61
                                    /SvtConditionsLoader.java+83added 61
                                    /SvtDaqMap.java+93added 61
                                    /SvtDaqMapConverter.java+81added 61
                                    /SvtGain.java+47added 61
                                    /SvtGainCollection.java+13added 61
                                    /SvtGainConverter.java+77added 61
                                    /SvtTimeShift.java+49added 61
                                    /SvtTimeShiftCollection.java+24added 61
                                    /SvtTimeShiftConverter.java+76added 61
src/test/java/org/hps/conditions/ConditionsDriverTest.java+97added 61
                                /DatabaseConditionsReaderTest.java+46added 61
src/test/java/org/hps/conditions/beam/BeamCurrentTest.java+81added 61
src/test/java/org/hps/conditions/ecal/EcalConditionsConverterTest.java+37added 61
                                     /EcalConditionsLoaderTest.java+111added 61
src/test/java/org/hps/conditions/svt/SvtConditionsConverterTest.java+48added 61
                                    /SvtConditionsLoaderTest.java+119added 61
+4164
61 added files
add conditions module

java/trunk/conditions
pom.xml added at 61
--- java/trunk/conditions/pom.xml	                        (rev 0)
+++ java/trunk/conditions/pom.xml	2013-12-03 21:35:47 UTC (rev 61)
@@ -0,0 +1,42 @@
+<?xml version="1.0"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <artifactId>hps-conditions</artifactId>
+    <groupId>org.hps</groupId>
+    <name>conditions</name>
+    <version>1.0-SNAPSHOT</version>
+    <description>conditions framework</description>
+    <parent>
+        <groupId>org.lcsim</groupId>
+        <artifactId>lcsim-parent</artifactId>
+        <version>3.0-SNAPSHOT</version>
+    </parent>
+    <scm>
+        <connection>scm:svn:svn://svn.freehep.org/hps/java/trunk/conditions</connection>
+        <developerConnection>scm:svn:svn://svn.freehep.org/hps/java/trunk/conditions</developerConnection>
+        <url>http://java.freehep.org/svn/repos/hps/list/java/trunk/conditions/</url>
+    </scm>
+    <dependencies>
+        <dependency>
+            <groupId>org.lcsim</groupId>
+            <artifactId>lcsim-event-processing</artifactId>
+            <version>3.0-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>org.hps</groupId>
+            <artifactId>hps-util</artifactId>
+            <version>1.0-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>org.hps</groupId>
+            <artifactId>hps-detector-data</artifactId>
+            <version>3.0-SNAPSHOT</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-java</artifactId>
+            <version>5.1.26</version>
+        </dependency>
+    </dependencies>
+</project>

java/trunk/conditions/src/main/java/org/hps/conditions
ChannelCollection.java added at 61
--- java/trunk/conditions/src/main/java/org/hps/conditions/ChannelCollection.java	                        (rev 0)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/ChannelCollection.java	2013-12-03 21:35:47 UTC (rev 61)
@@ -0,0 +1,10 @@
+package org.hps.conditions;
+
+import java.util.HashSet;
+
+/**
+ * This class represents a set of channel IDs from the conditions database.
+ * @author Jeremy McCormick <[log in to unmask]>
+ */
+public class ChannelCollection extends HashSet<Integer> {
+}

java/trunk/conditions/src/main/java/org/hps/conditions
ConditionsConstants.java added at 61
--- java/trunk/conditions/src/main/java/org/hps/conditions/ConditionsConstants.java	                        (rev 0)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/ConditionsConstants.java	2013-12-03 21:35:47 UTC (rev 61)
@@ -0,0 +1,55 @@
+package org.hps.conditions;
+
+/**
+ * Constants for HPS conditions system, such as conditions set key names.
+ */
+public final class ConditionsConstants {
+    
+    /** Prevent instantiation of this class, which is only a holder of static constant values. */
+    private ConditionsConstants() {}
+    
+    /** Conditions key for ConditionsRecord. */
+    public static final String CONDITIONS_RECORD = "conditions_record";
+
+    /** Conditions key for combined ECal conditions. */
+    public static final String ECAL_CONDITIONS = "ecal_conditions";
+    
+    /** Table with ECal channel data. */
+    public static final String ECAL_CHANNELS = "ecal_channels";
+
+    /** Conditions key for ECal gain data. */
+    public static final String ECAL_GAINS = "ecal_gains";
+    
+    /** Conditions key for ECal bad channel set. */
+    public static final String ECAL_BAD_CHANNELS = "ecal_bad_channels";
+    
+    /** Conditions key for ECal calibration information. */
+    public static final String ECAL_CALIBRATIONS = "ecal_calibrations";
+    
+    /** Conditions key for combined ECal conditions. */
+    public static final String SVT_CONDITIONS = "svt_conditions";
+    
+    /** Table with SVT channel data. */
+    public static final String SVT_CHANNELS = "svt_channels";
+    
+    /** Table with the SVT DAQ map. */
+    public static final String SVT_DAQ_MAP = "svt_daq_map";
+            
+    /** Conditions key for SVT calibration data. */ 
+    public static final String SVT_CALIBRATIONS = "svt_calibrations";
+    
+    /** Conditions key for SVT bad channels. */
+    public static final String SVT_BAD_CHANNELS = "svt_bad_channels";
+    
+    /** Conditions key for SVT pulse parameters. */
+    public static final String SVT_PULSE_PARAMETERS = "svt_pulse_parameters";
+    
+    /** Conditions key for SVT gain data. */
+    public static final String SVT_GAINS = "svt_gains";
+    
+    /** Conditions key for SVT time shifts by sensor. */
+    public static final String SVT_TIME_SHIFTS = "svt_time_shifts";
+    
+    /** Conditions key for integrated beam current. */
+    public static final String BEAM_CURRENT = "beam_current";
+}

java/trunk/conditions/src/main/java/org/hps/conditions
ConditionsConverterRegister.java added at 61
--- java/trunk/conditions/src/main/java/org/hps/conditions/ConditionsConverterRegister.java	                        (rev 0)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/ConditionsConverterRegister.java	2013-12-03 21:35:47 UTC (rev 61)
@@ -0,0 +1,76 @@
+package org.hps.conditions;
+
+import org.lcsim.conditions.ConditionsManager;
+import org.hps.conditions.beam.BeamCurrentConverter;
+import org.hps.conditions.ecal.EcalBadChannelConverter;
+import org.hps.conditions.ecal.EcalCalibrationConverter;
+import org.hps.conditions.ecal.EcalChannelMapConverter;
+import org.hps.conditions.ecal.EcalConditionsConverter;
+import org.hps.conditions.ecal.EcalGainConverter;
+import org.hps.conditions.svt.PulseParametersConverter;
+import org.hps.conditions.svt.SvtBadChannelConverter;
+import org.hps.conditions.svt.SvtCalibrationConverter;
+import org.hps.conditions.svt.SvtChannelMapConverter;
+import org.hps.conditions.svt.SvtConditionsConverter;
+import org.hps.conditions.svt.SvtDaqMapConverter;
+import org.hps.conditions.svt.SvtGainConverter;
+import org.hps.conditions.svt.SvtTimeShiftConverter;
+
+/**
+ * This class registers the full set of conditions converters onto the manager.
+ * @author Jeremy McCormick <[log in to unmask]>
+ */
+class ConditionsConverterRegister {
+    
+    /**
+     * This method will register all the conditions converters onto the given manager.
+     * @param manager The conditions manager.
+     */
+    static void register(ConditionsManager manager) {
+        
+        // ConditionsRecords with validity meta data.
+        manager.registerConditionsConverter(new ConditionsRecordConverter());
+        
+        // SVT channel map.
+        manager.registerConditionsConverter(new SvtChannelMapConverter());
+        
+        // SVT DAQ map.
+        manager.registerConditionsConverter(new SvtDaqMapConverter());
+        
+        // SVT calibrations.
+        manager.registerConditionsConverter(new SvtCalibrationConverter());
+        
+        // SVT gains.
+        manager.registerConditionsConverter(new SvtGainConverter());
+        
+        // SVT bad channels.
+        manager.registerConditionsConverter(new SvtBadChannelConverter());       
+       
+        // SVT time shift by sensor.
+        manager.registerConditionsConverter(new SvtTimeShiftConverter());
+                
+        // SVT combined conditions.
+        manager.registerConditionsConverter(new SvtConditionsConverter());
+        
+        // ECAL bad channels.
+        manager.registerConditionsConverter(new EcalBadChannelConverter());
+        
+        // ECAL channel map.
+        manager.registerConditionsConverter(new EcalChannelMapConverter());
+        
+        // ECAL gains.
+        manager.registerConditionsConverter(new EcalGainConverter());
+                
+        // ECAL calibrations.
+        manager.registerConditionsConverter(new EcalCalibrationConverter());
+        
+        // ECAL pulse parameters.
+        manager.registerConditionsConverter(new PulseParametersConverter());
+        
+        // ECAL combined conditions.
+        manager.registerConditionsConverter(new EcalConditionsConverter());
+        
+        // Beam current condition.
+        manager.registerConditionsConverter(new BeamCurrentConverter());
+    }
+}

java/trunk/conditions/src/main/java/org/hps/conditions
ConditionsDriver.java added at 61
--- java/trunk/conditions/src/main/java/org/hps/conditions/ConditionsDriver.java	                        (rev 0)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/ConditionsDriver.java	2013-12-03 21:35:47 UTC (rev 61)
@@ -0,0 +1,49 @@
+package org.hps.conditions;
+
+import org.lcsim.conditions.ConditionsManager;
+import org.lcsim.geometry.Detector;
+import org.hps.conditions.ecal.EcalConditions;
+import org.hps.conditions.ecal.EcalConditionsLoader;
+import org.hps.conditions.svt.SvtConditions;
+import org.hps.conditions.svt.SvtConditionsLoader;
+import org.lcsim.util.Driver;
+
+import static org.hps.conditions.ConditionsConstants.SVT_CONDITIONS;
+import static org.hps.conditions.ConditionsConstants.ECAL_CONDITIONS;
+
+/**
+ * This {@link org.lcsim.util.Driver} loads conditions onto an HPS detector.
+ * @author Jeremy McCormick <[log in to unmask]>
+ */
+public class ConditionsDriver extends Driver {
+
+    /**
+     * This method updates a new detector with SVT and ECal conditions data.
+     */
+    public void detectorChanged(Detector detector) {        
+        loadSvtConditions(detector);       
+        loadEcalConditions(detector);
+    }
+    
+    /**
+     * Load the SVT conditions onto the Detector.
+     * @param detector The detector to update.
+     */
+    private void loadSvtConditions(Detector detector) {        
+        ConditionsManager manager = ConditionsManager.defaultInstance();        
+        SvtConditions conditions = manager.getCachedConditions(SvtConditions.class, SVT_CONDITIONS).getCachedData();                   
+        SvtConditionsLoader loader = new SvtConditionsLoader();
+        loader.load(detector, conditions);
+    }    
+    
+    /** 
+     * Load the ECal conditions onto the Detector.
+     * @param detector The detector to update.
+     */ 
+    private void loadEcalConditions(Detector detector) {
+        ConditionsManager manager = ConditionsManager.defaultInstance();
+        EcalConditions conditions = manager.getCachedConditions(EcalConditions.class, ECAL_CONDITIONS).getCachedData();
+        EcalConditionsLoader loader = new EcalConditionsLoader();
+        loader.load(detector, conditions);
+    }
+}

java/trunk/conditions/src/main/java/org/hps/conditions
ConditionsRecord.java added at 61
--- java/trunk/conditions/src/main/java/org/hps/conditions/ConditionsRecord.java	                        (rev 0)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/ConditionsRecord.java	2013-12-03 21:35:47 UTC (rev 61)
@@ -0,0 +1,261 @@
+package org.hps.conditions;
+
+import static org.hps.conditions.ConditionsConstants.CONDITIONS_RECORD;
+
+import java.sql.Blob;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.Date;
+
+import org.lcsim.conditions.CachedConditions;
+import org.lcsim.conditions.ConditionsManager;
+
+/**
+ * This class represents a single record from the primary conditions data table,
+ * which defines the run validity range for a specific conditions set.
+ * 
+ * @author Jeremy McCormick <[log in to unmask]>
+ */
+public class ConditionsRecord {
+
+    int id;
+    int runStart;
+    int runEnd;
+    Date updated;
+    Date created;
+    Date validFrom;
+    Date validTo;
+    String createdBy;
+    String notes;
+    String name;
+    String formatVersion;
+    String tableName;
+    String fieldName;
+    int fieldValue;    
+                
+    protected ConditionsRecord() {        
+    }
+    
+    /**
+     * Load state into this object from a ResultSet, which must be positioned a priori
+     * to the correct row number.
+     * @param rs The ResultSet containing database records from the conditions table.
+     */
+    void load(ResultSet rs) {
+        try {            
+            id = rs.getInt(1);
+            runStart = rs.getInt(2);
+            runEnd = rs.getInt(3);
+            updated = rs.getTimestamp(4);
+            created = rs.getDate(5);
+            validFrom = rs.getDate(6);
+            validTo = rs.getDate(7);
+            createdBy = rs.getString(8);
+            Blob blob = rs.getBlob(9);
+            if (blob != null) {
+                byte[] blobData = blob.getBytes(1, (int)blob.length());
+                notes = new String(blobData);
+            }
+            name = rs.getString(10);
+            formatVersion = rs.getString(11);
+            tableName = rs.getString(12);
+            fieldName = rs.getString(13);
+            fieldValue = rs.getInt(14);
+            
+        } catch (SQLException e) {
+            throw new RuntimeException(e);
+        }
+    }
+     
+    /**
+     * Get the unique ID.
+     * @return The unique ID.
+     */
+    public int getId() {
+        return id;
+    }
+    
+    /**
+     * Get the starting run number.
+     * @return The starting run number.
+     */
+    public int getRunStart() {
+        return runStart;
+    }
+    
+    /**
+     * Get the ending run number.
+     * @return The ending run number.
+     */
+    public int getRunEnd() {
+        return runEnd;
+    }
+    
+    /**
+     * Get the date this record was last updated.
+     * @return The date this record was updated.
+     */
+    public Date getUpdated() {
+        return updated;
+    }
+    
+    /**
+     * Get the date this record was created.
+     * @return The date this record was created.
+     */
+    public Date getCreated() {
+        return created;
+    }
+    
+    /**
+     * Get the starting valid time.
+     * @return The starting valid time.
+     */
+    public Date getValidFrom() {
+        return validFrom;
+    }
+    
+    /**
+     * Get the ending valid time.
+     * @return The ending valid time.
+     */
+    public Date getValidTo() {
+        return validTo;
+    }
+
+    /**
+     * Get the name of the user who created this record.
+     * @return The name of the person who created the record.
+     */
+    public String getCreatedBy() {
+        return createdBy;
+    }
+
+    /**
+     * Get the notes.
+     * @return The notes about this condition.
+     */
+    public String getNotes() {
+        return notes;
+    }
+    
+    /**
+     * Get the name of these conditions, which should be unique by run number.
+     * @return The name of the conditions.
+     */
+    public String getName() {
+        return name;
+    }
+    
+    /**
+     * Get the version of the format these conditions are stored in.
+     * @return The conditions version.
+     */
+    public String getFormatVersion() {
+        return formatVersion;
+    }
+    
+    /**
+     * Get the name of the table containing the actual raw conditions data.
+     * @return The name of the table with the conditions data. 
+     */
+    public String getTableName() {
+        return tableName;
+    }
+    
+    /**
+     * Get the field that will define which set of conditions to fetch.
+     * @return The field used as a group ID of the conditions.
+     */
+    public String getFieldName() {
+        return fieldName;
+    }
+    
+    /**
+     * Get the value of the identifying field.
+     * @return The value of identifying field for these conditions.
+     */
+    public int getFieldValue() {
+        return fieldValue;
+    }    
+    
+    /**
+     * Convert this record to a human readable string, one field per line.
+     * @return This object represented as a string.
+     */
+    public String toString() {
+        StringBuffer buff = new StringBuffer();
+        buff.append("id: " + id + '\n');
+        buff.append("runStart: " + runStart + '\n');
+        buff.append("runEnd: " + runEnd + '\n');
+        buff.append("updated: " + updated + '\n');
+        buff.append("created: " + created + '\n');
+        buff.append("validFrom: " + validFrom + '\n');
+        buff.append("validTo: " + validTo + '\n');
+        buff.append("createdBy: " + createdBy + '\n');
+        buff.append("notes: " + notes + '\n');
+        buff.append("formatVersion: " + formatVersion + '\n');
+        buff.append("tableName: " + tableName + '\n');
+        buff.append("fieldName: " + fieldName + '\n');
+        buff.append("fieldValue: " + fieldValue + '\n');
+        return buff.toString();
+    }
+    
+    /**
+     * Find a ConditionsRecord with conditions key matching <code>name</code>.
+     * @param manager The current conditions manager.
+     * @param name The name of the conditions key.
+     * @return The matching ConditionsRecord.
+     * @throws IllegalArgumentException if no records are found.
+     * @throws IllegalArgumentException if more than one record is found.
+     */
+    public static ConditionsRecordCollection find(ConditionsManager manager, String name) {
+        CachedConditions<ConditionsRecordCollection> c = manager.getCachedConditions(ConditionsRecordCollection.class, CONDITIONS_RECORD);
+        ConditionsRecordCollection conditionsRecords = c.getCachedData();
+        conditionsRecords = conditionsRecords.find(name);
+        if (conditionsRecords.size() == 0) {
+            throw new IllegalArgumentException("No ConditionsRecord with name: " + name);
+        }              
+        //if (conditionsRecords.size() > 1) {
+        //    throw new IllegalArgumentException("Duplicate ConditionsRecord with name: " + name);
+        //}
+        return conditionsRecords;
+    }
+    
+    /**
+     * Find conditions records of all types in the database by run number.
+     * @param run The run number.
+     * @return The set of matching ConditionsRecords.
+     */
+    public static ConditionsRecordCollection find(int run) {
+        
+        ConditionsRecordCollection conditionsRecords = new ConditionsRecordCollection();
+        
+        ConnectionManager manager = ConnectionManager.getConnectionManager();
+        String db = manager.getConnectionParameters().getDatabase();
+        String table = manager.getConnectionParameters().getConditionsTable();
+                
+        String query = "SELECT * FROM " 
+                + db + "." + table                       
+                + " WHERE "
+                + "run_start <= "
+                + run
+                + " AND run_end >= "
+                + run;
+        
+        ResultSet resultSet = manager.query(query);
+            
+        // Iterate over conditions records.
+        try {
+            while (resultSet.next()) {
+                ConditionsRecord record = new ConditionsRecord();
+                record.load(resultSet);
+                conditionsRecords.add(record);
+            } 
+        } catch (SQLException x) {
+            throw new RuntimeException("Database error", x);
+        } 
+                   
+        return conditionsRecords;
+    }
+}
\ No newline at end of file

java/trunk/conditions/src/main/java/org/hps/conditions
ConditionsRecordCollection.java added at 61
--- java/trunk/conditions/src/main/java/org/hps/conditions/ConditionsRecordCollection.java	                        (rev 0)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/ConditionsRecordCollection.java	2013-12-03 21:35:47 UTC (rev 61)
@@ -0,0 +1,26 @@
+package org.hps.conditions;
+
+import java.util.ArrayList;
+
+/**
+ * This is a simple container class for objects with the type <code>ConditionsRecord</code>.
+ * @author Jeremy McCormick <[log in to unmask]>
+ */
+public class ConditionsRecordCollection extends ArrayList<ConditionsRecord> {
+            
+    /**
+     * Find a ConditionsRecord by its name or key in this collection.  
+     * This is the 'name' field from the conditions database table. 
+     * @param name The name of the conditions set, e.g. 'svt_calibrations' etc.
+     * @return The collection of ConditionsRecords, which can be empty if none were found.
+     */
+    public ConditionsRecordCollection find(String name) {
+        ConditionsRecordCollection records = new ConditionsRecordCollection();
+        for (ConditionsRecord rec : this) {
+            if (rec.getName().equals(name)) {
+                records.add(rec);
+            }
+        }
+        return records;
+    }        
+}
\ No newline at end of file

java/trunk/conditions/src/main/java/org/hps/conditions
ConditionsRecordConverter.java added at 61
--- java/trunk/conditions/src/main/java/org/hps/conditions/ConditionsRecordConverter.java	                        (rev 0)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/ConditionsRecordConverter.java	2013-12-03 21:35:47 UTC (rev 61)
@@ -0,0 +1,65 @@
+package org.hps.conditions;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+import org.lcsim.conditions.ConditionsManager;
+
+/**
+ * Read ConditionsRecord objects from the conditions database.  
+ * @author Jeremy McCormick <[log in to unmask]>
+ * @version $Id: ConditionsRecordConverter.java,v 1.5 2013/10/15 23:24:47 jeremy Exp $
+ */
+public class ConditionsRecordConverter extends DatabaseConditionsConverter<ConditionsRecordCollection> {
+           
+    /**
+     * Class constructor.
+     */
+    public ConditionsRecordConverter() {
+    }
+        
+    /**
+     * Get the ConditionsRecords for a run.  This method ignores the name argument 
+     * and will fetch all conditions records for the current run.
+     * @param manager The current conditions manager.
+     * @param name The name of the conditions set.
+     * @return The matching ConditionsRecords.
+     */
+    public ConditionsRecordCollection getData(ConditionsManager manager, String name) {
+                                
+        ConditionsRecordCollection records = new ConditionsRecordCollection();
+        
+        ConnectionManager connectionManager = this.getConnectionManager();
+        String tableName = connectionManager.getConnectionParameters().getConditionsTable();
+        
+        String query = "SELECT * from " 
+                + tableName
+                + " WHERE "
+                + "run_start <= "
+                + manager.getRun()
+                + " AND run_end >= "
+                + manager.getRun();
+               
+        ResultSet resultSet = connectionManager.query(query);
+        
+        try {
+            while(resultSet.next()) {                  
+                ConditionsRecord record = new ConditionsRecord();
+                record.load(resultSet);
+                records.add(record);
+            }            
+        } catch (SQLException x) {
+            throw new RuntimeException("Database error", x);
+        } 
+        
+        return records;
+    }
+
+    /**
+     * Get the type handled by this converter.
+     * @return The type handled by this converter, which is <code>ConditionsRecordCollection</code>.
+     */
+    public Class<ConditionsRecordCollection> getType() {
+        return ConditionsRecordCollection.class;
+    }        
+}
\ No newline at end of file

java/trunk/conditions/src/main/java/org/hps/conditions
ConnectionManager.java added at 61
--- java/trunk/conditions/src/main/java/org/hps/conditions/ConnectionManager.java	                        (rev 0)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/ConnectionManager.java	2013-12-03 21:35:47 UTC (rev 61)
@@ -0,0 +1,150 @@
+package org.hps.conditions;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.Properties;
+
+/**
+ * This class provides various database utilities for the conditions system, primarily the
+ * converter classes.
+ * 
+ * @author Jeremy McCormick <[log in to unmask]>
+ */
+public class ConnectionManager {
+
+    private ConnectionParameters connectionParameters = new ConnectionParameters();
+    private static ConnectionManager instance = null;
+    private Connection connection = null;
+
+    /**
+     * Class constructor which is private so singleton must be used.
+     */
+    private ConnectionManager() {
+        setupFromProperties();
+    }
+
+    /**
+     * Get the singleton instance of this class.
+     * @return The instance of this class.
+     */
+    public static ConnectionManager getConnectionManager() {
+        if (instance == null) {
+            instance = new ConnectionManager();
+        }
+        return instance;
+    }
+
+    /**
+     * Set the connection parameters.
+     * @param connectionParameters The connection parameters.
+     */
+    void setConnectionParameters(ConnectionParameters connectionParameters) {
+        this.connectionParameters = connectionParameters;
+    }
+
+    /**
+     * Get the connection parameters.
+     * @return The connection parameters.
+     */
+    public ConnectionParameters getConnectionParameters() {
+        return connectionParameters;
+    }
+
+    /**
+     * Create a connection to the database.
+     * @return The database connection.
+     */
+    Connection createConnection() {
+        Connection newConnection = connectionParameters.createConnection();
+        try {
+            newConnection.createStatement().execute("USE " + connectionParameters.getDatabase());
+        } catch (SQLException e) {
+            throw new RuntimeException("Failed to connect to database.", e);
+        }
+        return newConnection;
+    }
+
+    /**
+     * Cleanup a connection.
+     * @param connection The Connection to cleanup.
+     */
+    public void cleanup(Connection connection) {
+        if (connection != null) {
+            try {
+                if (!connection.isClosed())
+                    connection.close();
+                else
+                    System.err.println("Connection already closed!");
+            } catch (SQLException x) {
+                throw new RuntimeException("Failed to close connection.", x);
+            }
+        }
+    }
+
+    /**
+     * Cleanup a result set, or the Statement connected to it.
+     * @param resultSet The ResultSet to cleanup.
+     */
+    public void cleanup(ResultSet resultSet) {
+        if (resultSet != null) {
+            try {
+                // This should close the ResultSet itself, too.
+                Statement statement = resultSet.getStatement();
+                if (statement != null)
+                    if (!statement.isClosed())
+                        statement.close();
+                    else
+                        System.err.println("Statement already closed!");
+            } catch (SQLException x) {
+                throw new RuntimeException("Failed to close statement.", x);
+            }
+        }
+    }
+
+    /**
+     * This method can be used to perform a database query. 
+     * @param query The SQL query string.
+     * @return The ResultSet from the query or null.
+     */
+    public ResultSet query(String query) {
+        if (connection == null)
+            connection = createConnection();
+        ResultSet result = null;
+        try {
+            Statement statement = connection.createStatement();
+            result = statement.executeQuery(query);
+        } catch (SQLException x) {
+            throw new RuntimeException("Error in query: " + query, x);
+        }
+        return result;
+    }
+    
+    public void disconnect() {
+        cleanup(connection);
+    }
+
+    /**
+     * Setup the object from a properties file.
+     */
+    private void setupFromProperties() {
+        Object obj = System.getProperties().get("hps.conditions.db.configuration");
+        if (obj != null) {
+            String config = obj.toString();
+            Properties p = new Properties();
+            try {
+                p.load(new FileInputStream(new File(config)));
+            } catch (FileNotFoundException e) {
+                throw new RuntimeException(e);
+            } catch (IOException e) {
+                throw new RuntimeException(e);
+            }
+            connectionParameters = ConnectionParameters.fromProperties(p);
+        }
+    }
+}

java/trunk/conditions/src/main/java/org/hps/conditions
ConnectionParameters.java added at 61
--- java/trunk/conditions/src/main/java/org/hps/conditions/ConnectionParameters.java	                        (rev 0)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/ConnectionParameters.java	2013-12-03 21:35:47 UTC (rev 61)
@@ -0,0 +1,129 @@
+package org.hps.conditions;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+import java.util.Properties;
+
+/**
+ * This class encapsulates the parameters for connecting to a database, 
+ * including hostname, port, user and password.  It can also create and 
+ * return a Connection object based on these parameters.
+ * @author Jeremy McCormick <[log in to unmask]>
+ * @version $Id: ConnectionParameters.java,v 1.8 2013/10/04 01:54:16 jeremy Exp $
+ */
+public final class ConnectionParameters {
+    
+    /** Default values for the MySQL test database at SLAC. */
+    private String user = "rd_hps_cond_ro";
+    private String password = "2jumpinphotons.";
+    private int port = 3306;
+    private String hostname = "mysql-node03.slac.stanford.edu";
+    private String database = "rd_hps_cond";
+    private String conditionsTable = "conditions_dev";
+
+    /**
+     * No argument constructor that uses the defaults.
+     */
+    ConnectionParameters() {
+    }
+
+    /**
+     * Fully qualified constructor.
+     * @param user The user name.
+     * @param password The password.
+     * @param hostname The hostname.
+     * @param port The port number.
+     * @param conditionsTable The table containing conditions validity data.
+     */
+    ConnectionParameters(String user, String password, String database, String hostname, int port, String conditionsTable) {
+        this.user = user;
+        this.password = password;
+        this.database = database;
+        this.hostname = hostname;
+        this.port = port;
+        this.conditionsTable = conditionsTable;
+    }
+
+    /**
+     * Get Properties object for this connection.
+     * @return The Properties for this connection.
+     */
+    public Properties getConnectionProperties() {
+        Properties p = new Properties();
+        p.put("user", user);
+        p.put("password", password);
+        return p;
+    }
+
+    /**
+     * Get the hostname.
+     * @return The hostname.
+     */
+    public String getHostname() {
+        return hostname;
+    }
+
+    /**
+     * Get the port number.
+     * @return The port number.
+     */
+    public int getPort() {
+        return port;
+    }
+    
+    /**
+     * Get the name of the database.
+     * @return The name of the database.
+     */
+    public String getDatabase() {
+        return database;
+    }
+
+    /**
+     * Get the connection string for these parameters.
+     * @return The connection string.
+     */
+    public String getConnectionString() {
+        return "jdbc:mysql://" + hostname + ":" + port + "/";
+    }       
+    
+    /**
+     * Get the name of the conditions validity data.
+     * @return The name of the conditions validity data table. 
+     */
+    public String getConditionsTable() {
+        return conditionsTable;
+    }
+    
+    /**
+     * Create a database connection from these parameters.  
+     * The caller is responsible for closing it when finished.
+     * @return The Connection object.
+     */
+    public Connection createConnection() {
+        Properties connectionProperties = getConnectionProperties();
+        Connection connection = null;
+        try {
+            connection = DriverManager.getConnection(getConnectionString(), connectionProperties);
+        } catch (SQLException x) {
+            throw new RuntimeException("Failed to connect to database: " + getConnectionString(), x);
+        }
+        return connection;
+    }
+    
+    /**
+     * Create ConnectionParameters from data in a properties file.
+     * @param properties The properties file.
+     * @return The ConnectionParameters created from the properties file.
+     */
+    public static final ConnectionParameters fromProperties(Properties properties) {        
+        String user = properties.get("user").toString();
+        String password = properties.getProperty("password").toString();
+        String database = properties.getProperty("database").toString();
+        String hostname = properties.getProperty("hostname").toString();
+        int port = Integer.parseInt(properties.getProperty("port").toString());
+        String conditionsTable = properties.getProperty("conditionsTable").toString();
+        return new ConnectionParameters(user, password, database, hostname, port, conditionsTable);
+    }    
+}

java/trunk/conditions/src/main/java/org/hps/conditions
DatabaseConditionsConverter.java added at 61
--- java/trunk/conditions/src/main/java/org/hps/conditions/DatabaseConditionsConverter.java	                        (rev 0)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/DatabaseConditionsConverter.java	2013-12-03 21:35:47 UTC (rev 61)
@@ -0,0 +1,21 @@
+package org.hps.conditions;
+
+import org.lcsim.conditions.ConditionsConverter;
+
+/**
+ * This class is basically just a typedef right now but functionality may be added here
+ * that all converters can use.
+ * @author Jeremy McCormick <[log in to unmask]>
+ */
+public abstract class DatabaseConditionsConverter<T> implements ConditionsConverter<T> {   
+	
+    /**
+     * Get the the {@link ConnectionManager} associated with this converter.
+     * For now, this calls the singleton method of the ConnectionManager
+     * to get its instance.
+     * @return The ConnectionManager of this converter.
+     */
+    public ConnectionManager getConnectionManager() {
+        return ConnectionManager.getConnectionManager();
+    }
+}
\ No newline at end of file

java/trunk/conditions/src/main/java/org/hps/conditions
DatabaseConditionsReader.java added at 61
--- java/trunk/conditions/src/main/java/org/hps/conditions/DatabaseConditionsReader.java	                        (rev 0)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/DatabaseConditionsReader.java	2013-12-03 21:35:47 UTC (rev 61)
@@ -0,0 +1,164 @@
+package org.hps.conditions;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.logging.ConsoleHandler;
+import java.util.logging.Formatter;
+import java.util.logging.Level;
+import java.util.logging.LogRecord;
+import java.util.logging.Logger;
+
+import org.lcsim.conditions.ConditionsManager;
+import org.lcsim.conditions.ConditionsReader;
+
+/**
+ * <p>
+ * This a rewritten version of Dima's ExampleDatabaseConditionsReader that attempts to handle 
+ * the conditions and their meta data in a fully generic fashion.
+ * </p>
+ * 
+ * <p>
+ * In order to override the default database connection parameters, the system property
+ * <code>hps.conditions.db.configuration</code> should point to a properties file defining 
+ * the variables read by ConnectionParameters (see that class for details).  Otherwise, the 
+ * defaults will be used to connect to a test database at SLAC.
+ * <p>
+ * 
+ * <p>
+ * Setting custom connection properties would look something like the following from the CL:
+ * </p>
+ * 
+ * <p><code>java -Dhps.conditions.db.configuration=/path/to/my/config.prop [...]</code></p>
+ * 
+ * <p>
+ * Currently, this class should "know" directly about all the converters that are needed for loading
+ * conditions data via the <code>registerConditionsConverters</code> method.  
+ * </p>
+ * 
+ * @author Jeremy McCormick <[log in to unmask]>
+ * @version $Id: DatabaseConditionsReader.java,v 1.21 2013/10/18 06:08:55 jeremy Exp $ 
+ */
+public class DatabaseConditionsReader extends ConditionsReader {
+        
+    /** Database connection. */
+    private Connection connection = null;    
+    
+    /** Base ConditionsReader for getting the Detector. */
+    private final ConditionsReader reader;
+    
+    /** The current run number to determine if conditions are already loaded. */
+    private int currentRun = Integer.MIN_VALUE;
+    
+    /** Converter for making ConditionsRecord objects from the database. */
+    ConditionsRecordConverter conditionsRecordConverter = new ConditionsRecordConverter();
+    
+    /** The logger for printing messages. */
+    static Logger logger = null;
+
+    /**
+     * Class constructor taking a ConditionsReader.  This constructor is automatically called 
+     * by the ConditionsManager when this type of reader has been requested via the detector 
+     * properties file.
+     * 
+     * @param reader The basic ConditionsReader allowing access to the detector.
+     */
+    public DatabaseConditionsReader(ConditionsReader reader) {
+        this.reader = reader;        
+        
+        setupLogger();
+    }
+    
+    /**
+     * Setup the logger.
+     */
+    private final void setupLogger() {
+        if (logger == null) {
+            logger = Logger.getLogger(this.getClass().getSimpleName());
+            logger.setUseParentHandlers(false);
+            logger.setLevel(Level.ALL);
+            ConsoleHandler handler = new ConsoleHandler();
+            handler.setFormatter(new ConditionsFormatter());
+            logger.addHandler(handler);
+        }
+    }
+    
+    /**
+     * Simple log formatter for this class.
+     */
+    private static final class ConditionsFormatter extends Formatter {
+        
+        public String format(LogRecord record) {
+            StringBuilder sb = new StringBuilder();
+            sb.append(record.getLoggerName() + " [ " + record.getLevel() + " ] " + record.getMessage() + '\n');
+            return sb.toString();
+        }
+    }
+    
+    /**
+     * Update conditions for possibly new detector and run number.  
+     * @param manager The current conditions manager.
+     * @param detectorName The detector name.
+     * @param run The run number.
+     */
+    public boolean update(ConditionsManager manager, String detectorName, int run) throws IOException {
+                
+        logger.info("updating detector <" + detectorName + "> for run <" + run + "> ...");
+        
+        // Check if conditions are already cached for the run.
+        if (run == currentRun) {
+            logger.warning("Conditions already cached for run <" + run + ">.");
+            return false;
+        }
+            
+        // Register the converters on the manager.         
+        // FIXME: This should really only happen once instead of being called here every time.
+        ConditionsConverterRegister.register(manager);
+                
+        // Open a connection to the database.
+        connection = ConnectionManager.getConnectionManager().createConnection();
+        
+        // Cache the ConditionsRecords.
+        try {
+            setup(run);
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+                               
+        // Close the database connection.
+        try {
+            connection.close();
+            connection = null;
+        } catch (SQLException x) {
+            throw new IOException("Failed to close connection", x);
+        }
+                
+        return true;
+    }
+
+    /**
+     * Close the base reader.
+     */
+    public void close() throws IOException {
+        reader.close();
+    }
+
+    /**
+     * Implementation of ConditionReader API method.
+     * @return An InputStream with the conditions for <code>type</code>.
+     */
+    public InputStream open(String name, String type) throws IOException {
+        return reader.open(name, type);
+    }
+     
+    /**
+     * This will cache the ConditionsRecords for the run.
+     * @param run The run number.
+     * @throws SQLException
+     * @throws IOException
+     */
+    private final void setup(int run) throws SQLException, IOException {
+        ConditionsRecord.find(run);
+    }           
+}

java/trunk/conditions/src/main/java/org/hps/conditions
TestRunConditionsReader.java added at 61
--- java/trunk/conditions/src/main/java/org/hps/conditions/TestRunConditionsReader.java	                        (rev 0)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/TestRunConditionsReader.java	2013-12-03 21:35:47 UTC (rev 61)
@@ -0,0 +1,63 @@
+package org.hps.conditions;
+
+import java.io.IOException;
+import java.io.InputStream;
+import org.lcsim.conditions.ConditionsManager;
+import org.lcsim.conditions.ConditionsReader;
+
+import org.hps.conditions.DatabaseConditionsReader;
+
+/**
+ *
+ * @author Sho Uemura <[log in to unmask]>
+ * @author Jeremy McCormick <[log in to unmask]>
+ * @version $Id: TestRunConditionsReader.java,v 1.4 2013/10/17 23:04:19 jeremy Exp $
+ */
+public class TestRunConditionsReader extends DatabaseConditionsReader {
+
+    private String detectorName = null;
+    //private int run;
+
+    public TestRunConditionsReader(ConditionsReader reader) {
+        super(reader);
+    }
+
+    public InputStream open(String name, String type) throws IOException {
+        // 1) Check the detector base directory.
+        InputStream in = getClass().getResourceAsStream("/" + detectorName + "/" + name + "." + type);
+        if (in == null) {
+            // 2) Check for embedded jar resources.
+            in = getClass().getResourceAsStream("/org/lcsim/hps/calib/testrun/" + name + "." + type);
+            if (in == null) {
+                // 3) Use super's open method.
+                in = super.open(name, type);
+                
+                // If all of these failed to find conditions, then something went wrong.
+                if (in == null) {
+                    throw new IOException("Conditions " + name + " for " + detectorName + " with type " + type + " were not found");
+                }       
+            }
+        }
+        return in;
+    }
+
+    public void close() throws IOException {
+    }
+
+
+    public boolean update(ConditionsManager manager, String detectorName, int run) throws IOException {
+//            loadCalibsByRun(run);
+//        Detector detector = manager.getCachedConditions(Detector.class,"compact.xml").getCachedData();
+//        HPSEcalConditions.detectorChanged(detector, "Ecal");
+//        HPSSVTCalibrationConstants.loadCalibration(run);
+        this.detectorName = detectorName;
+        //this.run = run;
+        super.update(manager, detectorName, run);
+//        System.out.println(detectorName+run);
+        return true;
+    }
+//        private void loadCalibsByRun(int run) {
+//        HPSSVTCalibrationConstants.loadCalibration(run);
+//        FieldMap.loadFieldMap(run);
+//    }
+}

java/trunk/conditions/src/main/java/org/hps/conditions/beam
BeamCurrent.java added at 61
--- java/trunk/conditions/src/main/java/org/hps/conditions/beam/BeamCurrent.java	                        (rev 0)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/beam/BeamCurrent.java	2013-12-03 21:35:47 UTC (rev 61)
@@ -0,0 +1,26 @@
+package org.hps.conditions.beam;
+
+/**
+ * This class is a simple data holder for the integrated beam current condition.
+ * @author Jeremy McCormick <[log in to unmask]>
+ */
+public class BeamCurrent {
+    
+    double beamCurrent = Double.NaN;
+    
+    /**
+     * Class constructor.
+     * @param beamCurrent The integrated beam current value.
+     */
+    BeamCurrent(double beamCurrent) {
+        this.beamCurrent = beamCurrent;
+    }
+    
+    /**
+     * Get the integrated beam current.
+     * @return The integrated beam current.
+     */
+    double getIntegratedBeamCurrent() {
+        return beamCurrent;
+    }
+}

java/trunk/conditions/src/main/java/org/hps/conditions/beam
BeamCurrentConverter.java added at 61
--- java/trunk/conditions/src/main/java/org/hps/conditions/beam/BeamCurrentConverter.java	                        (rev 0)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/beam/BeamCurrentConverter.java	2013-12-03 21:35:47 UTC (rev 61)
@@ -0,0 +1,72 @@
+package org.hps.conditions.beam;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+import org.lcsim.conditions.ConditionsManager;
+import org.hps.conditions.ConditionsRecord;
+import org.hps.conditions.ConnectionManager;
+import org.hps.conditions.DatabaseConditionsConverter;
+
+/**
+ * This class creates a {@link BeamCurrent} from the conditions database.
+ * @author Jeremy McCormick <[log in to unmask]>
+ */
+public class BeamCurrentConverter extends DatabaseConditionsConverter<BeamCurrent> {
+    
+    /**
+     * Class constructor.
+     */
+    public BeamCurrentConverter() {
+    }
+
+    /**
+     * Get the conditions data.
+     * @param manager The current conditions manager.
+     * @param name The name of the conditions set.
+     */
+    public BeamCurrent getData(ConditionsManager manager, String name) {
+        
+        // Get the ConditionsRecord with the meta-data, which will use the current run number from the manager.
+        ConditionsRecord record = ConditionsRecord.find(manager, name).get(0);
+               
+        // Get the table name, field name, and field value defining the applicable conditions.
+        String tableName = record.getTableName();
+        String fieldName = record.getFieldName();
+        int fieldValue = record.getFieldValue();
+                        
+        // Get the connection manager.
+        ConnectionManager connectionManager = ConnectionManager.getConnectionManager();
+                                                                                            
+        // Construct the query to find matching records using the ID field.
+        String query = "SELECT beam_current FROM "
+                + tableName + " WHERE " + fieldName + " = " + fieldValue;
+            
+        // Execute the query and get the results.
+        ResultSet resultSet = connectionManager.query(query);
+        
+        // The object to be returned to caller.
+        BeamCurrent beamCurrent = null;
+        
+        try {
+            // Loop over the gain records.            
+            while(resultSet.next()) {                              
+                beamCurrent = new BeamCurrent(resultSet.getDouble(1));
+                break;
+            }            
+        } catch (SQLException x) {
+            throw new RuntimeException("Database error.", x);
+        }
+        
+        // Return collection of gain objects to caller.
+        return beamCurrent;
+    }
+
+    /**
+     * Get the type handled by this converter.     
+     * @return The type handled by this converter.
+     */
+    public Class<BeamCurrent> getType() {
+        return BeamCurrent.class;
+    }        
+}

java/trunk/conditions/src/main/java/org/hps/conditions/ecal
EcalBadChannelCollection.java added at 61
--- java/trunk/conditions/src/main/java/org/hps/conditions/ecal/EcalBadChannelCollection.java	                        (rev 0)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/ecal/EcalBadChannelCollection.java	2013-12-03 21:35:47 UTC (rev 61)
@@ -0,0 +1,9 @@
+package org.hps.conditions.ecal;
+
+import org.hps.conditions.ChannelCollection;
+
+/**
+ * A collection of bad channel IDs in the ECAL.
+ */
+public class EcalBadChannelCollection extends ChannelCollection {
+}

java/trunk/conditions/src/main/java/org/hps/conditions/ecal
EcalBadChannelConverter.java added at 61
--- java/trunk/conditions/src/main/java/org/hps/conditions/ecal/EcalBadChannelConverter.java	                        (rev 0)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/ecal/EcalBadChannelConverter.java	2013-12-03 21:35:47 UTC (rev 61)
@@ -0,0 +1,70 @@
+package org.hps.conditions.ecal;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+import org.lcsim.conditions.ConditionsManager;
+import org.hps.conditions.ChannelCollection;
+import org.hps.conditions.ConditionsRecord;
+import org.hps.conditions.ConditionsRecordCollection;
+import org.hps.conditions.ConnectionManager;
+import org.hps.conditions.DatabaseConditionsConverter;
+
+/**
+ * This class creates a {@link ChannelCollection} representing bad readout channels.
+ * @author Jeremy McCormick <[log in to unmask]>
+ */
+public class EcalBadChannelConverter extends DatabaseConditionsConverter<EcalBadChannelCollection> {
+
+    /**
+     * Create the collection from the conditions database. 
+     * @param manager The conditions manager.
+     * @param name The name of the conditions set.
+     */
+    public EcalBadChannelCollection getData(ConditionsManager manager, String name) {
+
+        // Collection to be returned to caller.
+        EcalBadChannelCollection badChannels = new EcalBadChannelCollection();
+
+        // Get the ConditionsRecord with the meta-data, which will use the
+        // current run number from the manager.
+        ConditionsRecordCollection records = ConditionsRecord.find(manager, name);
+
+        // Loop over ConditionsRecords.  For this particular type of condition, multiple
+        // sets of bad channels are possible.
+        for (ConditionsRecord record : records) {
+        
+            // Get the table name, field name, and field value defining the
+            // applicable conditions.
+            String tableName = record.getTableName();
+            String fieldName = record.getFieldName();
+            int fieldValue = record.getFieldValue();
+
+            // Query for getting back bad channel records.
+            String query = "SELECT ecal_channel_id FROM " + tableName + " WHERE " 
+                    + fieldName + " = " + fieldValue + " ORDER BY id ASC";
+            ResultSet resultSet = ConnectionManager.getConnectionManager().query(query);
+            
+            // Loop over the records.
+            try {
+                while (resultSet.next()) {
+                    int channelId = resultSet.getInt(1);
+                    badChannels.add(channelId);
+                }
+            } catch (SQLException x) {
+                throw new RuntimeException(x);
+            } 
+        }
+               
+        return badChannels;
+    }
+
+    /**
+     * Get the type handled by this converter.
+     * 
+     * @return The type handled by this converter.
+     */
+    public Class<EcalBadChannelCollection> getType() {
+        return EcalBadChannelCollection.class;
+    }
+}

java/trunk/conditions/src/main/java/org/hps/conditions/ecal
EcalCalibration.java added at 61
--- java/trunk/conditions/src/main/java/org/hps/conditions/ecal/EcalCalibration.java	                        (rev 0)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/ecal/EcalCalibration.java	2013-12-03 21:35:47 UTC (rev 61)
@@ -0,0 +1,42 @@
+package org.hps.conditions.ecal;
+
+/**
+ * This class is a simplistic representation of ECal pedestal and noise
+ * values from the conditions database.
+ * 
+ * @author Jeremy McCormick <[log in to unmask]>
+ */
+class EcalCalibration {
+       
+    /** The pedestal value. */
+    private double pedestal;
+    
+    /** The noise value. */
+    private double noise;
+    
+    /**
+     * Fully qualified class constructor.
+     * @param pedestal The pedestal value.
+     * @param noise The noise value.
+     */
+    EcalCalibration(double pedestal, double noise) {
+        this.pedestal = pedestal;
+        this.noise = noise;
+    }
+        
+    /**
+     * Get the pedestal value.
+     * @return The gain value.
+     */
+    public double getPedestal() {
+        return pedestal;
+    }       
+    
+    /**
+     * Get the noise value.
+     * @return The noise value.
+     */
+    public double getNoise() {
+        return noise;
+    }
+}
\ No newline at end of file

java/trunk/conditions/src/main/java/org/hps/conditions/ecal
EcalCalibrationCollection.java added at 61
--- java/trunk/conditions/src/main/java/org/hps/conditions/ecal/EcalCalibrationCollection.java	                        (rev 0)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/ecal/EcalCalibrationCollection.java	2013-12-03 21:35:47 UTC (rev 61)
@@ -0,0 +1,15 @@
+package org.hps.conditions.ecal;
+
+import java.util.LinkedHashMap;
+
+/**
+ * This class represents a list of {@link EcalCalibration} objects and their ECAL channel IDs.
+ * @author Jeremy McCormick <[log in to unmask]>
+ */
+public class EcalCalibrationCollection extends LinkedHashMap<Integer,EcalCalibration> {
+    /**
+     * Class constructor.
+     */
+    EcalCalibrationCollection() {        
+    }
+}

java/trunk/conditions/src/main/java/org/hps/conditions/ecal
EcalCalibrationConverter.java added at 61
--- java/trunk/conditions/src/main/java/org/hps/conditions/ecal/EcalCalibrationConverter.java	                        (rev 0)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/ecal/EcalCalibrationConverter.java	2013-12-03 21:35:47 UTC (rev 61)
@@ -0,0 +1,76 @@
+package org.hps.conditions.ecal;
+
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+import org.lcsim.conditions.ConditionsManager;
+import org.hps.conditions.ConditionsRecord;
+import org.hps.conditions.ConnectionManager;
+import org.hps.conditions.DatabaseConditionsConverter;
+
+/**
+ * This class creates a list of {@link EcalCalibrationCollection} from the
+ * conditions database.
+ * 
+ * @author Jeremy McCormick <[log in to unmask]>
+ */
+public class EcalCalibrationConverter extends DatabaseConditionsConverter<EcalCalibrationCollection> {
+
+    /**
+     * Create the calibration collection from the conditions database.
+     * @param manager The conditions manager.
+     * @param name The name of the conditions set.
+     */
+    public EcalCalibrationCollection getData(ConditionsManager manager, String name) {
+
+        // Collection to be returned to caller.
+        EcalCalibrationCollection calibrations = new EcalCalibrationCollection();
+
+        // Get the ConditionsRecord with the meta-data, which will use the
+        // current run number from the manager.
+        ConditionsRecord record = ConditionsRecord.find(manager, name).get(0);
+
+        // Get the table name, field name, and field value defining the
+        // applicable conditions.
+        String tableName = record.getTableName();
+        String fieldName = record.getFieldName();
+        int fieldValue = record.getFieldValue();
+
+        // References to database objects.
+        ResultSet resultSet = null;
+        ConnectionManager connectionManager = getConnectionManager();
+
+        // The query to get conditions.
+        String query = "SELECT ecal_channel_id, pedestal, noise FROM " 
+                + tableName + " WHERE " 
+                + fieldName + " = " + fieldValue + " ORDER BY ecal_channel_id ASC";
+
+        // Execute the query.
+        resultSet = connectionManager.query(query);
+
+        try {
+            // Loop over the records.
+            while (resultSet.next()) {
+                // Create calibration object from record.
+                int channelId = resultSet.getInt(1);
+                double pedestal = resultSet.getDouble(2);
+                double noise = resultSet.getDouble(3);
+                calibrations.put(channelId, new EcalCalibration(pedestal, noise));
+            }
+        } catch (SQLException x) {
+            throw new RuntimeException("Database error.", x);
+        } 
+        
+        return calibrations;
+    }
+
+    /**
+     * Get the type handled by this converter.
+     * 
+     * @return The type handled by this converter.
+     */
+    public Class<EcalCalibrationCollection> getType() {
+        return EcalCalibrationCollection.class;
+    }
+}

java/trunk/conditions/src/main/java/org/hps/conditions/ecal
EcalChannel.java added at 61
--- java/trunk/conditions/src/main/java/org/hps/conditions/ecal/EcalChannel.java	                        (rev 0)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/ecal/EcalChannel.java	2013-12-03 21:35:47 UTC (rev 61)
@@ -0,0 +1,122 @@
+package org.hps.conditions.ecal;
+
+/**
+ * This class encapsulates all the setup information about a single ECal channel, e.g. one crystal.
+ * This includes the channel ID from the conditions database; the crate, slot, and channel numbers
+ * from the DAQ hardware; and the physical x and y values of the geometric crystal volumes. 
+ * Each of these three pieces of data specifies a unique channel, so the information is in 
+ * some sense redundant.  This class allows all these values to be associated by channel 
+ * in the same place.  The object references are used as keys into a {@link EcalChannelMap}
+ * in the {@link EcalConditions} object for getting channel data.
+ * @author Jeremy McCormick <[log in to unmask]>
+ */
+public class EcalChannel {
+    
+    /** Channel info. */
+    int id, crate, slot, channel, x, y;
+    
+    /**
+     * Identifying information for an ECal channel.  This is over-specified in 
+     * that crate-slot-channel, x-y, and id all uniquely identify the 
+     * channel by themselves.  But we add them all here to have the information 
+     * in one place.
+     * @param id The database ID of the channel.
+     * @param crate The crate number (1 or 2).
+     * @param slot The slot number.
+     * @param channel The channel number.
+     * @param x The x value of the channel.
+     * @param y The y value of the channel.
+     */
+    EcalChannel(int id, int crate, int slot, int channel, int x, int y) {
+        this.id = id;
+        this.crate = crate;
+        this.slot = slot;
+        this.channel = channel;
+        this.x = x;
+        this.y = y;
+    }
+
+    /**
+     * Get the crate number.
+     * @return The crate number.
+     */
+    public int getCrate() {
+        return crate;
+    }
+    
+    /**
+     * Get the slot number.
+     * @return The slot number.
+     */
+    public int getSlot() {
+        return slot;
+    }
+    
+    /**
+     * Get the channel number.
+     * @return The channel number.
+     */
+    public int getChannel() {
+        return channel;
+    }
+    
+    /**
+     * Get the x value.
+     * @return The x value.
+     */
+    public int getX() {
+        return x;
+    }
+    
+    /**
+     * Get the y value.
+     * @return The y value.
+     */
+    public int getY() {
+        return y;
+    }
+
+    /**
+     * Get the ID.
+     * @return The ID of the channel.
+     */
+    public int getId() {
+        return id;
+    }
+    
+    /**
+     * Implementation of equals.
+     * @return True if objects are equal; false if not.
+     */
+    public boolean equals(Object o) {
+        if (o == null) {
+            return false;
+        }
+        if (!(o instanceof EcalChannel)) {
+            return false;
+        }
+        if (o == this) {
+            return true;
+        }
+        EcalChannel c = (EcalChannel)o;
+        return c.getId() == id 
+                && c.getCrate() == crate 
+                && c.getSlot() == slot 
+                && c.getChannel() == channel
+                && c.getX() == x
+                && c.getY() == y;
+    }
+    
+    /**
+     * Implement of string conversion.
+     * @return The string representation of this channel data.
+     */
+    public String toString() {
+        return "id: " + id 
+                + ", crate: " + crate 
+                + ", slot: " + slot 
+                + ", channel: " + channel 
+                + ", x: " + x 
+                + ", y: " + y;
+    }
+}
\ No newline at end of file

java/trunk/conditions/src/main/java/org/hps/conditions/ecal
EcalChannelConstants.java added at 61
--- java/trunk/conditions/src/main/java/org/hps/conditions/ecal/EcalChannelConstants.java	                        (rev 0)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/ecal/EcalChannelConstants.java	2013-12-03 21:35:47 UTC (rev 61)
@@ -0,0 +1,69 @@
+package org.hps.conditions.ecal;
+
+/**
+ * This class represents ECAL conditions per channel.  Individual channel
+ * settings can be retrieved using the {@link EcalConditions} object
+ * and its {@link EcalChannelMap}.
+ * @author Jeremy McCormick <[log in to unmask]>
+ */
+public class EcalChannelConstants {
+    
+    EcalGain gain = null;
+    EcalCalibration calibration = null;
+    boolean badChannel = false;
+    
+    /**
+     * Class constructor, which is package protected.
+     */
+    EcalChannelConstants() {        
+    }
+    
+    /**
+     * Set the gain.
+     * @param gain The gain object.
+     */
+    void setGain(EcalGain gain) {
+        this.gain = gain;
+    }
+    
+    /**
+     * Set the calibration.
+     * @param calibration The calibration object.
+     */
+    void setCalibration(EcalCalibration calibration) {
+        this.calibration = calibration;
+    }
+    
+    /**
+     * Set the bad channel setting.
+     * @param badChannel The bad channel setting.
+     */
+    void setBadChannel(boolean badChannel) {
+        this.badChannel = badChannel;
+    }
+    
+    /**
+     * Get the gain.
+     * @return The gain.
+     */
+    public EcalGain getGain() {
+        return gain;
+    }
+    
+    /**
+     * Get the calibration.
+     * @return The calibration.
+     */
+    public EcalCalibration getCalibration() {
+        return calibration;
+    }
+    
+    /**
+     * Get whether this channel is bad or not.
+     * @return True if channel is bad; false if not.
+     */
+    public boolean isBadChannel() {
+        return badChannel;
+    }
+
+}

java/trunk/conditions/src/main/java/org/hps/conditions/ecal
EcalChannelMap.java added at 61
--- java/trunk/conditions/src/main/java/org/hps/conditions/ecal/EcalChannelMap.java	                        (rev 0)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/ecal/EcalChannelMap.java	2013-12-03 21:35:47 UTC (rev 61)
@@ -0,0 +1,52 @@
+package org.hps.conditions.ecal;
+
+import java.util.HashMap;
+
+/**
+ * This class maps ID values from the database to detailed ECal channel information.
+ * There should really only be one of these data structures per job, as the EcalChannel 
+ * objects are used as unique identifiers in the {@link EcalConditions} class.
+ */
+public class EcalChannelMap extends HashMap<Integer, EcalChannel> {
+    
+    /**
+     * Class constructor.
+     */
+    EcalChannelMap() {        
+    }
+    
+    /**
+     * Find a channel by using DAQ information.
+     * @param crate The crate number.
+     * @param slot The slot number.
+     * @param channelNumber The channel number.
+     * @return The matching channel or null if does not exist.
+     */
+    public EcalChannel find(int crate, int slot, int channelNumber) {
+        for (EcalChannel channel : values()) {
+            if (channel.getCrate() == crate 
+                    && channel.getSlot() == slot 
+                    && channel.getChannel() == channelNumber) {
+                return channel;
+            }
+        }
+        return null;
+    }
+    
+    /**
+     * Find a channel by using its physical ID information.
+     * @param x The x value.
+     * @param y The y value.
+     * @return The matching channel or null if does not exist.
+     * 
+     * FIXME: Improve performance of this method from O(N).
+     */
+    public EcalChannel find(int x, int y) {
+        for (EcalChannel channel : values()) {
+            if (channel.getX() == x && channel.getY()== y) {
+                return channel;
+            }
+        }
+        return null;
+    }
+}
\ No newline at end of file

java/trunk/conditions/src/main/java/org/hps/conditions/ecal
EcalChannelMapConverter.java added at 61
--- java/trunk/conditions/src/main/java/org/hps/conditions/ecal/EcalChannelMapConverter.java	                        (rev 0)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/ecal/EcalChannelMapConverter.java	2013-12-03 21:35:47 UTC (rev 61)
@@ -0,0 +1,71 @@
+package org.hps.conditions.ecal;
+
+import static org.hps.conditions.ConditionsConstants.ECAL_CHANNELS;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+import org.lcsim.conditions.ConditionsManager;
+import org.hps.conditions.ConnectionManager;
+import org.hps.conditions.DatabaseConditionsConverter;
+
+/**
+ * This class creates the {@link EcalChannelMap} from the conditions table
+ * containing the channel data.
+ * 
+ * @author Jeremy McCormick <[log in to unmask]>
+ */
+public class EcalChannelMapConverter extends DatabaseConditionsConverter<EcalChannelMap> {
+
+    /**
+     * Load the data from the conditions database.
+     * @param manager The conditions manager.
+     * @param name The name of the conditions set.
+     */
+    public EcalChannelMap getData(ConditionsManager manager, String name) {
+
+        // Collection to be returned to caller.
+        EcalChannelMap channels = new EcalChannelMap();
+
+        // References to database objects.
+        ResultSet resultSet = null;
+        ConnectionManager connectionManager = getConnectionManager();
+
+        // Assign default key name if none was given.
+        if (name == null)
+            name = ECAL_CHANNELS;
+
+        // Query to retrieve channel data.
+        String query = "SELECT id, x, y, crate, slot, channel FROM " + name;
+
+        // Execute the query and get the results.
+        resultSet = connectionManager.query(query);
+
+        try {
+            // Loop over the records.
+            while (resultSet.next()) {
+                // Create channel data object from database record.
+                int id = resultSet.getInt(1);
+                int x = resultSet.getInt(2);
+                int y = resultSet.getInt(3);
+                int crate = resultSet.getInt(4);
+                int slot = resultSet.getInt(5);
+                int channel = resultSet.getInt(6);
+                EcalChannel channelData = new EcalChannel(id, crate, slot, channel, x, y);
+                channels.put(channelData.getId(), channelData);
+            }
+        } catch (SQLException x) {
+            throw new RuntimeException("Database error.", x);
+        } 
+        
+        return channels;
+    }
+
+    /**
+     * Get the type that this converter handles.
+     * @return The type handled by this converter.
+     */
+    public Class<EcalChannelMap> getType() {
+        return EcalChannelMap.class;
+    }
+}

java/trunk/conditions/src/main/java/org/hps/conditions/ecal
EcalConditions.java added at 61
--- java/trunk/conditions/src/main/java/org/hps/conditions/ecal/EcalConditions.java	                        (rev 0)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/ecal/EcalConditions.java	2013-12-03 21:35:47 UTC (rev 61)
@@ -0,0 +1,125 @@
+package org.hps.conditions.ecal;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * This class provides access to all ECal conditions from the database,
+ * including gain, pedestal and bad channel settings, per crystal. 
+ * 
+ * @author Jeremy McCormick <[log in to unmask]>
+ */
+public class EcalConditions {
+    
+    /** Channel map. */
+    EcalChannelMap channelMap = new EcalChannelMap();
+    
+    /** Map between channels and conditions data. */
+    Map<EcalChannel,EcalChannelConstants> channelData = new HashMap<EcalChannel,EcalChannelConstants>();
+             
+    /**
+     * Class constructor, which is package protected.
+     */
+    EcalConditions() {        
+    }
+    
+    /**
+     * Set the channel map.
+     * @param channels The channel map.
+     */
+    void setChannelMap(EcalChannelMap channelMap) {
+        this.channelMap = channelMap;
+    }
+        
+    /**
+     * Get the map between database IDs and <code>EcalChannel</code> objects.
+     * @return The channel map.
+     */
+    public EcalChannelMap getChannelMap() {
+        return channelMap;
+    }
+       
+    /**
+     * Get the conditions constants for a specific channel.  These will be
+     * created if they do not exist for the given channel, BUT only channels
+     * in the current channel map are allowed as an argument.
+     * @param channel The ECAL channel.
+     * @return The conditions constants for the channel.
+     * @throws IllegalArgumentException if channel does not exist in the channel map.
+     */
+    public EcalChannelConstants getChannelConstants(EcalChannel channel) {
+        // This channel must come from the map.
+        if (!channelMap.containsValue(channel)) {
+            System.err.println("Channel not found in map => " + channel);
+            throw new IllegalArgumentException("Channel was not found in map.");
+        }
+        // If channel has no data yet, then add it.
+        if (!channelData.containsKey(channel))
+            channelData.put(channel, new EcalChannelConstants());
+        return channelData.get(channel);
+    }         
+            
+    /**
+     * Convert this object to a string.
+     * @return A string representation of this object.
+     */
+    public String toString() {
+        StringBuffer buff = new StringBuffer();
+        
+        buff.append('\n');
+        buff.append("Printing ECAL conditions ...");
+        buff.append('\n');
+        buff.append('\n');
+        
+        // Table header:
+        buff.append("id");
+        buff.append("    ");
+        buff.append("crate");
+        buff.append("  ");
+        buff.append("slot");        
+        buff.append("   ");
+        buff.append("channel");        
+        buff.append("  ");
+        buff.append("x");
+        buff.append("      ");
+        buff.append("y");        
+        buff.append("     ");
+        buff.append("gain");
+        buff.append("       ");
+        buff.append("pedestal");
+        buff.append("   ");
+        buff.append("noise");
+        buff.append("      ");
+        buff.append("bad");
+        buff.append('\n');
+        for (int i=0; i<80; i++) {
+            buff.append("-");
+        }        
+        buff.append('\n');
+        
+        // Loop over all channels.
+        for (EcalChannel channel : channelMap.values()) {
+            
+            EcalChannelConstants constants = getChannelConstants(channel);
+            
+            double gain = constants.getGain().getGain();
+            double pedestal = constants.getCalibration().getPedestal();
+            double noise = constants.getCalibration().getNoise();
+            boolean bad = constants.isBadChannel();
+            
+            // Channel data.
+            buff.append(String.format("%-5d %-6d %-6d %-8d %-6d %-6d", 
+                    channel.getId(), channel.getCrate(), channel.getSlot(), channel.getChannel(), 
+                    channel.getX(), channel.getY()));
+            
+            // Constants.
+            buff.append(String.format("%-10.4f %-10.4f %-10.4f ", gain, pedestal, noise));
+            
+            // Bad channel.
+            buff.append(bad);
+            
+            buff.append('\n');
+        }
+        return buff.toString();
+    }
+}
\ No newline at end of file

java/trunk/conditions/src/main/java/org/hps/conditions/ecal
EcalConditionsConverter.java added at 61
--- java/trunk/conditions/src/main/java/org/hps/conditions/ecal/EcalConditionsConverter.java	                        (rev 0)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/ecal/EcalConditionsConverter.java	2013-12-03 21:35:47 UTC (rev 61)
@@ -0,0 +1,72 @@
+package org.hps.conditions.ecal;
+
+import static org.hps.conditions.ConditionsConstants.ECAL_BAD_CHANNELS;
+import static org.hps.conditions.ConditionsConstants.ECAL_CALIBRATIONS;
+import static org.hps.conditions.ConditionsConstants.ECAL_CHANNELS;
+import static org.hps.conditions.ConditionsConstants.ECAL_GAINS;
+
+import java.util.Map.Entry;
+
+import org.lcsim.conditions.ConditionsManager;
+import org.hps.conditions.DatabaseConditionsConverter;
+
+/**
+ * This class loads all ecal conditions into an {@link EcalConditions} object
+ * from the database, based on the current run number known by the conditions manager.
+ * @author Jeremy McCormick <[log in to unmask]>
+ */
+public class EcalConditionsConverter extends DatabaseConditionsConverter<EcalConditions> {
+       
+    /**
+     * Create ECAL conditions object containing all data for the current run.
+     */
+    public EcalConditions getData(ConditionsManager manager, String name) {
+        
+        // Create new, empty conditions object to fill with data.
+        EcalConditions conditions = new EcalConditions();
+                               
+        // Get the channel information from the database.                
+        EcalChannelMap channelMap = manager.getCachedConditions(EcalChannelMap.class, ECAL_CHANNELS).getCachedData();
+        
+        // Set the channel map.
+        conditions.setChannelMap(channelMap);
+                                       
+        // Add gains.
+        EcalGainCollection gains = manager.getCachedConditions(EcalGainCollection.class, ECAL_GAINS).getCachedData();        
+        for (Entry<Integer,EcalGain> entry : gains.entrySet()) {
+            EcalChannel channel = channelMap.get(entry.getKey());
+            EcalGain gain = entry.getValue();
+            conditions.getChannelConstants(channel).setGain(gain);
+        }
+        
+        // Add bad channels.
+        EcalBadChannelCollection badChannels = manager.getCachedConditions(
+                EcalBadChannelCollection.class, ECAL_BAD_CHANNELS).getCachedData();
+        for (Integer badChannel : badChannels) {
+            EcalChannel channel = channelMap.get(badChannel);
+            conditions.getChannelConstants(channel).setBadChannel(true);
+        }
+        
+        // Add calibrations including pedestal and noise values.
+        EcalCalibrationCollection calibrations = 
+                manager.getCachedConditions(EcalCalibrationCollection.class, ECAL_CALIBRATIONS).getCachedData();
+        for (Entry<Integer,EcalCalibration> entry : calibrations.entrySet()) {
+            EcalChannel channel = channelMap.get(entry.getKey());
+            EcalCalibration calibration = entry.getValue();
+            conditions.getChannelConstants(channel).setCalibration(calibration);
+        }       
+        
+        // Return the conditions object to caller.
+        return conditions;
+    }
+
+    /**
+     * Get the type handled by this converter.
+     * @return The type handled by this converter.
+     */
+    public Class<EcalConditions> getType() {
+        return EcalConditions.class;
+    }
+    
+    
+}

java/trunk/conditions/src/main/java/org/hps/conditions/ecal
EcalConditionsLoader.java added at 61
--- java/trunk/conditions/src/main/java/org/hps/conditions/ecal/EcalConditionsLoader.java	                        (rev 0)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/ecal/EcalConditionsLoader.java	2013-12-03 21:35:47 UTC (rev 61)
@@ -0,0 +1,67 @@
+package org.hps.conditions.ecal;
+
+import java.util.List;
+
+import org.lcsim.detector.converter.compact.EcalCrystal;
+import org.lcsim.geometry.Detector;
+
+/**
+ * Load {@link SvtConditions} data onto <code>HpsSiSensor</code> objects.
+ * @author Jeremy McCormick <[log in to unmask]>
+ */
+public class EcalConditionsLoader {
+    
+    /**
+     * Load ECal conditions data onto a detector object.
+     * @param detector The detector object.
+     * @param conditions The conditions object.
+     */
+    public void load(Detector detector, EcalConditions conditions) {
+        
+        // Find EcalCrystal objects.        
+        List<EcalCrystal> crystals = detector.getDetectorElement().findDescendants(EcalCrystal.class);
+        
+        // Get the full channel map created by the conditions system.
+        EcalChannelMap channelMap = conditions.getChannelMap();
+                
+        // Loop over crystals.
+        for (EcalCrystal crystal : crystals) {
+            
+            // Reset possibly existing conditions data.
+            crystal.reset();
+            
+            // Find the corresponding entry in the channel map for this crystal.
+            EcalChannel channel = channelMap.find(crystal.getX(), crystal.getY());            
+            if (channel == null) {
+                throw new RuntimeException("EcalChannel not found for crystal: " + crystal.getName());
+            }
+            
+            // Set the crate.
+            crystal.setCrate(channel.getCrate());
+            
+            // Set the slot.
+            crystal.setSlot(channel.getSlot());
+            
+            // Set the channel number.
+            crystal.setChannel(channel.getChannel());
+            
+            // Get the channel constants.
+            EcalChannelConstants constants = conditions.getChannelConstants(channel);
+            if (constants == null) {
+                throw new RuntimeException("EcalChannelConstants not found for crystal: " + crystal.getName());
+            }
+                        
+            // Set bad channel.
+            crystal.setBadChannel(constants.isBadChannel());
+            
+            // Set pedestal.
+            crystal.setPedestal(constants.getCalibration().getPedestal());
+            
+            // Set noise.
+            crystal.setNoise(constants.getCalibration().getNoise());
+            
+            // Set gain.
+            crystal.setGain(constants.getGain().getGain());
+        }
+    }
+}
\ No newline at end of file

java/trunk/conditions/src/main/java/org/hps/conditions/ecal
EcalGain.java added at 61
--- java/trunk/conditions/src/main/java/org/hps/conditions/ecal/EcalGain.java	                        (rev 0)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/ecal/EcalGain.java	2013-12-03 21:35:47 UTC (rev 61)
@@ -0,0 +1,29 @@
+package org.hps.conditions.ecal;
+
+/**
+ * This class is a simplistic representation of gain values from the ECAL
+ * conditions database.     
+ * @author Jeremy McCormick <[log in to unmask]>
+ */
+class EcalGain {
+       
+    /** The gain value. */
+    private double gain;
+    
+    /**
+     * Fully qualified class constructor.
+     * @param id
+     * @param gain
+     */
+    EcalGain(double gain) {
+        this.gain = gain;
+    }
+    
+    /**
+     * Get the gain value.
+     * @return The gain value.
+     */
+    public double getGain() {
+        return gain;
+    }       
+}
\ No newline at end of file

java/trunk/conditions/src/main/java/org/hps/conditions/ecal
EcalGainCollection.java added at 61
--- java/trunk/conditions/src/main/java/org/hps/conditions/ecal/EcalGainCollection.java	                        (rev 0)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/ecal/EcalGainCollection.java	2013-12-03 21:35:47 UTC (rev 61)
@@ -0,0 +1,14 @@
+package org.hps.conditions.ecal;
+
+import java.util.LinkedHashMap;
+
+/**
+ * This class maps ECAL channel IDs from the database to ECal gain parameters.
+ */
+public class EcalGainCollection extends LinkedHashMap<Integer,EcalGain> {
+    /**
+     * Class constructor.
+     */
+    EcalGainCollection() {        
+    }
+}

java/trunk/conditions/src/main/java/org/hps/conditions/ecal
EcalGainConverter.java added at 61
--- java/trunk/conditions/src/main/java/org/hps/conditions/ecal/EcalGainConverter.java	                        (rev 0)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/ecal/EcalGainConverter.java	2013-12-03 21:35:47 UTC (rev 61)
@@ -0,0 +1,74 @@
+package org.hps.conditions.ecal;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+import org.lcsim.conditions.ConditionsManager;
+import org.hps.conditions.ConditionsRecord;
+import org.hps.conditions.ConnectionManager;
+import org.hps.conditions.DatabaseConditionsConverter;
+
+/**
+ * This class creates an {@link EcalGainCollection} from the appropriate
+ * conditions database information.
+ */
+public class EcalGainConverter extends DatabaseConditionsConverter<EcalGainCollection> {
+
+    /**
+     * Create the collection from the conditions database.
+     * @param manager The conditions manager.
+     * @param name The name of the conditions set.
+     */
+    public EcalGainCollection getData(ConditionsManager manager, String name) {
+
+        // Collection to be returned to caller.
+        EcalGainCollection gains = new EcalGainCollection();
+
+        // Get the ConditionsRecord with the meta-data, which will use the
+        // current run number from the manager.
+        ConditionsRecord record = ConditionsRecord.find(manager, name).get(0);
+
+        // Get the table name, field name, and field value defining the
+        // applicable conditions.
+        String tableName = record.getTableName();
+        String fieldName = record.getFieldName();
+        int fieldValue = record.getFieldValue();
+
+        // References to database objects.
+        ConnectionManager connectionManager = getConnectionManager();
+
+        // Get the name of the current database being used.
+        String database = connectionManager.getConnectionParameters().getDatabase();
+
+        // Database query on ecal gain table.
+        String query = "SELECT ecal_channel_id, gain FROM " 
+                + tableName + " WHERE " 
+                + fieldName + " = " + fieldValue + " ORDER BY id ASC";
+
+        // Execute the query and get the results.
+        ResultSet resultSet = connectionManager.query(query);
+
+        try {
+            // Loop over the records.
+            while (resultSet.next()) {
+                // Create gain object from database record.
+                int channelId = resultSet.getInt(1);
+                double gain = resultSet.getDouble(2);
+                gains.put(channelId, new EcalGain(gain));
+            }
+        } catch (SQLException x) {
+            throw new RuntimeException("Database error.", x);
+        } 
+        
+        return gains;
+    }
+
+    /**
+     * Get the type handled by this converter.
+     * @return The type handled by this converter.
+     */
+    public Class<EcalGainCollection> getType() {
+        return EcalGainCollection.class;
+    }
+
+}

java/trunk/conditions/src/main/java/org/hps/conditions
package-info.java added at 61
--- java/trunk/conditions/src/main/java/org/hps/conditions/package-info.java	                        (rev 0)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/package-info.java	2013-12-03 21:35:47 UTC (rev 61)
@@ -0,0 +1,13 @@
+/**
+ * <p>
+ * The HPS conditions package provides facilities for accessing time dependent conditions
+ * for a detector at runtime using a framework built on the LCSim Conditions System package.
+ * The {@link DatabaseConditionsReader} has a set of converters for reading data from
+ * tables using SQL queries and creating appropriate, typed objects for them.
+ * </p>
+ * 
+ * <p>
+ * @author Jeremy McCormick <[log in to unmask]>
+ * </p>
+ */
+package org.hps.conditions;
\ No newline at end of file

java/trunk/conditions/src/main/java/org/hps/conditions/svt
ChannelConstants.java added at 61
--- java/trunk/conditions/src/main/java/org/hps/conditions/svt/ChannelConstants.java	                        (rev 0)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/svt/ChannelConstants.java	2013-12-03 21:35:47 UTC (rev 61)
@@ -0,0 +1,101 @@
+package org.hps.conditions.svt;
+
+/**
+ * This class represents the conditions for a single SVT channel.
+ * 
+ * @author Omar Moreno <[log in to unmask]>
+ * @author Jeremy McCormick <[log in to unmask]>
+ * @version $Id: ChannelConstants.java,v 1.5 2013/10/04 01:43:48 jeremy Exp $
+ */
+public class ChannelConstants {
+
+    private SvtCalibration calibration = null;
+    private SvtGain gain = null;
+    private PulseParameters pulseParameters = null;
+    private boolean badChannel = false;
+
+    /**
+     * Class constructor.
+     */
+    ChannelConstants() {
+    }    
+
+    /**
+     * Set the pulse parameters.
+     * @param pulseParameters The pulse parameters
+     */
+    void setPulseParameters(PulseParameters pulseParameters) {
+        this.pulseParameters = pulseParameters;
+    }
+    
+    /**
+     * Set the gain.
+     * @param gain The gain object.
+     */
+    void setGain(SvtGain gain) {
+        this.gain = gain;
+    }
+    
+    /**
+     * Set the calibration.
+     * @param calibration The calibration object.
+     */
+    void setCalibration(SvtCalibration calibration) {
+        this.calibration = calibration;
+    }      
+    
+    /**
+     * Set the bad channel flag.
+     * @param badChannel The bad channel flag value.
+     */
+    void setBadChannel(boolean badChannel) {
+        this.badChannel = badChannel;
+    }
+        
+    /**
+     * Check if this is a bad channel.
+     * @return True if channel is bad; false if not.
+     */
+    public boolean isBadChannel() {
+        return badChannel;
+    }
+        
+    /**
+     * Get the pulse parameters.
+     * @return The pulse parameters.
+     */
+    public PulseParameters getPulseParameters() {
+        return pulseParameters;
+    }
+    
+    /**
+     * Get the gain.
+     * @return The gain.
+     */
+    public SvtGain getGain() {
+        return gain;
+    }
+    
+    /**
+     * Get the calibration.
+     * @return The calibration.
+     */
+    public SvtCalibration getCalibration() {
+        return calibration;
+    }
+
+    /**
+     * Convert this object to a string.
+     * @return This object converted to a string.
+     */
+    public String toString() {
+        StringBuffer buffer = new StringBuffer();        
+        buffer.append(getCalibration());
+        buffer.append(", ");
+        buffer.append(getGain());
+        buffer.append(", ");
+        buffer.append(getPulseParameters());
+        return buffer.toString();
+    }
+}
+

java/trunk/conditions/src/main/java/org/hps/conditions/svt
PulseParameters.java added at 61
--- java/trunk/conditions/src/main/java/org/hps/conditions/svt/PulseParameters.java	                        (rev 0)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/svt/PulseParameters.java	2013-12-03 21:35:47 UTC (rev 61)
@@ -0,0 +1,80 @@
+package org.hps.conditions.svt;
+
+/**
+ * This class represents the pulse parameters for an SVT channel.
+ * @author Jeremy McCormick <[log in to unmask]>
+ */
+public class PulseParameters {
+    
+    double amplitude = Double.NaN;
+    double t0 = Double.NaN;
+    double tp = Double.NaN;
+    double chisq = Double.NaN;
+
+    /**
+     * Full qualified class constructor.
+     * @param amplitude The amplitude.
+     * @param t0 The start time.
+     * @param tp The shaping time.
+     * @param chisq The chisq of the measurement.
+     */
+    PulseParameters(double amplitude, double t0, double tp, double chisq) {
+        this.amplitude = amplitude;
+        this.t0 = t0;
+        this.tp = tp;
+        this.chisq = chisq;
+    }
+    
+    /**
+     * Get the amplitude.
+     * @return The amplifude.
+     */
+    double getAmplitude() {
+        return amplitude;
+    }
+    
+    /**
+     * Get the starting time.
+     * @return The starting time.
+     */
+    double getT0() {
+        return t0;
+    }
+    
+    /**
+     * Get the time shift.
+     * @return The time shift.
+     */
+    double getTimeShift() {
+        return tp;
+    }
+    
+    /**
+     * Get the chisq.
+     * @return The chisq.
+     */
+    double getChisq() {
+        return chisq;
+    }
+    
+    /**
+     * Convert this object to a human readable string.
+     * @return This object converted to a string.
+     */
+    public String toString() {
+        return "amp: " + amplitude + ", t0: " + t0 + ", shift: " + tp + ", chisq: " + chisq;
+    }
+    
+    /**
+     * Convert this object to an array of doubles.
+     * @return This object converted to an array of doubles.
+     */
+    public double[] toArray() {
+        double[] values = new double[4];
+        values[0] = amplitude;
+        values[1] = t0;
+        values[2] = tp;
+        values[3] = chisq;
+        return values;
+    }
+}

java/trunk/conditions/src/main/java/org/hps/conditions/svt
PulseParametersCollection.java added at 61
--- java/trunk/conditions/src/main/java/org/hps/conditions/svt/PulseParametersCollection.java	                        (rev 0)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/svt/PulseParametersCollection.java	2013-12-03 21:35:47 UTC (rev 61)
@@ -0,0 +1,12 @@
+package org.hps.conditions.svt;
+
+import java.util.LinkedHashMap;
+
+/**
+ * A collection of {@link PulseParameters} objects stored by SVT channel ID.
+ * @author Jeremy McCormick <[log in to unmask]>
+ */
+public class PulseParametersCollection extends LinkedHashMap<Integer,PulseParameters> {
+    PulseParametersCollection() {        
+    }
+}

java/trunk/conditions/src/main/java/org/hps/conditions/svt
PulseParametersConverter.java added at 61
--- java/trunk/conditions/src/main/java/org/hps/conditions/svt/PulseParametersConverter.java	                        (rev 0)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/svt/PulseParametersConverter.java	2013-12-03 21:35:47 UTC (rev 61)
@@ -0,0 +1,81 @@
+package org.hps.conditions.svt;
+
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+import org.lcsim.conditions.ConditionsManager;
+import org.hps.conditions.ConditionsRecord;
+import org.hps.conditions.ConnectionManager;
+import org.hps.conditions.DatabaseConditionsConverter;
+
+/**
+ * This class creates a {@link PulseParametersCollection} object from the
+ * conditions database.
+ * 
+ * @author Jeremy McCormick <[log in to unmask]>
+ */
+public class PulseParametersConverter extends DatabaseConditionsConverter<PulseParametersCollection> {
+
+    /**
+     * Get the pulse parameters by channel for this run by named conditions set.
+     * @param manager The current conditions manager.
+     * @param name The name of the conditions set.
+     * @return The channel constants data.
+     */
+    public PulseParametersCollection getData(ConditionsManager manager, String name) {
+
+        // Get the ConditionsRecord with the meta-data, which will use the
+        // current run number from the manager.s
+        ConditionsRecord record = ConditionsRecord.find(manager, name).get(0);
+
+        // Get the table name, field name, and field value defining the
+        // applicable conditions.
+        String tableName = record.getTableName();
+        String fieldName = record.getFieldName();
+        int fieldValue = record.getFieldValue();
+
+        // Object for building the return value.
+        PulseParametersCollection collection = new PulseParametersCollection();
+
+        // Connection objects.
+        ConnectionManager connectionManager = getConnectionManager();
+
+        // Get the name of the current database being used.
+        String database = connectionManager.getConnectionParameters().getDatabase();
+
+        // Construct the query to find matching calibration records.
+        String query = "SELECT svt_channel_id, amplitude, t0, tp, chisq FROM " 
+                + tableName + " WHERE " 
+                + fieldName + " = " + fieldValue + " ORDER BY id ASC";
+
+        // Execute the query and get the results.
+        ResultSet resultSet = connectionManager.query(query);
+        
+        try {
+            // Loop over the calibration records.
+            while (resultSet.next()) {
+                // Create calibration object from database record.
+                int channelId = resultSet.getInt(1);
+                double amplitude = resultSet.getDouble(2);
+                double t0 = resultSet.getDouble(3);
+                double tp = resultSet.getDouble(4);
+                double chisq = resultSet.getDouble(5);
+                collection.put(channelId, new PulseParameters(amplitude, t0, tp, chisq));
+            }
+        } catch (SQLException x) {
+            throw new RuntimeException("Database error.", x);
+        }
+        
+        // Return the collection of channel constants to caller.
+        return collection;
+    }
+
+    /**
+     * Get the type handled by this converter.
+     * @return The type handled by this converter, which is <code>ConditionsRecordCollection</code>.
+     */
+    public Class<PulseParametersCollection> getType() {
+        return PulseParametersCollection.class;
+    }
+}

java/trunk/conditions/src/main/java/org/hps/conditions/svt
SvtBadChannelCollection.java added at 61
--- java/trunk/conditions/src/main/java/org/hps/conditions/svt/SvtBadChannelCollection.java	                        (rev 0)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/svt/SvtBadChannelCollection.java	2013-12-03 21:35:47 UTC (rev 61)
@@ -0,0 +1,11 @@
+package org.hps.conditions.svt;
+
+import org.hps.conditions.ChannelCollection;
+
+/**
+ * This class represents a set of bad channels in the SVT by their channel IDs
+ * from the conditions database.
+ * @author Jeremy McCormick <[log in to unmask]>
+ */
+public class SvtBadChannelCollection extends ChannelCollection {
+}

java/trunk/conditions/src/main/java/org/hps/conditions/svt
SvtBadChannelConverter.java added at 61
--- java/trunk/conditions/src/main/java/org/hps/conditions/svt/SvtBadChannelConverter.java	                        (rev 0)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/svt/SvtBadChannelConverter.java	2013-12-03 21:35:47 UTC (rev 61)
@@ -0,0 +1,69 @@
+package org.hps.conditions.svt;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+import org.lcsim.conditions.ConditionsManager;
+import org.hps.conditions.ConditionsRecord;
+import org.hps.conditions.ConditionsRecordCollection;
+import org.hps.conditions.ConnectionManager;
+import org.hps.conditions.DatabaseConditionsConverter;
+
+/**
+ * This class creates an {@link SvtBadChannelCollection} representing bad readout channels
+ * in the SVT.
+ * @author Jeremy McCormick <[log in to unmask]>
+ */
+public class SvtBadChannelConverter extends DatabaseConditionsConverter<SvtBadChannelCollection> {
+
+    /**
+     * Create the collection from the conditions database. 
+     * @param manager The conditions manager.
+     * @param name The name of the conditions set.
+     */
+    public SvtBadChannelCollection getData(ConditionsManager manager, String name) {
+
+        // Collection to be returned to caller.
+        SvtBadChannelCollection badChannels = new SvtBadChannelCollection();
+
+        // Get the ConditionsRecord with the meta-data, which will use the
+        // current run number from the manager.
+        ConditionsRecordCollection records = ConditionsRecord.find(manager, name);
+
+        // Loop over ConditionsRecords.  For this particular type of condition, multiple
+        // sets of bad channels are possible.
+        for (ConditionsRecord record : records) {
+        
+            // Get the table name, field name, and field value defining the
+            // applicable conditions.
+            String tableName = record.getTableName();
+            String fieldName = record.getFieldName();
+            int fieldValue = record.getFieldValue();
+
+            // Query for getting back bad channel records.
+            String query = "SELECT svt_channel_id FROM " + tableName + " WHERE " 
+                    + fieldName + " = " + fieldValue + " ORDER BY id ASC";
+            ResultSet resultSet = ConnectionManager.getConnectionManager().query(query);
+            
+            // Loop over the records.
+            try {
+                while (resultSet.next()) {
+                    int channelId = resultSet.getInt(1);
+                    badChannels.add(channelId);
+                }
+            } catch (SQLException x) {
+                throw new RuntimeException(x);
+            } 
+        }
+               
+        return badChannels;
+    }
+
+    /**
+     * Get the type handled by this converter.
+     * @return The type handled by this converter.
+     */
+    public Class<SvtBadChannelCollection> getType() {
+        return SvtBadChannelCollection.class;
+    }
+}

java/trunk/conditions/src/main/java/org/hps/conditions/svt
SvtCalibration.java added at 61
--- java/trunk/conditions/src/main/java/org/hps/conditions/svt/SvtCalibration.java	                        (rev 0)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/svt/SvtCalibration.java	2013-12-03 21:35:47 UTC (rev 61)
@@ -0,0 +1,45 @@
+package org.hps.conditions.svt;
+
+/**
+ * This class represents a noise and pedestal measurement for an SVT channel.
+ * @author Jeremy McCormick <[log in to unmask]>
+ */
+class SvtCalibration {
+    
+    double noise = Double.NaN;
+    double pedestal = Double.NaN;
+    
+    /**
+     * Fully qualified constructor.
+     * @param noise The noise value.
+     * @param pedestal The pedestal value.
+     */
+    SvtCalibration(double noise, double pedestal) {
+        this.noise = noise;
+        this.pedestal = pedestal;
+    }
+        
+    /**
+     * Get the noise value.
+     * @return The noise value.
+     */
+    public double getNoise() {
+        return noise;
+    }
+    
+    /**
+     * Get the pedestal value.
+     * @return The pedestal value.
+     */
+    public double getPedestal() {
+        return pedestal;
+    }
+    
+    /**
+     * Convert this object to a human readable string.
+     * @return This object converted to a string.
+     */
+    public String toString() {
+        return "noise: " + noise + ", pedestal: " + pedestal;
+    }
+}

java/trunk/conditions/src/main/java/org/hps/conditions/svt
SvtCalibrationCollection.java added at 61
--- java/trunk/conditions/src/main/java/org/hps/conditions/svt/SvtCalibrationCollection.java	                        (rev 0)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/svt/SvtCalibrationCollection.java	2013-12-03 21:35:47 UTC (rev 61)
@@ -0,0 +1,16 @@
+package org.hps.conditions.svt;
+
+import java.util.LinkedHashMap;
+
+/**
+ * This class is a collection of {@link SvtCalibration} objects associated to their 
+ * SVT channel IDs from the database.
+ * @author Jeremy McCormick <[log in to unmask]>
+ */
+public class SvtCalibrationCollection extends LinkedHashMap<Integer,SvtCalibration> {
+    /**
+     * Class constructor.
+     */
+    SvtCalibrationCollection() {        
+    }
+}

java/trunk/conditions/src/main/java/org/hps/conditions/svt
SvtCalibrationConverter.java added at 61
--- java/trunk/conditions/src/main/java/org/hps/conditions/svt/SvtCalibrationConverter.java	                        (rev 0)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/svt/SvtCalibrationConverter.java	2013-12-03 21:35:47 UTC (rev 61)
@@ -0,0 +1,85 @@
+package org.hps.conditions.svt;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+import org.lcsim.conditions.ConditionsManager;
+import org.hps.conditions.ConditionsRecord;
+import org.hps.conditions.ConnectionManager;
+import org.hps.conditions.DatabaseConditionsConverter;
+
+/**
+ * This class creates a {@link SvtCalibrationCollection} from the conditions
+ * database.
+ * @author Jeremy McCormick <[log in to unmask]>
+ */
+public class SvtCalibrationConverter extends DatabaseConditionsConverter<SvtCalibrationCollection> {
+
+    /**
+     * Class constructor.
+     */
+    public SvtCalibrationConverter() {
+    }
+
+    /**
+     * Get the SVT channel constants for this run by named set.     
+     * @param manager The current conditions manager.
+     * @param name The name of the conditions set.
+     * @return The channel constants data.
+     */
+    public SvtCalibrationCollection getData(ConditionsManager manager, String name) {
+
+        // Get the ConditionsRecord with the meta-data, which will use the
+        // current run number from the manager.
+        ConditionsRecord record = ConditionsRecord.find(manager, name).get(0);
+
+        // Get the table name, field name, and field value defining the
+        // applicable conditions.
+        String tableName = record.getTableName();
+        String fieldName = record.getFieldName();
+        int fieldValue = record.getFieldValue();
+
+        // Objects for building the return value.
+        SvtCalibrationCollection collection = new SvtCalibrationCollection();
+
+        // Get a connection from the manager.
+        ConnectionManager connectionManager = getConnectionManager();
+
+        // Construct the query to find matching calibration records using the ID
+        // field.
+        String query = "SELECT svt_channel_id, noise, pedestal FROM " 
+                + tableName + " WHERE " 
+                + fieldName + " = " + fieldValue + " ORDER BY svt_channel_id ASC";
+
+        // Execute the query and get the results.
+        ResultSet resultSet = connectionManager.query(query);
+
+        try {
+            // Loop over the calibration records.
+            while (resultSet.next()) {
+
+                // Get the calibration data for a single channel.
+                int channelId = resultSet.getInt(1);
+                double noise = resultSet.getDouble(2);
+                double pedestal = resultSet.getDouble(3);
+
+                collection.put(channelId, new SvtCalibration(noise, pedestal));
+            }
+        } catch (SQLException x) {
+            throw new RuntimeException("Database error.", x);
+        } 
+        
+        // Return the collection of channel constants to caller.
+        return collection;
+    }
+
+    /**
+     * Get the type handled by this converter.
+     * 
+     * @return The type handled by this converter, which is
+     *         <code>ConditionsRecordCollection</code>.
+     */
+    public Class<SvtCalibrationCollection> getType() {
+        return SvtCalibrationCollection.class;
+    }
+}
\ No newline at end of file

java/trunk/conditions/src/main/java/org/hps/conditions/svt
SvtChannel.java added at 61
--- java/trunk/conditions/src/main/java/org/hps/conditions/svt/SvtChannel.java	                        (rev 0)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/svt/SvtChannel.java	2013-12-03 21:35:47 UTC (rev 61)
@@ -0,0 +1,83 @@
+package org.hps.conditions.svt;
+
+/**
+ * This class represents SVT channel setup information, including hybrid, FPGA, and channel numbers.
+ * @author Jeremy McCormick <[log in to unmask]>
+ */
+public class SvtChannel {
+
+    /** Channel data. */
+    private int id, hybrid, fpga, channel;
+    
+    /**
+     * Fully qualified constructor.
+     * @param id The database record ID from the channel table.
+     * @param fpga The FPGA number (0 to 6).
+     * @param hybrid The hybrid number (0 to 2).
+     * @param channel The channel number (0 to 639).
+     */
+    SvtChannel(int id, int fpga, int hybrid, int channel) {
+        this.id = id;
+        this.fpga = fpga;
+        this.hybrid = hybrid;        
+        this.channel = channel;
+    }
+    
+    /**
+     * Get the channel ID.
+     * @return The channel ID.
+     */
+    public int getId() {
+        return id;
+    }
+    
+    /**
+     * Get the hybrid number.
+     * @return The hybrid number.
+     */
+    public int getHybrid() {
+        return hybrid;
+    }
+    
+    /**
+     * Get the FPGA number.
+     * @return The FPGA number.
+     */
+    public int getFpga() {
+        return fpga;
+    }
+    
+    /**
+     * Get the channel number.  This is different from the ID.
+     * @return The channel number.
+     */
+    public int getChannel() {
+        return channel;
+    }    
+    
+    /**
+     * Convert this object to a human readable string.
+     * @return This object as a string.
+     */
+    public String toString() {
+        return "id: " + id + ", fpga: " + fpga + ", hybrid: " + hybrid + ", channel: " + channel;
+    }
+    
+    /**
+     * Implementation of equals.
+     * @return True if the object equals this one; false if not.
+     */
+    public boolean equals(Object o) {
+        if (o == null)
+            return false;
+        if (!(o instanceof SvtChannel))
+            return false;
+        if (o == this)
+            return true;
+        SvtChannel channel = (SvtChannel)o;
+        return id == channel.getId() 
+                && hybrid == channel.getHybrid() 
+                && fpga == channel.getFpga() 
+                && hybrid == channel.getHybrid();
+    }    
+}
\ No newline at end of file

java/trunk/conditions/src/main/java/org/hps/conditions/svt
SvtChannelMap.java added at 61
--- java/trunk/conditions/src/main/java/org/hps/conditions/svt/SvtChannelMap.java	                        (rev 0)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/svt/SvtChannelMap.java	2013-12-03 21:35:47 UTC (rev 61)
@@ -0,0 +1,53 @@
+package org.hps.conditions.svt;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+
+import org.lcsim.hps.util.Pair;
+
+/**
+ * This class represents a map between SVT channels and their IDs from the channels table
+ * in the conditions database.  It can be used to lookup information stored in the {@link SvtConditions} object.
+ * @author Jeremy McCormick <[log in to unmask]>
+ */
+public class SvtChannelMap extends HashMap<Integer,SvtChannel> {
+    
+    /**
+     * Constructor, which is package protected.  Users should not 
+     * create this class directly but retrieve it from the {@link SvtConditions}
+     * object instead.
+     */
+    SvtChannelMap() {
+    }
+    
+    /**
+     * Find channels that match a DAQ pair (FPGA, hybrid).
+     * @param pair The DAQ pair.
+     * @return The channels matching the DAQ pair or null if not found.
+     */
+    public Collection<SvtChannel> find(Pair<Integer,Integer> pair) {
+        List<SvtChannel> channels = new ArrayList<SvtChannel>(); 
+        int fpga = pair.getFirstElement();
+        int hybrid = pair.getSecondElement();
+        for (SvtChannel channel : values()) {
+            if (channel.getFpga() == fpga && channel.getHybrid() == hybrid) {
+                channels.add(channel);
+            }
+        }
+        return channels;
+    }
+               
+    /**
+     * Convert this object to a human readable string.
+     * @return This object converted to a string.
+     */
+    public String toString() {        
+        StringBuffer buff = new StringBuffer();
+        for (SvtChannel channel : values()) {
+            buff.append(channel.toString() + '\n');
+        }
+        return buff.toString();
+    }
+}

java/trunk/conditions/src/main/java/org/hps/conditions/svt
SvtChannelMapConverter.java added at 61
--- java/trunk/conditions/src/main/java/org/hps/conditions/svt/SvtChannelMapConverter.java	                        (rev 0)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/svt/SvtChannelMapConverter.java	2013-12-03 21:35:47 UTC (rev 61)
@@ -0,0 +1,65 @@
+package org.hps.conditions.svt;
+
+import static org.hps.conditions.ConditionsConstants.SVT_CHANNELS;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+import org.lcsim.conditions.ConditionsManager;
+import org.hps.conditions.ConnectionManager;
+import org.hps.conditions.DatabaseConditionsConverter;
+
+/**
+ * This class converts a table of SVT channel setup data into an {@link SvtChannelMap}.
+ * @author Jeremy McCormick <[log in to unmask]>
+ */
+public class SvtChannelMapConverter extends DatabaseConditionsConverter<SvtChannelMap> {
+
+    /**
+     * Create the channel map from the conditions database.
+     * @param manager The current conditions manager.
+     * @param name The name of the conditions set.
+     */
+    public SvtChannelMap getData(ConditionsManager manager, String name) {
+
+        // Objects for building the return value.
+        SvtChannelMap channels = new SvtChannelMap();
+
+        // Get the connection manager.
+        ConnectionManager connectionManager = getConnectionManager();
+
+        // Assign default key name for channel data if none given.
+        if (name == null)
+            name = SVT_CHANNELS;
+
+        // Construct the query to get the channel data.
+        String query = "SELECT id, fpga, hybrid, channel FROM " + name;
+
+        // Execute the query and get the results.
+        ResultSet resultSet = connectionManager.query(query);
+
+        try {
+            // Loop over records.
+            while (resultSet.next()) {
+                // Add SVT channel data for this record.
+                int id = resultSet.getInt(1);
+                int fpga = resultSet.getInt(2);
+                int hybrid = resultSet.getInt(3);
+                int channel = resultSet.getInt(4);
+                SvtChannel data = new SvtChannel(id, fpga, hybrid, channel);
+                channels.put(data.getId(), data);
+            }
+        } catch (SQLException x) {
+            throw new RuntimeException("Database error.", x);
+        } 
+        return channels;
+    }
+
+    /**
+     * Get the type handled by this converter.
+     * @return The type handled by this converter.
+     */
+    public Class<SvtChannelMap> getType() {
+        return SvtChannelMap.class;
+    }
+}

java/trunk/conditions/src/main/java/org/hps/conditions/svt
SvtConditions.java added at 61
--- java/trunk/conditions/src/main/java/org/hps/conditions/svt/SvtConditions.java	                        (rev 0)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/svt/SvtConditions.java	2013-12-03 21:35:47 UTC (rev 61)
@@ -0,0 +1,171 @@
+package org.hps.conditions.svt;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * This class contains all SVT conditions data by readout channel.
+ * {@link SvtChannel} objects from the {@linkSvtChannelMap} should be 
+ * used to lookup the conditions using the {@link #getChannelConstants(SvtChannel)} method.
+ * 
+ * @author Jeremy McCormick <[log in to unmask]>
+ * @version $Id: SvtConditions.java,v 1.11 2013/10/15 23:45:56 jeremy Exp $
+ */
+public class SvtConditions {
+    
+    /** SVT conditions data. */
+    private Map<SvtChannel, ChannelConstants> channelData = new HashMap<SvtChannel, ChannelConstants>();
+    private SvtChannelMap channelMap = null;
+    private SvtDaqMap daqMap = null;
+    private SvtTimeShiftCollection timeShifts = null;
+    
+    /**
+     * Class constructor, which takes a channel map.
+     * @param channelMap The SVT channel map.
+     */
+    SvtConditions(SvtChannelMap channelMap) {
+        this.channelMap = channelMap;
+    }     
+        
+    /**
+     * Get the conditions constants for a specific channel.  These will be
+     * created if they do not exist for the given channel, BUT only channels
+     * in the current channel map are allowed as an argument.
+     * @param channel The SVT channel.
+     * @return The conditions constants for the channel.
+     * @throws IllegalArgumentException if .
+     */
+    public ChannelConstants getChannelConstants(SvtChannel channel) {
+        // This channel must come from the map.
+        if (!channelMap.containsValue(channel)) {
+            System.err.println("Channel not found in map => " + channel);
+            throw new IllegalArgumentException("Channel was not found in map.");
+        }
+        // If channel has no data yet, then add it.
+        if (!channelData.containsKey(channel))
+            channelData.put(channel, new ChannelConstants());
+        return channelData.get(channel);
+    }         
+        
+    /**
+     * Get the {@link SvtChannelMap} for this set of conditions.
+     * @return The SVT channel map.
+     */
+    public SvtChannelMap getChannelMap() {
+        return channelMap;
+    }
+    
+    /**
+     * Get the {@link SvtDaqMap} associated with these conditions.
+     * @return The SVT DAQ map.
+     */
+    public SvtDaqMap getDaqMap() {
+        return daqMap;
+    }
+    
+    /**
+     * Get the {@link SvtTimeShiftCollection}.
+     * @return The time shifts by sensor.
+     */
+    public SvtTimeShiftCollection getTimeShifts() {
+        return timeShifts;
+    }
+    
+    /**
+     * Set the {@link SvtDaqMap} associated with these conditions.
+     * @param daqMap The SVT DAQ map.
+     */
+    void setDaqMap(SvtDaqMap daqMap) {
+        this.daqMap = daqMap;
+    }
+    
+    /**
+     * Set the sensor time shifts.
+     * @param timeShifts The sensor time shifts collection.
+     */
+    void setTimeShifts(SvtTimeShiftCollection timeShifts) {
+        this.timeShifts = timeShifts;
+    }
+            
+    /**
+     * Convert this object to a human readable string.  This method prints a formatted table 
+     * of channel data independently of how its member objects implement their string conversion method. 
+     * For now, it does not print the time shifts by sensor as all other information is by channel.
+     * @return This object converted to a string, without the DAQ map.
+     */
+    public String toString() {
+        StringBuffer buff = new StringBuffer();
+        
+        buff.append('\n');
+        buff.append("Printing SVTConditions ...");
+        buff.append('\n');
+        buff.append('\n');
+        
+        // Table header:
+        buff.append("id");
+        buff.append("     ");
+        buff.append("fpga");
+        buff.append("  ");
+        buff.append("hybrid");
+        buff.append("   ");
+        buff.append("channel");
+        buff.append("  ");
+        buff.append("noise");
+        buff.append("     ");
+        buff.append("pedestal");
+        buff.append("    ");
+        buff.append("gain");
+        buff.append("   ");
+        buff.append("offset");
+        buff.append("    ");
+        buff.append("amplitude");
+        buff.append("  ");
+        buff.append("t0");
+        buff.append("       ");
+        buff.append("shift");
+        buff.append("    ");
+        buff.append("chisq");
+        buff.append("      ");
+        buff.append("bad");
+        buff.append('\n'); 
+        for (int i=0; i<115; i++) {
+            buff.append("-");
+        }        
+        buff.append('\n');
+        // Loop over channels.
+        for (SvtChannel channel : channelMap.values()) {
+            
+            // Get the conditions for the channel.
+            ChannelConstants constants = getChannelConstants(channel);
+            SvtGain gain = constants.getGain();
+            PulseParameters pulse = constants.getPulseParameters();
+            SvtCalibration calibration = constants.getCalibration();
+            
+            // Channel data.
+            buff.append(String.format("%-6d %-5d %-8d %-8d ", channel.getId(), channel.getFpga(), channel.getHybrid(), channel.getChannel()));
+
+            // Calibration.
+            buff.append(String.format("%-9.4f %-11.4f ", calibration.getNoise(), calibration.getPedestal()));
+            
+            // Gain.
+            buff.append(String.format("%-6.4f %-9.4f ", gain.getGain(), gain.getOffset()));
+            
+            // Pulse shape.
+            buff.append(String.format("%-10.4f %-8.4f %-8.4f %-10.4f ", pulse.getAmplitude(), pulse.getT0(), pulse.getTimeShift(), pulse.getChisq()));
+            
+            // Bad channel.
+            buff.append(constants.isBadChannel());
+            
+            buff.append('\n');                                  
+        }
+        
+        buff.append('\n');
+        buff.append("Printing SVT DAQ Map...");
+        buff.append('\n');
+        buff.append('\n');
+        buff.append(getDaqMap());
+        
+        return buff.toString();
+    }
+}
+

java/trunk/conditions/src/main/java/org/hps/conditions/svt
SvtConditionsConverter.java added at 61
--- java/trunk/conditions/src/main/java/org/hps/conditions/svt/SvtConditionsConverter.java	                        (rev 0)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/svt/SvtConditionsConverter.java	2013-12-03 21:35:47 UTC (rev 61)
@@ -0,0 +1,81 @@
+package org.hps.conditions.svt;
+
+import static org.hps.conditions.ConditionsConstants.SVT_BAD_CHANNELS;
+import static org.hps.conditions.ConditionsConstants.SVT_CALIBRATIONS;
+import static org.hps.conditions.ConditionsConstants.SVT_CHANNELS;
+import static org.hps.conditions.ConditionsConstants.SVT_DAQ_MAP;
+import static org.hps.conditions.ConditionsConstants.SVT_GAINS;
+import static org.hps.conditions.ConditionsConstants.SVT_PULSE_PARAMETERS;
+import static org.hps.conditions.ConditionsConstants.SVT_TIME_SHIFTS;
+
+import java.util.Map.Entry;
+
+import org.lcsim.conditions.ConditionsManager;
+import org.hps.conditions.DatabaseConditionsConverter;
+
+/**
+ * This class creates an {@link SvtConditions} object from the database,
+ * based on the current run number known by the conditions manager.
+ */
+public class SvtConditionsConverter extends DatabaseConditionsConverter<SvtConditions> {
+                     
+    /**
+     * Create and return the SVT conditions object.  
+     * @param manager The current conditions manager.
+     * @param name The conditions key, which is ignored for now.
+     */
+    public SvtConditions getData(ConditionsManager manager, String name) {
+                        
+        // Get the SVT channel map.
+        SvtChannelMap channels = manager.getCachedConditions(SvtChannelMap.class, SVT_CHANNELS).getCachedData();
+        
+        // Create the conditions object.
+        SvtConditions conditions = new SvtConditions(channels);
+        
+        // Create the DAQ map.
+        SvtDaqMap daqMap = manager.getCachedConditions(SvtDaqMap.class, SVT_DAQ_MAP).getCachedData();
+        conditions.setDaqMap(daqMap);
+                                               
+        // Add calibrations by channel.
+        SvtCalibrationCollection calibrations = manager.getCachedConditions(SvtCalibrationCollection.class, SVT_CALIBRATIONS).getCachedData();
+        for (Entry<Integer,SvtCalibration> entry : calibrations.entrySet()) {
+            SvtChannel channel = conditions.getChannelMap().get(entry.getKey());
+            conditions.getChannelConstants(channel).setCalibration(entry.getValue());
+        }  
+        
+        // Add pulse parameters by channel.
+        PulseParametersCollection pulseParameters = manager.getCachedConditions(PulseParametersCollection.class, SVT_PULSE_PARAMETERS).getCachedData();
+        for (Entry<Integer,PulseParameters> entry : pulseParameters.entrySet()) {
+            SvtChannel channel = conditions.getChannelMap().get(entry.getKey());
+            conditions.getChannelConstants(channel).setPulseParameters(entry.getValue());
+        }
+        
+        // Add bad channels.
+        SvtBadChannelCollection badChannels = manager.getCachedConditions(SvtBadChannelCollection.class, SVT_BAD_CHANNELS).getCachedData();        
+        for (Integer badChannel : badChannels) {
+            SvtChannel channel = conditions.getChannelMap().get(badChannel);
+            conditions.getChannelConstants(channel).setBadChannel(true);
+        }
+        
+        // Add gains by channel.
+        SvtGainCollection gains = manager.getCachedConditions(SvtGainCollection.class, SVT_GAINS).getCachedData();
+        for (Entry<Integer,SvtGain> entry : gains.entrySet()) {
+            SvtChannel channel = conditions.getChannelMap().get(entry.getKey());
+            conditions.getChannelConstants(channel).setGain(entry.getValue());
+        }
+        
+        // Set the time shifts by sensor.
+        SvtTimeShiftCollection timeShifts = manager.getCachedConditions(SvtTimeShiftCollection.class, SVT_TIME_SHIFTS).getCachedData();
+        conditions.setTimeShifts(timeShifts);
+        
+        return conditions;    
+    }
+
+    /**
+     * Get the type handled by this converter.
+     * @return The type handled by this converter.
+     */
+    public Class<SvtConditions> getType() {
+        return SvtConditions.class;
+    }    
+}

java/trunk/conditions/src/main/java/org/hps/conditions/svt
SvtConditionsLoader.java added at 61
--- java/trunk/conditions/src/main/java/org/hps/conditions/svt/SvtConditionsLoader.java	                        (rev 0)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/svt/SvtConditionsLoader.java	2013-12-03 21:35:47 UTC (rev 61)
@@ -0,0 +1,83 @@
+package org.hps.conditions.svt;
+
+import java.util.Collection;
+import java.util.List;
+
+import org.lcsim.detector.tracker.silicon.HpsSiSensor;
+import org.lcsim.geometry.Detector;
+import org.lcsim.hps.util.Pair;
+
+/**
+ * This class loads {@link SvtConditions} data onto <code>HpsSiSensor</code> objects.
+ * @author Jeremy McCormick <[log in to unmask]>
+ */
+public class SvtConditionsLoader {
+    
+    /**
+     * Load conditions data onto a detector object.
+     * This method is analogous to {@link org.lcsim.hps.recon.tracking.SvtUtils#setup(Detector)}.
+     * @param detector The detector object.
+     * @param conditions The conditions object.
+     */
+    public void load(Detector detector, SvtConditions conditions) {
+        
+        // Find sensor objects.        
+        List<HpsSiSensor> sensors = detector.getDetectorElement().findDescendants(HpsSiSensor.class);
+        SvtChannelMap channelMap = conditions.getChannelMap();
+        SvtDaqMap daqMap = conditions.getDaqMap();
+        SvtTimeShiftCollection timeShifts = conditions.getTimeShifts();
+        
+        // Loop over sensors.
+        for (HpsSiSensor sensor : sensors) {
+            
+            // Reset possible existing conditions data on sensor.
+            sensor.reset();
+            
+            // Get the layer number.
+            int layerNumber = sensor.getLayerNumber();
+            
+            // Get info from the DAQ map about this sensor. 
+            Pair<Integer, Integer> daqPair = null;            
+            int half = SvtDaqMap.TOP;
+            if (sensor.isBottomLayer()) {
+                half = SvtDaqMap.BOTTOM;
+            }             
+            daqPair = daqMap.get(half, layerNumber);
+            if (daqPair == null) {
+                throw new RuntimeException("Failed to find DAQ pair for sensor: " + sensor.getName());
+            }
+            
+            // Set FPGA value from DAQ map.
+            sensor.setFpgaNumber(daqPair.getFirstElement());
+            
+            // Set hybrid value from DAQ map.
+            sensor.setHybridNumber(daqPair.getSecondElement());
+            
+            // Find all the channels for this sensor.
+            Collection<SvtChannel> channels = channelMap.find(daqPair);
+                        
+            // Loop over the channels of the sensor.
+            for (SvtChannel channel : channels) {
+                // Get conditions data for this channel.
+                ChannelConstants constants = conditions.getChannelConstants(channel);
+                int channelNumber = channel.getChannel();
+                
+                //
+                // Set conditions data for this channel on the sensor object:
+                //
+                if (constants.isBadChannel()) {
+                    sensor.setBadChannel(channelNumber);
+                }
+                sensor.setGain(channelNumber, constants.getGain().getGain());
+                sensor.setTimeOffset(channelNumber, constants.getGain().getOffset());
+                sensor.setNoise(channelNumber, constants.getCalibration().getNoise());
+                sensor.setPedestal(channelNumber, constants.getCalibration().getPedestal());
+                sensor.setPulseParameters(channelNumber, constants.getPulseParameters().toArray());
+            }
+            
+            // Set the time shift for the sensor.
+            SvtTimeShift sensorTimeShift = timeShifts.find(daqPair).get(0);
+            sensor.setTimeShift(sensorTimeShift.getTimeShift());
+        }
+    }
+}

java/trunk/conditions/src/main/java/org/hps/conditions/svt
SvtDaqMap.java added at 61
--- java/trunk/conditions/src/main/java/org/hps/conditions/svt/SvtDaqMap.java	                        (rev 0)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/svt/SvtDaqMap.java	2013-12-03 21:35:47 UTC (rev 61)
@@ -0,0 +1,93 @@
+package org.hps.conditions.svt;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.lcsim.hps.util.Pair;
+
+/**
+ * This class establishes the mapping between layer numbers and DAQ pair (FPGA, hybrid)
+ * for the top and bottom halves of the detector. 
+ * @author Jeremy McCormick <[log in to unmask]>
+ */
+public class SvtDaqMap {
+
+    /**
+     * Flag values for top or bottom half.
+     * FIXME: This should probably be an enum but it is simpler to use int values for now.  
+     */
+    static final int TOP = 0;
+    static final int BOTTOM = 1;    
+      
+    /**
+     * This is the data structure used for the mapping of layer numbers to DAQ pair by top or bottom half.
+     * The mapping is the following: half => layer => pair(fpga, hybrid)
+     */
+    @SuppressWarnings("serial")
+    static private class LayerMap extends HashMap<Integer,HashMap<Integer,Pair<Integer,Integer>>> {        
+    }
+     
+    /**
+     * Object that holds the DAQ map data.
+     */
+    LayerMap layerMap = new LayerMap();
+    
+    /**
+     * Class constructor.
+     */
+    SvtDaqMap() {
+        layerMap.put(TOP, new HashMap<Integer,Pair<Integer,Integer>>());
+        layerMap.put(BOTTOM, new HashMap<Integer,Pair<Integer,Integer>>());
+    }
+     
+    /**
+     * Add a record to the DAQ map.
+     * @param half The value indicating top or bottom half of the detector.
+     * @param layerNumber The layer number.
+     */
+    void add(int half, int layerNumber, Pair<Integer,Integer> pair) {
+        layerMap.get(half).put(layerNumber, pair);
+    }
+    
+    /**
+     * Get a DAQ pair (FPGA, hybrid) by layer number.
+     * @param half Value indicating top or bottom half of detector.
+     * @param layerNumber The layer number.
+     * @return The DAQ pair for the half and layer number or null if does not exist.
+     */
+    Pair<Integer,Integer> get(int half, int layerNumber) {
+        return layerMap.get(half).get(layerNumber);
+    }    
+    
+    /**
+     * Convert this object to a string.
+     * @return This object converted to a string.
+     */
+    public String toString() {
+        StringBuffer buff = new StringBuffer();
+        buff.append("half");
+        buff.append(" ");
+        buff.append("layer");
+        buff.append(" ");
+        buff.append("fpga");
+        buff.append(" ");
+        buff.append("hybrid");
+        buff.append('\n');
+        buff.append("----------------------");
+        buff.append('\n');
+        for (int half : layerMap.keySet()) {
+            Map<Integer,Pair<Integer,Integer>> map = layerMap.get(half);
+            for (Map.Entry<Integer, Pair<Integer,Integer>> entry : map.entrySet()) {
+                buff.append(half);
+                buff.append("    ");
+                buff.append(String.format("%-2d", entry.getKey()));
+                buff.append("    ");                
+                buff.append(entry.getValue().getFirstElement());
+                buff.append("    ");
+                buff.append(entry.getValue().getSecondElement());
+                buff.append('\n');
+            }
+        }        
+        return buff.toString();
+    }    
+}

java/trunk/conditions/src/main/java/org/hps/conditions/svt
SvtDaqMapConverter.java added at 61
--- java/trunk/conditions/src/main/java/org/hps/conditions/svt/SvtDaqMapConverter.java	                        (rev 0)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/svt/SvtDaqMapConverter.java	2013-12-03 21:35:47 UTC (rev 61)
@@ -0,0 +1,81 @@
+package org.hps.conditions.svt;
+
+import static org.hps.conditions.ConditionsConstants.SVT_DAQ_MAP;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+import org.lcsim.conditions.ConditionsManager;
+import org.hps.conditions.ConditionsRecord;
+import org.hps.conditions.ConnectionManager;
+import org.hps.conditions.DatabaseConditionsConverter;
+import org.lcsim.hps.util.Pair;
+
+/**
+ * This class creates a {@link SvtDaqMap} from the conditions database.
+ * @author Jeremy McCormick <[log in to unmask]>
+ */
+public class SvtDaqMapConverter extends DatabaseConditionsConverter<SvtDaqMap> {
+
+    /**
+     * Create an {@link SvtDaqMap} object from the database.
+     */
+    public SvtDaqMap getData(ConditionsManager manager, String name) {
+        
+        // Use default key name if not set.
+        if (name == null) {
+            name = SVT_DAQ_MAP;
+        }
+        
+        // The object to be returned to caller.
+        SvtDaqMap daqMap = new SvtDaqMap();
+        
+        // Get the ConditionsRecord with the meta-data, which will use the current run number from the manager.
+        ConditionsRecord record = ConditionsRecord.find(manager, name).get(0);
+               
+        // Get the table name, field name, and field value defining the applicable conditions.
+        String tableName = record.getTableName();
+        String fieldName = record.getFieldName();
+        int fieldValue = record.getFieldValue();
+                        
+        // Get the connection manager.
+        ConnectionManager connectionManager = ConnectionManager.getConnectionManager();
+                                                                                            
+        // Construct the query to find matching calibration records using the ID field.
+        String query = "SELECT half, layer, hybrid, fpga FROM "
+                + tableName + " WHERE " + fieldName + " = " + fieldValue
+                + " ORDER BY half ASC, layer ASC";
+                   
+        // Execute the query and get the results.
+        ResultSet resultSet = connectionManager.query(query);
+               
+        try {
+            // Loop over the database records.
+            while(resultSet.next()) {          
+                
+                // Get record data.
+                int half = resultSet.getInt(1);
+                int layer = resultSet.getInt(2);
+                int hybrid = resultSet.getInt(3);
+                int fpga = resultSet.getInt(4);
+                                
+                // Add data to DAQ map: half => layer => DAQ pair               
+                daqMap.add(half, layer, new Pair<Integer,Integer>(fpga, hybrid));
+            }            
+        } catch (SQLException x) {
+            throw new RuntimeException("Database error.", x);
+        } 
+        
+        // Return DAQ map to caller.
+        return daqMap;
+    }
+
+    /**
+     * Get the type handled by this converter.
+     * @return The type handled by this converter.
+     */
+    public Class<SvtDaqMap> getType() {
+        return SvtDaqMap.class;
+    }
+
+}

java/trunk/conditions/src/main/java/org/hps/conditions/svt
SvtGain.java added at 61
--- java/trunk/conditions/src/main/java/org/hps/conditions/svt/SvtGain.java	                        (rev 0)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/svt/SvtGain.java	2013-12-03 21:35:47 UTC (rev 61)
@@ -0,0 +1,47 @@
+package org.hps.conditions.svt;
+
+/**
+ * This class represents gain measurements for a single SVT channel.
+ * @author Jeremy McCormick <[log in to unmask]>
+ */
+public class SvtGain {
+
+    double gain = Double.NaN;
+    double offset = Double.NaN;
+    
+    /**
+     * Full qualified class constructor.
+     * @param gain The gain of the channel.
+     * @param offset The gain's offset.
+     */
+    SvtGain(double gain, double offset) {
+        this.gain = gain;
+        this.offset = offset;
+    }
+    
+    /**
+     * Get the gain.
+     * @return The gain value.
+     */
+    double getGain() {
+        return gain;
+    }
+    
+    /**
+     * Get the offset.
+     * @return The offset value.
+     */
+    double getOffset() {
+        return offset;
+    }
+    
+    /**
+     * Convert this object to a human-readable string.
+     * @return This object converted to a string.
+     */
+    public String toString() {
+        //return "gain: " + gain + ", offset: " + offset;
+        return "" + gain + '\t' + offset;
+    }
+    
+}

java/trunk/conditions/src/main/java/org/hps/conditions/svt
SvtGainCollection.java added at 61
--- java/trunk/conditions/src/main/java/org/hps/conditions/svt/SvtGainCollection.java	                        (rev 0)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/svt/SvtGainCollection.java	2013-12-03 21:35:47 UTC (rev 61)
@@ -0,0 +1,13 @@
+package org.hps.conditions.svt;
+
+import java.util.LinkedHashMap;
+
+/**
+ * This class represents a list of {@link SvtGain} objects associated 
+ * with their SVT channel IDs from the database.
+ * @author Jeremy McCormick <[log in to unmask]>
+ */
+public class SvtGainCollection extends LinkedHashMap<Integer, SvtGain> {
+    SvtGainCollection() {        
+    }
+}

java/trunk/conditions/src/main/java/org/hps/conditions/svt
SvtGainConverter.java added at 61
--- java/trunk/conditions/src/main/java/org/hps/conditions/svt/SvtGainConverter.java	                        (rev 0)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/svt/SvtGainConverter.java	2013-12-03 21:35:47 UTC (rev 61)
@@ -0,0 +1,77 @@
+package org.hps.conditions.svt;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+import org.lcsim.conditions.ConditionsManager;
+import org.hps.conditions.ConditionsRecord;
+import org.hps.conditions.ConnectionManager;
+import org.hps.conditions.DatabaseConditionsConverter;
+
+/**
+ * This class creates a {@link SvtGainCollection} from the conditions database.
+ * @author Jeremy McCormick <[log in to unmask]>
+ */
+public class SvtGainConverter extends DatabaseConditionsConverter<SvtGainCollection> {
+    
+    /**
+     * Class constructor.
+     */
+    public SvtGainConverter() {
+    }
+
+    /**
+     * Get the SVT channel constants for this run by named set.
+     * @param manager The current conditions manager.
+     * @param name The name of the conditions set.
+     * @return The channel constants data.
+     */
+    public SvtGainCollection getData(ConditionsManager manager, String name) {
+        
+        // Get the ConditionsRecord with the meta-data, which will use the current run number from the manager.
+        ConditionsRecord record = ConditionsRecord.find(manager, name).get(0);
+               
+        // Get the table name, field name, and field value defining the applicable conditions.
+        String tableName = record.getTableName();
+        String fieldName = record.getFieldName();
+        int fieldValue = record.getFieldValue();
+                
+        // Objects for building the return value.
+        SvtGainCollection collection = new SvtGainCollection();
+        
+        // Get the connection manager.
+        ConnectionManager connectionManager = ConnectionManager.getConnectionManager();
+                                                                                            
+        // Construct the query to find matching calibration records using the ID field.
+        String query = "SELECT svt_channel_id, gain, offset FROM "
+                + tableName + " WHERE " + fieldName + " = " + fieldValue
+                + " ORDER BY svt_channel_id ASC";
+            
+        // Execute the query and get the results.
+        ResultSet resultSet = connectionManager.query(query);
+               
+        try {
+            // Loop over the gain records.            
+            while(resultSet.next()) {                                 
+                // Create the object with this channel's gain parameters.
+                int channelId = resultSet.getInt(1);
+                double gain = resultSet.getDouble(2);
+                double offset = resultSet.getDouble(3);
+                collection.put(channelId, new SvtGain(gain, offset));
+            }            
+        } catch (SQLException x) {
+            throw new RuntimeException("Database error.", x);
+        }
+        
+        // Return collection of gain objects to caller.
+        return collection;
+    }
+
+    /**
+     * Get the type handled by this converter.     
+     * @return The type handled by this converter.
+     */
+    public Class<SvtGainCollection> getType() {
+        return SvtGainCollection.class;
+    }        
+}
\ No newline at end of file

java/trunk/conditions/src/main/java/org/hps/conditions/svt
SvtTimeShift.java added at 61
--- java/trunk/conditions/src/main/java/org/hps/conditions/svt/SvtTimeShift.java	                        (rev 0)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/svt/SvtTimeShift.java	2013-12-03 21:35:47 UTC (rev 61)
@@ -0,0 +1,49 @@
+package org.hps.conditions.svt;
+
+/**
+ * This class is a data holder for associating a time shift with a specific sensor
+ * by FPGA and hybrid numbers.
+ * @author Jeremy McCormick <[log in to unmask]>
+ */
+public class SvtTimeShift {
+    
+    int fpga;
+    int hybrid;
+    double timeShift;
+    
+    /**
+     * Fully qualified constructor.
+     * @param fpga The FPGA number.
+     * @param hybrid The hybrid number.
+     * @param timeShift The time shift.
+     */
+    SvtTimeShift(int fpga, int hybrid, double timeShift) {
+        this.fpga = fpga;
+        this.hybrid = hybrid;
+        this.timeShift = timeShift;
+    }
+    
+    /**
+     * Get the FPGA number.
+     * @return The FPGA number.
+     */
+    int getFpga() {
+        return fpga;
+    }
+    
+    /**
+     * Get the hybrid number.
+     * @return The hybrid number.
+     */
+    int getHybrid() {
+        return hybrid;
+    }
+    
+    /**
+     * Get the time shift.
+     * @return The time shift.
+     */
+    double getTimeShift() {
+        return timeShift;
+    }
+}

java/trunk/conditions/src/main/java/org/hps/conditions/svt
SvtTimeShiftCollection.java added at 61
--- java/trunk/conditions/src/main/java/org/hps/conditions/svt/SvtTimeShiftCollection.java	                        (rev 0)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/svt/SvtTimeShiftCollection.java	2013-12-03 21:35:47 UTC (rev 61)
@@ -0,0 +1,24 @@
+package org.hps.conditions.svt;
+
+import java.util.ArrayList;
+
+import org.lcsim.hps.util.Pair;
+
+/**
+ * A simple collection of {@link SvtTimeShift} objects.
+ * @author Jeremy McCormick <[log in to unmask]>
+ */
+public class SvtTimeShiftCollection extends ArrayList<SvtTimeShift> {
+
+    SvtTimeShiftCollection find(Pair<Integer,Integer> pair) {
+        SvtTimeShiftCollection timeShifts = new SvtTimeShiftCollection();
+        int fpga = pair.getFirstElement();
+        int hybrid = pair.getSecondElement();
+        for (SvtTimeShift timeShift : this) {
+            if (timeShift.getFpga() == fpga && timeShift.getHybrid() == hybrid) {
+                timeShifts.add(timeShift);
+            }
+        }
+        return timeShifts;
+    }
+}

java/trunk/conditions/src/main/java/org/hps/conditions/svt
SvtTimeShiftConverter.java added at 61
--- java/trunk/conditions/src/main/java/org/hps/conditions/svt/SvtTimeShiftConverter.java	                        (rev 0)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/svt/SvtTimeShiftConverter.java	2013-12-03 21:35:47 UTC (rev 61)
@@ -0,0 +1,76 @@
+package org.hps.conditions.svt;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+import org.lcsim.conditions.ConditionsManager;
+import org.hps.conditions.ConditionsRecord;
+import org.hps.conditions.ConnectionManager;
+import org.hps.conditions.DatabaseConditionsConverter;
+
+/**
+ * This class creates a {@link SvtGainCollection} from the conditions database.
+ * @author Jeremy McCormick <[log in to unmask]>
+ */
+public class SvtTimeShiftConverter extends DatabaseConditionsConverter<SvtTimeShiftCollection> {
+    
+    /**
+     * Class constructor.
+     */
+    public SvtTimeShiftConverter() {
+    }
+
+    /**
+     * Get the SVT channel constants for this run by named set.
+     * @param manager The current conditions manager.
+     * @param name The name of the conditions set.
+     * @return The channel constants data.
+     */
+    public SvtTimeShiftCollection getData(ConditionsManager manager, String name) {
+        
+        // Get the ConditionsRecord with the meta-data, which will use the current run number from the manager.
+        ConditionsRecord record = ConditionsRecord.find(manager, name).get(0);
+               
+        // Get the table name, field name, and field value defining the applicable conditions.
+        String tableName = record.getTableName();
+        String fieldName = record.getFieldName();
+        int fieldValue = record.getFieldValue();
+                
+        // Collection that will be returned. 
+        SvtTimeShiftCollection collection = new SvtTimeShiftCollection();
+        
+        // Get the connection manager.
+        ConnectionManager connectionManager = ConnectionManager.getConnectionManager();
+                                                                                            
+        // Construct the query to find matching records.
+        String query = "SELECT fpga, hybrid, time_shift FROM "
+                + tableName + " WHERE " + fieldName + " = " + fieldValue;
+            
+        // Execute the query and get the results.
+        ResultSet resultSet = connectionManager.query(query);
+               
+        try {
+            // Loop over the records.            
+            while(resultSet.next()) {                                 
+                // Create the object with the sensor time shift.
+                int fpga = resultSet.getInt(1);
+                int hybrid = resultSet.getInt(2);
+                double timeShift = resultSet.getDouble(3);
+                collection.add(new SvtTimeShift(fpga, hybrid, timeShift));
+            }            
+        } catch (SQLException x) {
+            throw new RuntimeException("Database error.", x);
+        }
+        
+        // Return collection to caller.
+        return collection;
+    }
+
+    /**
+     * Get the type handled by this converter.     
+     * @return The type handled by this converte.
+     */
+    public Class<SvtTimeShiftCollection> getType() {
+        return SvtTimeShiftCollection.class;
+    }        
+}
\ No newline at end of file

java/trunk/conditions/src/test/java/org/hps/conditions
ConditionsDriverTest.java added at 61
--- java/trunk/conditions/src/test/java/org/hps/conditions/ConditionsDriverTest.java	                        (rev 0)
+++ java/trunk/conditions/src/test/java/org/hps/conditions/ConditionsDriverTest.java	2013-12-03 21:35:47 UTC (rev 61)
@@ -0,0 +1,97 @@
+package org.hps.conditions;
+
+import java.io.File;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import junit.framework.TestCase;
+
+import org.lcsim.detector.tracker.silicon.HpsSiSensor;
+import org.lcsim.event.EventHeader;
+import org.lcsim.geometry.Detector;
+import org.lcsim.util.Driver;
+import org.lcsim.util.cache.FileCache;
+import org.lcsim.util.loop.LCSimLoop;
+
+/**
+ * This class tests that {@link org.lcsim.hps.conditions.ConditionsDriver} works correctly.
+ * @author Jeremy McCormick <[log in to unmask]>
+ */
+public class ConditionsDriverTest extends TestCase {
+    
+    /** This test file has a few events from the "good runs" of the Test Run. */
+    private static final String TEST_FILE_URL = "http://www.lcsim.org/test/hps/conditions_test.slcio";
+    
+    /** Answer key for number of bad channels by run. */
+    static Map<Integer,Integer> badChannelAnswerKey = new HashMap<Integer,Integer>();
+    
+    /** Setup the bad channel answer key by run. */
+    static {
+       badChannelAnswerKey.put(1351, 441);
+       badChannelAnswerKey.put(1353, 473);
+       badChannelAnswerKey.put(1354, 474);
+       badChannelAnswerKey.put(1358, 344);
+       badChannelAnswerKey.put(1359, 468);
+       badChannelAnswerKey.put(1360, 468);
+    }
+    
+    /** This is the number of bad channels in the QA set for all runs. */
+    static int BAD_CHANNELS_QA_ANSWER = 50;
+
+    /**
+     * Run the test.
+     * @throws Exception 
+     */
+    public void test() throws Exception {
+
+        // Cache file locally from URL.
+        FileCache cache = new FileCache();
+        File testFile = cache.getCachedFile(new URL(TEST_FILE_URL));
+        
+        // Run the ConditionsDriver over test data containing multiple runs from the Test Run.
+        LCSimLoop loop = new LCSimLoop();
+        loop.setLCIORecordSource(testFile);
+        loop.add(new ConditionsDriver());  
+        loop.add(new SvtBadChannelChecker());
+        loop.loop(-1, null);
+    }
+    
+    /**
+     * This Driver will check the number of bad channels for a run against the answer key.
+     * @author Jeremy McCormick <[log in to unmask]>
+     */
+    class SvtBadChannelChecker extends Driver {
+        
+        int currentRun = Integer.MIN_VALUE;
+        
+        /**
+         * This method will check the number of bad channels against the answer key
+         * for the first event of a new run.
+         */
+        public void process(EventHeader event) {
+            int run = event.getRunNumber();
+            if (run != currentRun) {
+                currentRun = run;
+                Detector detector = event.getDetector();
+                int badChannels = 0;
+                List<HpsSiSensor> sensors = detector.getDetectorElement().findDescendants(HpsSiSensor.class);
+                for (HpsSiSensor sensor : sensors) {
+                    int nchannels = sensor.getNumberOfChannels();
+                    for (int i=0; i<nchannels; i++) {
+                        if (sensor.isBadChannel(i))
+                            ++badChannels;
+                    }
+                }
+                System.out.println("Run " + currentRun + " has " + badChannels + " SVT bad channels.");
+                Integer badChannelAnswer = badChannelAnswerKey.get(run);
+                if (badChannelAnswer != null) {
+                    TestCase.assertEquals("Wrong number of bad channels found.", (int)badChannelAnswer, (int)badChannels);
+                } else {
+                    TestCase.assertEquals("Wrong number of bad channels found.", (int)BAD_CHANNELS_QA_ANSWER, (int)badChannels);
+                }
+            }
+        }
+    }
+}

java/trunk/conditions/src/test/java/org/hps/conditions
DatabaseConditionsReaderTest.java added at 61
--- java/trunk/conditions/src/test/java/org/hps/conditions/DatabaseConditionsReaderTest.java	                        (rev 0)
+++ java/trunk/conditions/src/test/java/org/hps/conditions/DatabaseConditionsReaderTest.java	2013-12-03 21:35:47 UTC (rev 61)
@@ -0,0 +1,46 @@
+package org.hps.conditions;
+
+import java.io.PrintStream;
+
+import junit.framework.TestCase;
+
+import org.lcsim.conditions.CachedConditions;
+import org.lcsim.conditions.ConditionsManager;
+import org.lcsim.conditions.ConditionsManager.ConditionsNotFoundException;
+
+/**
+ * This class tests the DatabaseConditionsReader on dummy data.
+ * 
+ * @author jeremym
+ */
+public class DatabaseConditionsReaderTest extends TestCase {
+    
+    /** Example detector from hps-detectors. */
+    private final String detectorName = "HPS-conditions-test";
+    
+    /** Run number of conditions set. */
+    private final int runNumber = 777;
+        
+    /** Print output. */
+    private final PrintStream ps = System.out;
+    
+    /**
+     * Create the manager, load the detector, and then get the conditions meta-data
+     * for the selected conditions set.  Finally, use the sample converter to create 
+     * an SvtCalibrationConstants object from the database rows.
+     */
+    public void test() {
+	ConditionsManager manager = ConditionsManager.defaultInstance();
+	try {
+	    manager.setDetector(detectorName, runNumber);
+	} catch (ConditionsNotFoundException e) {
+	    throw new RuntimeException(e);
+	}
+			
+	CachedConditions<ConditionsRecordCollection> c2 = manager.getCachedConditions(ConditionsRecordCollection.class, "conditions_records");
+	ConditionsRecordCollection rc = c2.getCachedData();
+	for (ConditionsRecord r : rc) {
+	    ps.println(r.toString());
+	}	      
+    }    
+}

java/trunk/conditions/src/test/java/org/hps/conditions/beam
BeamCurrentTest.java added at 61
--- java/trunk/conditions/src/test/java/org/hps/conditions/beam/BeamCurrentTest.java	                        (rev 0)
+++ java/trunk/conditions/src/test/java/org/hps/conditions/beam/BeamCurrentTest.java	2013-12-03 21:35:47 UTC (rev 61)
@@ -0,0 +1,81 @@
+package org.hps.conditions.beam;
+
+import java.io.File;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.Map;
+
+import junit.framework.TestCase;
+
+import org.lcsim.conditions.ConditionsManager;
+import org.lcsim.event.EventHeader;
+import org.lcsim.util.Driver;
+import org.lcsim.util.cache.FileCache;
+import org.lcsim.util.loop.LCSimLoop;
+
+import static org.hps.conditions.ConditionsConstants.BEAM_CURRENT;
+
+/**
+ * This test checks the beam current values by run.
+ * @author Jeremy McCormick <[log in to unmask]>
+ */
+public class BeamCurrentTest extends TestCase {
+    
+    /** This test file has a few events from the "good runs" of the Test Run. */
+    private static final String TEST_FILE_URL = "http://www.lcsim.org/test/hps/conditions_test.slcio";
+    
+    /** Answer key for beam current by run. */
+    static Map<Integer,Double> beamCurrentAnswerKey = new HashMap<Integer,Double>();
+    
+    /** Setup the beam current answer key by run. */
+    static {
+        beamCurrentAnswerKey.put(1349, 54879.7343788147); 
+        beamCurrentAnswerKey.put(1351, 26928.0426635742);        
+        beamCurrentAnswerKey.put(1353, 204325.132622242); 
+        beamCurrentAnswerKey.put(1354, 148839.141475141); 
+        beamCurrentAnswerKey.put(1358, 92523.9428218845); 
+        beamCurrentAnswerKey.put(1359, 91761.4541434497);       
+        beamCurrentAnswerKey.put(1360, 209883.979889035); 
+        beamCurrentAnswerKey.put(1362, 110298.553449392); 
+        beamCurrentAnswerKey.put(1363, 8556.8459701538); 
+    }
+    
+    /**
+     * Run the test.
+     * @throws Exception 
+     */
+    public void test() throws Exception {
+
+        // Cache file locally from URL.
+        FileCache cache = new FileCache();
+        File testFile = cache.getCachedFile(new URL(TEST_FILE_URL));
+        
+        // Run the ConditionsDriver over test data containing multiple runs from the Test Run.
+        LCSimLoop loop = new LCSimLoop();
+        loop.setLCIORecordSource(testFile);
+        loop.add(new BeamCurrentChecker());
+        loop.loop(-1, null);
+    }
+    
+    /**
+     * This Driver will check the beam current for a run against the answer key.
+     * @author Jeremy McCormick <[log in to unmask]>
+     */
+    class BeamCurrentChecker extends Driver {
+        
+        int currentRun = Integer.MIN_VALUE;
+        
+        /**
+         * This method will check the beam current against the answer key
+         * for the first event of a new run.
+         */
+        public void process(EventHeader event) {
+            if (currentRun != event.getRunNumber()) {
+                currentRun = event.getRunNumber();
+                BeamCurrent beamCurrent = ConditionsManager.defaultInstance().getCachedConditions(BeamCurrent.class, BEAM_CURRENT).getCachedData();
+                System.out.println("Run " + event.getRunNumber() + " has integrated beam current " + beamCurrent.getIntegratedBeamCurrent() + " nC.");
+                assertEquals("Wrong beam current for run.", beamCurrentAnswerKey.get(currentRun), beamCurrent.getIntegratedBeamCurrent());
+            }
+        }
+    }
+}

java/trunk/conditions/src/test/java/org/hps/conditions/ecal
EcalConditionsConverterTest.java added at 61
--- java/trunk/conditions/src/test/java/org/hps/conditions/ecal/EcalConditionsConverterTest.java	                        (rev 0)
+++ java/trunk/conditions/src/test/java/org/hps/conditions/ecal/EcalConditionsConverterTest.java	2013-12-03 21:35:47 UTC (rev 61)
@@ -0,0 +1,37 @@
+package org.hps.conditions.ecal;
+
+import junit.framework.TestCase;
+
+import org.lcsim.conditions.ConditionsManager;
+import org.lcsim.conditions.ConditionsManager.ConditionsNotFoundException;
+import org.hps.conditions.ConnectionManager;
+import org.lcsim.util.loop.LCSimConditionsManagerImplementation;
+
+public class EcalConditionsConverterTest extends TestCase {
+    
+    /** An example detector from hps-detectors. */
+    private static final String detectorName = "HPS-conditions-test";
+    
+    /** The run number of the conditions set in the database. */
+    private static final int runNumber = 777;
+        
+    public void test() {
+        
+        // Setup the conditions manager.        
+        ConditionsManager.setDefaultConditionsManager(new LCSimConditionsManagerImplementation());
+        ConditionsManager manager = ConditionsManager.defaultInstance();
+        try {
+            manager.setDetector(detectorName, runNumber);
+        } catch (ConditionsNotFoundException e) {
+            throw new RuntimeException(e);
+        }
+                                        
+        // Test that the manager gets ECAL conditions.
+        EcalConditions conditions = manager.getCachedConditions(EcalConditions.class, "ecal_conditions").getCachedData();        
+        assertNotNull(conditions);
+        System.out.println(conditions);
+        
+        // Cleanup the connection.
+        ConnectionManager.getConnectionManager().disconnect();
+    }    
+}

java/trunk/conditions/src/test/java/org/hps/conditions/ecal
EcalConditionsLoaderTest.java added at 61
--- java/trunk/conditions/src/test/java/org/hps/conditions/ecal/EcalConditionsLoaderTest.java	                        (rev 0)
+++ java/trunk/conditions/src/test/java/org/hps/conditions/ecal/EcalConditionsLoaderTest.java	2013-12-03 21:35:47 UTC (rev 61)
@@ -0,0 +1,111 @@
+package org.hps.conditions.ecal;
+
+import java.util.List;
+
+import junit.framework.TestCase;
+
+import org.lcsim.conditions.ConditionsManager;
+import org.lcsim.conditions.ConditionsManager.ConditionsNotFoundException;
+import org.lcsim.detector.converter.compact.EcalCrystal;
+import org.lcsim.geometry.Detector;
+import org.lcsim.util.loop.LCSimConditionsManagerImplementation;
+
+import org.hps.conditions.ConnectionManager;
+
+/**
+ * This test loads ECal conditions data onto the detector and checks the results
+ * for basic validity.  
+ * @author Jeremy McCormick <[log in to unmask]>
+ */
+public class EcalConditionsLoaderTest extends TestCase {
+    
+    /** An example detector from hps-detectors. */
+    private static final String detectorName = "HPS-conditions-test";
+    
+    /** The run number of the conditions set in the database. */
+    private static final int runNumber = 1351;
+    
+    /** Expected number of crystals. */
+    private static final int CRYSTAL_COUNT_ANSWER = 442;
+    
+    /** Expected number of bad channels. */
+    private static final int BAD_CHANNELS_ANSWER = 44;
+    
+    /** Valid minimum and maximum values for DAQ setup parameters. */
+    private static final int MIN_CRATE_ANSWER = 1;    
+    private static final int MAX_CRATE_ANSWER = 2;
+    private static final int MIN_SLOT_ANSWER = 3;
+    private static final int MAX_SLOT_ANSWER = 19;
+    private static final int MIN_CHANNEL_ANSWER = 0;
+    private static final int MAX_CHANNEL_ANSWER = 19;
+                                           
+    /**
+     * Load SVT conditions data onto the detector and perform basic checks afterwards.
+     */
+    public void test() {
+        
+        // Setup the conditions manager.        
+        ConditionsManager.setDefaultConditionsManager(new LCSimConditionsManagerImplementation());
+        ConditionsManager manager = ConditionsManager.defaultInstance();
+        try {
+            manager.setDetector(detectorName, runNumber);
+        } catch (ConditionsNotFoundException e) {
+            throw new RuntimeException(e);
+        }
+        
+        // Get the detector.
+        Detector detector = manager.getCachedConditions(Detector.class, "compact.xml").getCachedData();
+        
+        // Get conditions.
+        EcalConditions conditions = manager.getCachedConditions(EcalConditions.class, "ecal_conditions").getCachedData();
+
+        // Load conditions onto detector.
+        EcalConditionsLoader loader = new EcalConditionsLoader();
+        loader.load(detector, conditions);
+        
+        // Get crystals from detector.
+        List<EcalCrystal> crystals = detector.getDetectorElement().findDescendants(EcalCrystal.class);
+        
+        // Check number of crystals.
+        assertEquals("Wrong number of crystals.", CRYSTAL_COUNT_ANSWER, crystals.size());
+
+        // Counter for bad channels.
+        int badChannelCount = 0;
+        
+        // Loop over crystals.
+        for (EcalCrystal crystal : crystals) {
+            
+            // Get DAQ information.
+            int crate = crystal.getCrate();
+            int slot = crystal.getSlot();
+            int channel = crystal.getChannel();
+            
+            // Check basic validity of DAQ setup information.
+            assertTrue("Crate number is out of range.", crate >= MIN_CRATE_ANSWER && crate <= MAX_CRATE_ANSWER);            
+            assertTrue("Slot number is out of range.", slot >= MIN_SLOT_ANSWER && slot <= MAX_SLOT_ANSWER);            
+            assertTrue("Channel number is out of range.", MIN_CHANNEL_ANSWER >=0 && channel <= MAX_CHANNEL_ANSWER);
+
+            // Get time dependent conditions.
+            double pedestal = crystal.getPedestal();
+            double noise = crystal.getNoise();
+            double gain = crystal.getGain();
+            boolean badChannel = crystal.isBadChannel();
+
+            // Check basic validity of conditions.  They should all be non-zero.
+            assertTrue("Pedestal value is zero.", pedestal != 0);
+            assertTrue("Noise value is zero.", noise != 0);
+            assertTrue("Gain value is zero.", gain != 0);
+                        
+            // Increment bad channel count.
+            if (badChannel)
+                ++badChannelCount;
+            
+        }
+        
+        // Check total number of bad channels.
+        assertEquals("Wrong number of bad channels.", BAD_CHANNELS_ANSWER, badChannelCount);
+
+        // Cleanup the database connection.
+        ConnectionManager.getConnectionManager().disconnect();
+    }
+}

java/trunk/conditions/src/test/java/org/hps/conditions/svt
SvtConditionsConverterTest.java added at 61
--- java/trunk/conditions/src/test/java/org/hps/conditions/svt/SvtConditionsConverterTest.java	                        (rev 0)
+++ java/trunk/conditions/src/test/java/org/hps/conditions/svt/SvtConditionsConverterTest.java	2013-12-03 21:35:47 UTC (rev 61)
@@ -0,0 +1,48 @@
+package org.hps.conditions.svt;
+
+import junit.framework.TestCase;
+
+import org.lcsim.conditions.ConditionsManager;
+import org.lcsim.conditions.ConditionsManager.ConditionsNotFoundException;
+import org.lcsim.util.loop.LCSimConditionsManagerImplementation;
+
+import org.hps.conditions.ConnectionManager;
+
+/**
+ * This class loads and prints {@link SvtConditions}, which internally uses the  
+ * {@link SvtConditionsConverter}.
+ * 
+ * @author Jeremy McCormick <[log in to unmask]>
+ */
+public class SvtConditionsConverterTest extends TestCase {
+    
+    /** An example detector from hps-detectors. */
+    private static final String detectorName = "HPS-conditions-test";
+    
+    /** The run number of the conditions set in the database. */
+    private static final int runNumber = 777;
+            
+    /**
+     * Load and print all SVT conditions for a certain run number.
+     */
+    public void test() {
+        
+        // Setup the conditions manager.        
+        ConditionsManager.setDefaultConditionsManager(new LCSimConditionsManagerImplementation());
+        ConditionsManager manager = ConditionsManager.defaultInstance();
+        try {
+            manager.setDetector(detectorName, runNumber);
+        } catch (ConditionsNotFoundException e) {
+            throw new RuntimeException(e);
+        }
+        
+        // Get conditions and print them out.
+        SvtConditions svt = manager.getCachedConditions(SvtConditions.class, "svt_conditions").getCachedData();
+        assertNotNull(svt);
+        System.out.println(svt);
+        System.out.println("Successfully loaded SVT conditions!");
+        
+        // Cleanup the connection.
+        ConnectionManager.getConnectionManager().disconnect();
+    }
+}

java/trunk/conditions/src/test/java/org/hps/conditions/svt
SvtConditionsLoaderTest.java added at 61
--- java/trunk/conditions/src/test/java/org/hps/conditions/svt/SvtConditionsLoaderTest.java	                        (rev 0)
+++ java/trunk/conditions/src/test/java/org/hps/conditions/svt/SvtConditionsLoaderTest.java	2013-12-03 21:35:47 UTC (rev 61)
@@ -0,0 +1,119 @@
+package org.hps.conditions.svt;
+
+import java.util.List;
+
+import junit.framework.TestCase;
+
+import org.lcsim.conditions.ConditionsManager;
+import org.lcsim.conditions.ConditionsManager.ConditionsNotFoundException;
+import org.lcsim.detector.tracker.silicon.HpsSiSensor;
+import org.lcsim.geometry.Detector;
+import org.lcsim.util.loop.LCSimConditionsManagerImplementation;
+
+import org.hps.conditions.ConnectionManager;
+
+/**
+ * This test loads conditions data onto the detector and then checks that 
+ * all channels of each sensor have non-zero data values for these parameters. 
+ * 
+ * @author Jeremy McCormick <[log in to unmask]>
+ */
+public class SvtConditionsLoaderTest extends TestCase {
+    
+    /** An example detector from hps-detectors. */
+    private static final String detectorName = "HPS-conditions-test";
+    
+    /** The run number of the conditions set in the database. */
+    private static final int runNumber = 1351;
+    
+    /**
+     * The number of bad channels that should be returned for the run.
+     * One of these is a duplicate so the row count is actually 442 in the database. 
+     */
+    private static final int BAD_CHANNELS_ANSWER = 441;
+    
+    /** The number of channels where pulse information is all zeroes. */
+    private static final int PULSE_NOT_SET_ANSWER = 4;
+            
+    /**
+     * Load SVT conditions data onto the detector and perform basic checks afterwards.
+     */
+    public void test() {
+        
+        // Setup the conditions manager.        
+        ConditionsManager.setDefaultConditionsManager(new LCSimConditionsManagerImplementation());
+        ConditionsManager manager = ConditionsManager.defaultInstance();
+        try {
+            manager.setDetector(detectorName, runNumber);
+        } catch (ConditionsNotFoundException e) {
+            throw new RuntimeException(e);
+        }
+        
+        // Get the detector.
+        Detector detector = manager.getCachedConditions(Detector.class, "compact.xml").getCachedData();
+        
+        // Get conditions.
+        SvtConditions conditions = manager.getCachedConditions(SvtConditions.class, "svt_conditions").getCachedData();
+
+        // Load conditions onto detector.
+        SvtConditionsLoader loader = new SvtConditionsLoader();
+        loader.load(detector, conditions);
+        
+        // Check sensor data.
+        List<HpsSiSensor> sensors = detector.getDetectorElement().findDescendants(HpsSiSensor.class);
+        final int nchannels = sensors.get(0).getNumberOfChannels();
+        int badChannels = 0;
+        int pulseNotSet = 0;
+        // Loop over sensors.
+        for (HpsSiSensor sensor : sensors) {
+            // Loop over channels.
+            for (int channel=0; channel<nchannels; channel++) {
+                
+                // Check that hardware information seems reasonable.
+                int hybrid = sensor.getHybridNumber();
+                assertTrue("Invalid hybrid value.", hybrid >= 0 && hybrid <= 2);
+                int fpga = sensor.getFpgaNumber();
+                assertTrue("Invalid FPGA value.", fpga >= 0 && fpga <= 6);
+                
+                // Check that conditions values are not zero:
+                assertTrue("Gain is zero.", sensor.getGain(channel) != 0);
+                assertTrue("Noise is zero.", sensor.getNoise(channel) != 0);
+                assertTrue("Pedestal is zero.", sensor.getPedestal(channel) != 0);
+                assertTrue("Time offset is zero.", sensor.getTimeOffset(channel) != 0);
+                assertTrue("PulseParameters points to null.", sensor.getPulseParameters(channel) != null);               
+                double[] pulse = sensor.getPulseParameters(channel);
+                
+                // There are four channels in the database where these are all zeroes.
+                if (pulse[0] != 0) {                
+                    // Check pulse parameters:
+                    assertTrue("amplitude is zero.", pulse[0] != 0);
+                    assertTrue("t0 is zero.", pulse[1] != 0);
+                    assertTrue("tp is zero.", pulse[2] != 0);
+                    assertTrue("chisq is zero.", pulse[3] != 0);
+                } else {
+                    pulseNotSet += 1;
+                }
+                
+                // Add to bad channel count.
+                if (sensor.isBadChannel(channel)) {
+                    ++badChannels;
+                }
+            }
+
+            // Check that time shift is set for the sensor.  When unset, it's value will be NaN.
+            assertTrue("Time shift was not set.", sensor.getTimeShift() != Double.NaN);
+        }
+        
+        // Check that there were at least some bad channels.
+        assertTrue("Number of bad channels was zero.", badChannels != 0);
+        
+        // Now check the exact number of bad channels, which should be the QA set plus those for run 1351.
+        assertEquals("Wrong number of dead channels found.", BAD_CHANNELS_ANSWER, badChannels);
+
+        // There should be exactly 4 channels where the pulse parameters are all zeroes.
+        assertEquals("The number of channels for which pulse was not set is wrong.", PULSE_NOT_SET_ANSWER, pulseNotSet);
+        
+        // Cleanup the database connection.
+        ConnectionManager.getConnectionManager().disconnect();
+    }
+}
SVNspam 0.1